On Fri, Jun 13, 2014 at 11:36:24AM +0000, David Laight wrote: > From: Robert Baldyga > > usb_gadget_disconnect() shouldn't be called under spinlock to avoid > > spinlock recursion. Function usb_gadget_disconnect() calls pullup(), > > which is callback from UDC driver, usually calling composite_disconnect(). > > This function wants to lock spinlock used in usb_function_deactivate() > > causing spinlock recursion. > ... > > +++ b/drivers/usb/gadget/composite.c > > @@ -260,8 +260,11 @@ int usb_function_deactivate(struct usb_function *function) > > > > spin_lock_irqsave(&cdev->lock, flags); > > > > - if (cdev->deactivations == 0) > > + if (cdev->deactivations == 0) { > > + spin_unlock_irqrestore(&cdev->lock, flags); > > status = usb_gadget_disconnect(cdev->gadget); > > + spin_lock_irqsave(&cdev->lock, flags); > > + } > > if (status == 0) > > cdev->deactivations++; > > That sort of change rings big alarm bells. > You've effectively isolated the usb_gadget_disconnect() call > from the check that cdev->deactivations == 0. > And then you increment cdev->deactivations below. > > Looks like it will be racy to me. yes, it will. Fixing this requires a much more involved change. -- balbi
Attachment:
signature.asc
Description: Digital signature