Re: [BUG] usbip: vhci: Sleeping function called from invalid context in vhci_urb_enqueue on PREEMPT_RT

Alan Stern
2025-08-16T14:16:39Z

On Sat, Aug 16, 2025 at 11:18:02AM +0900, Yunseong Kim wrote:
> I think this part is a macro, so it appears this way.
>
> Link: https://github.com/torvalds/linux/blob/v6.17-rc1/include/linux/spinlock_rt.h#L96
>
> #define spin_lock_irqsave(lock, flags) \
> do { \
> typecheck(unsigned long, flags); \
> flags = 0; \
> spin_lock(lock); \
> } while (0)
>
> My tree is indeed 6.17-rc1. I made a mistake in the diagram,
> which caused the misunderstanding. I’ve redrawn the diagram:
>
> kworker (hub_event)
> |
> v
> vhci_urb_enqueue() [drivers/usb/usbip/vhci_hcd.c]
> |
> |---> spin_unlock_irqrestore(&vhci->lock, flags);
> | (Context: IRQs Enabled, Process Context)
> |---> local_irq_disable();
> |
> | *** STATE CHANGE: IRQs Disabled (Atomic Context) ***
> |
> +-----> usb_hcd_giveback_urb() [drivers/usb/core/hcd.c]
> |
> v
> __usb_hcd_giveback_urb()
> |
> v
> mon_complete() [drivers/usb/mon/mon_main.c]
> |
> |---> spin_lock_irqsave() [include/linux/spinlock_rt.h]
> |
> v https://github.com/torvalds/linux/blob/v6.17-rc1/include/linux/spinlock_rt.h#L96
> spin_lock() [kernel/locking/spinlock_rt.c] <--- Attempts to acquire lock
> |
> | [On PREEMPT_RT]
> v
> rt_spin_lock() [kernel/locking/spinlock_rt.c]
> |
> v
> [May Sleep if contended]
> |
> X <----------- BUG: Sleeping in atomic context (IRQs are disabled!)
>
> |
> |---> local_irq_enable();
> (Context: IRQs Enabled)

So it looks like we should be using a different function instead of
local_irq_disable(). We need something which in a non-RT build will
disable interrupts on the local CPU, but in an RT build will merely
disable preemption. (In fact, every occurrence of local_irq_disable()
in the USB subsystem probably should be changed in this way.)

Is there such a function?

Alan Stern