Re: [RFC PATCH v2 01/11] rust: usb: add synchronous bulk transfer support

From: Oliver Neukum

Date: Mon Jul 06 2026 - 07:35:05 EST




On 03.07.26 05:00, Mike Lothian wrote:

[..]
+ /// [`usb_bulk_msg()`]: https://docs.kernel.org/driver-api/usb/usb.html#c.usb_bulk_msg
+ pub fn bulk_send(&self, endpoint: u8, data: &[u8], timeout: Delta) -> Result<usize> {
+ let mut actual: kernel::ffi::c_int = 0;
+
+ // `usb_bulk_msg()` requires a DMA-capable buffer; `data` may live on the
+ // stack or in `.rodata`, so copy it into a kmalloc'd bounce buffer.
+ let mut buf = KVec::with_capacity(data.len(), GFP_KERNEL)?;
+ buf.extend_from_slice(data, GFP_KERNEL)?;

And here is the GFP_KERNEL again. I am afraid I was not clear enough.
I am sorry for that. Let me explain again in great detail and clarity.

Let us assume that you have a device with two interfaces. One is storage
and the other one is driven by a driver written in Rust.

The storage driver experiences an error and runs the error handler.
Eventually the device will be reset. Now, after a reset the device state
will be gone. Both interfaces' drivers need to restore it to the state
the device had before the reset.

Presumably the driver written in Rust would like to use bulk_send()
to restore the device state. It is, however, running in post_reset()

Now you use GFP_KERNEL in post_reset().
Memory allocator wants to write out pages (after all we were already
writing out pages)
Memory allocator finds that an error handler is running. It needs to wait for it.
Error handler needs to wait for the reset (including post_reset() to be done)

We are deadlocked. You cannot just allocate memory in a USB driver. Ever.
You must export the gfp_t. Always. No exceptions.

Regards
Oliver