On 2018-09-01 16:12:10 [+0800], Jia-Ju Bai wrote: > wdm_in_callback() is a completion handler function for the USB driver. > So it should not sleep. But it calls service_outstanding_interrupt(), > which calls usb_submit_urb() with GFP_KERNEL.
At which point does wdm_in_callback() invoke service_outstanding_interrupt()? I don't see it. I see one invocation from wdm_read() and another from service_interrupt_work(). Also, if that would be the case, then spin_unlock_irq() in an USB completion handler (which might run in IRQ context with interrupts disabled) would be wrong. > To fix this bug, GFP_KERNEL is replaced with GFP_ATOMIC. > > This bug is found by my static analysis tool DSAC. > > Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> > --- > v2: > * Add more description. > --- > drivers/usb/class/cdc-wdm.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c > index a0d284ef3f40..632a2bfabc08 100644 > --- a/drivers/usb/class/cdc-wdm.c > +++ b/drivers/usb/class/cdc-wdm.c > @@ -458,7 +458,7 @@ static int service_outstanding_interrupt(struct > wdm_device *desc) > > set_bit(WDM_RESPONDING, &desc->flags); > spin_unlock_irq(&desc->iuspin); > - rv = usb_submit_urb(desc->response, GFP_KERNEL); > + rv = usb_submit_urb(desc->response, GFP_ATOMIC); > spin_lock_irq(&desc->iuspin); > if (rv) { > dev_err(&desc->intf->dev, Sebastian