Patch "usb: usbip: Fix possible deadlocks reported by lockdep" has been added to the 3.18-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
usb: usbip: Fix possible deadlocks reported by lockdep
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
21619792d1eca7e772ca190ba68588e57f29595bMon Sep 17 00:00:00 2001
From: Andrew Goodbody <[email protected]>
Date: Tue, 2 Feb 2016 17:36:39 +0000
Subject: usb: usbip: Fix possible deadlocks reported by lockdep
From: Andrew Goodbody <[email protected]>
commit 21619792d1eca7e772ca190ba68588e57f29595b upstream.
Change spin_lock calls to spin_lock_irqsave to prevent attmpted recursive lock taking in interrupt context.
This patch fixes Bug 109351
https://bugzilla.kernel.org/show_bug.cgi?id=109351
--- drivers/usb/usbip/usbip_event.c | 5 +- drivers/usb/usbip/vhci_hcd.c | 88 +++++++++++++++++++++++----------------- drivers/usb/usbip/vhci_rx.c | 30 +++++++------ drivers/usb/usbip/vhci_sysfs.c | 19 +++++--- drivers/usb/usbip/vhci_tx.c | 14 +++--- 5 files changed, 91 insertions(+), 65 deletions(-)
drivers/usb/usbip/usbip_event.c +3 -2
@@ -117,11 +117,12 @@ EXPORT_SYMBOL_GPL(usbip_event_add);int usbip_event_happened (struct usbip_device *ud) {int happened =0 ; +unsigned long flags; -spin_lock (&ud->lock); +spin_lock_irqsave (&ud->lock, flags);if (ud->event !=0 ) happened =1 ; -spin_unlock (&ud->lock); +spin_unlock_irqrestore (&ud->lock, flags);return happened; }
drivers/usb/usbip/vhci_hcd.c +52 -36
321 lines not on this page · raw message
drivers/usb/usbip/vhci_rx.c +17 -13
@@ -72,10 +72,11 @@ static void vhci_recv_ret_submit(struct {struct usbip_device *ud = &vdev->ud;struct urb *urb; +unsigned long flags; -spin_lock (&vdev->priv_lock); +spin_lock_irqsave (&vdev->priv_lock, flags); urb =pickup_urb_and_free_priv (vdev, pdu->base.seqnum); -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);if (!urb) {pr_err ("cannot find a urb of seqnum %u\n" , pdu->base.seqnum);
@@ -104,9 +105,9 @@ static void vhci_recv_ret_submit(structusbip_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);
@@ -117,8 +118,9 @@ static struct vhci_unlink *dequeue_pendi struct usbip_header *pdu) {struct vhci_unlink *unlink, *tmp; +unsigned long flags; -spin_lock (&vdev->priv_lock); +spin_lock_irqsave (&vdev->priv_lock, flags);list_for_each_entry_safe (unlink, tmp, &vdev->unlink_rx, list) {pr_info ("unlink->seqnum %lu\n" , unlink->seqnum);
@@ -127,12 +129,12 @@ static struct vhci_unlink *dequeue_pendi unlink->seqnum);list_del (&unlink->list); -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);return unlink; } } -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);return NULL ; }
@@ -142,6 +144,7 @@ static void vhci_recv_ret_unlink(struct {struct vhci_unlink *unlink;struct urb *urb; +unsigned long flags;usbip_dump_header (pdu);
@@ -152,9 +155,9 @@ static void vhci_recv_ret_unlink(structreturn ; } -spin_lock (&vdev->priv_lock); +spin_lock_irqsave (&vdev->priv_lock, flags); urb =pickup_urb_and_free_priv (vdev, unlink->unlink_seqnum); -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);if (!urb) {/*
@@ -171,9 +174,9 @@ static void vhci_recv_ret_unlink(struct urb->status = pdu->u.ret_unlink.status;pr_info ("urb->status %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);
@@ -185,10 +188,11 @@ static void vhci_recv_ret_unlink(structstatic int vhci_priv_tx_empty (struct vhci_device *vdev) {int empty =0 ; +unsigned long flags; -spin_lock (&vdev->priv_lock); +spin_lock_irqsave (&vdev->priv_lock, flags); empty =list_empty (&vdev->priv_rx); -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);return empty; }
drivers/usb/usbip/vhci_sysfs.c +11 -8
@@ -32,10 +32,11 @@ static ssize_t status_show(struct device {char *s = out;int i =0 ; +unsigned long flags;BUG_ON (!the_controller || !out); -spin_lock (&the_controller->lock); +spin_lock_irqsave (&the_controller->lock, flags);/* * output example:
@@ -73,7 +74,7 @@ static ssize_t status_show(struct devicespin_unlock (&vdev->ud.lock); } -spin_unlock (&the_controller->lock); +spin_unlock_irqrestore (&the_controller->lock, flags);return out - s; }
@@ -83,11 +84,12 @@ static DEVICE_ATTR_RO(status);static int vhci_port_disconnect (__u32 rhport) {struct vhci_device *vdev; +unsigned long flags;usbip_dbg_vhci_sysfs ("enter\n" );/* lock */ -spin_lock (&the_controller->lock); +spin_lock_irqsave (&the_controller->lock, flags); vdev =port_to_vdev (rhport);
@@ -97,14 +99,14 @@ static int vhci_port_disconnect(__u32 rh/* unlock */ spin_unlock (&vdev->ud.lock); -spin_unlock (&the_controller->lock); +spin_unlock_irqrestore (&the_controller->lock, flags);return -EINVAL ; }/* unlock */ spin_unlock (&vdev->ud.lock); -spin_unlock (&the_controller->lock); +spin_unlock_irqrestore (&the_controller->lock, flags);usbip_event_add (&vdev->ud,VDEV_EVENT_DOWN );
@@ -180,6 +182,7 @@ static ssize_t store_attach(struct devicint sockfd =0 ;__u32 rhport =0 , devid =0 , speed =0 ;int err; +unsigned long flags;/* * @rhport: port number of vhci_hcd
@@ -205,14 +208,14 @@ static ssize_t store_attach(struct devic/* now need lock until setting vdev status as used */ /* begin a lock */ -spin_lock (&the_controller->lock); +spin_lock_irqsave (&the_controller->lock, flags); vdev =port_to_vdev (rhport);spin_lock (&vdev->ud.lock);if (vdev->ud.status !=VDEV_ST_NULL ) {/* end of the lock */ spin_unlock (&vdev->ud.lock); -spin_unlock (&the_controller->lock); +spin_unlock_irqrestore (&the_controller->lock, flags);sockfd_put (socket);
@@ -231,7 +234,7 @@ static ssize_t store_attach(struct devic vdev->ud.status =VDEV_ST_NOTASSIGNED ;spin_unlock (&vdev->ud.lock); -spin_unlock (&the_controller->lock); +spin_unlock_irqrestore (&the_controller->lock, flags);/* end the lock */ vdev->ud.tcp_rx =kthread_get_run (vhci_rx_loop, &vdev->ud,"vhci_rx" );
drivers/usb/usbip/vhci_tx.c +8 -6
@@ -47,16 +47,17 @@ static void setup_cmd_submit_pdu(structstatic struct vhci_priv *dequeue_from_priv_tx (struct vhci_device *vdev) {struct vhci_priv *priv, *tmp; +unsigned long flags; -spin_lock (&vdev->priv_lock); +spin_lock_irqsave (&vdev->priv_lock, flags);list_for_each_entry_safe (priv, tmp, &vdev->priv_tx, list) {list_move_tail (&priv->list, &vdev->priv_rx); -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);return priv; } -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);return NULL ; }
@@ -136,16 +137,17 @@ static int vhci_send_cmd_submit(struct vstatic struct vhci_unlink *dequeue_from_unlink_tx (struct vhci_device *vdev) {struct vhci_unlink *unlink, *tmp; +unsigned long flags; -spin_lock (&vdev->priv_lock); +spin_lock_irqsave (&vdev->priv_lock, flags);list_for_each_entry_safe (unlink, tmp, &vdev->unlink_tx, list) {list_move_tail (&unlink->list, &vdev->unlink_rx); -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);return unlink; } -spin_unlock (&vdev->priv_lock); +spin_unlock_irqrestore (&vdev->priv_lock, flags);return NULL ; }
Patches currently in stable-queue which might be from [email protected] are
queue-3.18/usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch