USB: usb serial gadget smp related bug
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 <emints@ru.mvista.com> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
0e3c8c26c7
commit
80f8af0c59
|
@ -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));
|
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);
|
list_del(&req_entry->re_entry);
|
||||||
req->length = len;
|
req->length = len;
|
||||||
|
spin_unlock_irqrestore(&dev->dev_lock, flags);
|
||||||
if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
|
if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"gs_send: cannot queue read request, ret=%d\n",
|
"gs_send: cannot queue read request, ret=%d\n",
|
||||||
ret);
|
ret);
|
||||||
|
spin_lock_irqsave(&dev->dev_lock, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
spin_lock_irqsave(&dev->dev_lock, flags);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue