From david-b@pacbell.net Sat Sep 2 03:59:35 2006 From: "Eugeny S. Mints" Subject: USB: usb serial gadget smp related bug Date: Sat, 2 Sep 2006 03:59:19 -0700 To: Greg KH Cc: "Eugeny S. Mints" , Content-Disposition: inline Message-Id: <200609020359.20009.david-b@pacbell.net> From: "Eugeny S. Mints" Adjust dev->dev_lock spinlock lock/unlock calls to be safe for SMP case. Otherwise the following sequence may lead to a deadlock in SMP case: gs_send()->usb_ep_queue() ->(in case a request is satisfied immediatly) gs_write_complete() for ex for pxa2xx_udc.c: usb_ep_queue()->pxa2xx_ep_queue()->write_fifo()->done()->gs_write_complete() (through req.complete pointer) Signed-off-by: Eugeny S. Mints Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/serial.c | 3 +++ 1 file changed, 3 insertions(+) --- gregkh-2.6.orig/drivers/usb/gadget/serial.c +++ gregkh-2.6/drivers/usb/gadget/serial.c @@ -1120,12 +1120,15 @@ static int gs_send(struct gs_dev *dev) gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2)); list_del(&req_entry->re_entry); req->length = len; + spin_unlock_irqrestore(&dev->dev_lock, flags); if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { printk(KERN_ERR "gs_send: cannot queue read request, ret=%d\n", ret); + spin_lock_irqsave(&dev->dev_lock, flags); break; } + spin_lock_irqsave(&dev->dev_lock, flags); } else { break; }