| From 0ebac3a404220d0d3ecbe286df31276ae55968b5 Mon Sep 17 00:00:00 2001 |
| From: Bart Westgeest <bart@elbrys.com> |
| Date: Tue, 1 Nov 2011 15:01:28 -0400 |
| Subject: [PATCH 11/24] staging: usbip: bugfix for deadlock |
| |
| commit 438957f8d4a84daa7fa5be6978ad5897a2e9e5e5 upstream. |
| |
| Interrupts must be disabled prior to calling usb_hcd_unlink_urb_from_ep. |
| If interrupts are not disabled, it can potentially lead to a deadlock. |
| The deadlock is readily reproduceable on a slower (ARM based) device |
| such as the TI Pandaboard. |
| |
| Signed-off-by: Bart Westgeest <bart@elbrys.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| drivers/staging/usbip/vhci_rx.c | 10 ++++++---- |
| 1 file changed, 6 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c |
| index a1ac1b8..b09c67a 100644 |
| --- a/drivers/staging/usbip/vhci_rx.c |
| +++ b/drivers/staging/usbip/vhci_rx.c |
| @@ -69,6 +69,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, |
| { |
| struct usbip_device *ud = &vdev->ud; |
| struct urb *urb; |
| + unsigned long flags; |
| |
| spin_lock(&vdev->priv_lock); |
| |
| @@ -109,9 +110,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, |
| |
| usbip_dbg_vhci_rx("now giveback urb %p\n", urb); |
| |
| - spin_lock(&the_controller->lock); |
| + spin_lock_irqsave(&the_controller->lock, flags); |
| usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); |
| - spin_unlock(&the_controller->lock); |
| + spin_unlock_irqrestore(&the_controller->lock, flags); |
| |
| usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); |
| |
| @@ -152,6 +153,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, |
| { |
| struct vhci_unlink *unlink; |
| struct urb *urb; |
| + unsigned long flags; |
| |
| usbip_dump_header(pdu); |
| |
| @@ -183,9 +185,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, |
| urb->status = pdu->u.ret_unlink.status; |
| usbip_uinfo("%d\n", urb->status); |
| |
| - spin_lock(&the_controller->lock); |
| + spin_lock_irqsave(&the_controller->lock, flags); |
| usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); |
| - spin_unlock(&the_controller->lock); |
| + spin_unlock_irqrestore(&the_controller->lock, flags); |
| |
| usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, |
| urb->status); |
| -- |
| 1.7.12.1 |
| |