Patch "usb: usbip: Fix possible deadlocks reported by lockdep" has been added to the 4.4-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 4.4-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-4.4 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
317 lines not on this page · raw message
drivers/usb/usbip/vhci_rx.c +17 -13
@@ -71,10 +71,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 max seqnum %d\n",
@@ -103,9 +104,9 @@ static void vhci_recv_ret_submit(structusbip_dbg_vhci_rx ("now giveback urb %u\n" , pdu->base.seqnum); -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);
@@ -116,8 +117,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);
@@ -126,12 +128,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 ; }
@@ -141,6 +143,7 @@ static void vhci_recv_ret_unlink(struct {struct vhci_unlink *unlink;struct urb *urb; +unsigned long flags;usbip_dump_header (pdu);
@@ -151,9 +154,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) {/*
@@ -170,9 +173,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);
@@ -184,10 +187,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:
@@ -74,7 +75,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; }
@@ -84,11 +85,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);
@@ -98,14 +100,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 );
@@ -181,6 +183,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
@@ -206,14 +209,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);
@@ -232,7 +235,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 ; }
@@ -137,16 +138,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-4.4/usb-usbip-fix-possible-deadlocks-reported-by-lockdep.patch