--- /dev/null
+From 21619792d1eca7e772ca190ba68588e57f29595b Mon Sep 17 00:00:00 2001
+From: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+Date: Tue, 2 Feb 2016 17:36:39 +0000
+Subject: usb: usbip: Fix possible deadlocks reported by lockdep
+
+From: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+
+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
+
+Signed-off-by: Andrew Goodbody <andrew.goodbody@cambrionix.com>
+Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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(-)
+
+--- a/drivers/usb/usbip/usbip_event.c
++++ b/drivers/usb/usbip/usbip_event.c
+@@ -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;
+ }
+--- a/drivers/usb/usbip/vhci_hcd.c
++++ b/drivers/usb/usbip/vhci_hcd.c
+@@ -121,9 +121,11 @@ static void dump_port_status_diff(u32 pr
+
+ void rh_port_connect(int rhport, enum usb_device_speed speed)
+ {
++ unsigned long flags;
++
+ usbip_dbg_vhci_rh("rh_port_connect %d\n", rhport);
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+
+ the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION
+ | (1 << USB_PORT_FEAT_C_CONNECTION);
+@@ -139,22 +141,24 @@ void rh_port_connect(int rhport, enum us
+ break;
+ }
+
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ usb_hcd_poll_rh_status(vhci_to_hcd(the_controller));
+ }
+
+ static void rh_port_disconnect(int rhport)
+ {
++ unsigned long flags;
++
+ usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+
+ the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION;
+ the_controller->port_status[rhport] |=
+ (1 << USB_PORT_FEAT_C_CONNECTION);
+
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+ usb_hcd_poll_rh_status(vhci_to_hcd(the_controller));
+ }
+
+@@ -182,13 +186,14 @@ static int vhci_hub_status(struct usb_hc
+ int retval;
+ int rhport;
+ int changed = 0;
++ unsigned long flags;
+
+ retval = DIV_ROUND_UP(VHCI_NPORTS + 1, 8);
+ memset(buf, 0, retval);
+
+ vhci = hcd_to_vhci(hcd);
+
+- spin_lock(&vhci->lock);
++ spin_lock_irqsave(&vhci->lock, flags);
+ if (!HCD_HW_ACCESSIBLE(hcd)) {
+ usbip_dbg_vhci_rh("hw accessible flag not on?\n");
+ goto done;
+@@ -209,7 +214,7 @@ static int vhci_hub_status(struct usb_hc
+ usb_hcd_resume_root_hub(hcd);
+
+ done:
+- spin_unlock(&vhci->lock);
++ spin_unlock_irqrestore(&vhci->lock, flags);
+ return changed ? retval : 0;
+ }
+
+@@ -236,6 +241,7 @@ static int vhci_hub_control(struct usb_h
+ struct vhci_hcd *dum;
+ int retval = 0;
+ int rhport;
++ unsigned long flags;
+
+ u32 prev_port_status[VHCI_NPORTS];
+
+@@ -254,7 +260,7 @@ static int vhci_hub_control(struct usb_h
+
+ dum = hcd_to_vhci(hcd);
+
+- spin_lock(&dum->lock);
++ spin_lock_irqsave(&dum->lock, flags);
+
+ /* store old status and compare now and old later */
+ if (usbip_dbg_flag_vhci_rh) {
+@@ -408,7 +414,7 @@ static int vhci_hub_control(struct usb_h
+ }
+ usbip_dbg_vhci_rh(" bye\n");
+
+- spin_unlock(&dum->lock);
++ spin_unlock_irqrestore(&dum->lock, flags);
+
+ return retval;
+ }
+@@ -431,6 +437,7 @@ static void vhci_tx_urb(struct urb *urb)
+ {
+ struct vhci_device *vdev = get_vdev(urb->dev);
+ struct vhci_priv *priv;
++ unsigned long flags;
+
+ if (!vdev) {
+ pr_err("could not get virtual device");
+@@ -443,7 +450,7 @@ static void vhci_tx_urb(struct urb *urb)
+ return;
+ }
+
+- spin_lock(&vdev->priv_lock);
++ spin_lock_irqsave(&vdev->priv_lock, flags);
+
+ priv->seqnum = atomic_inc_return(&the_controller->seqnum);
+ if (priv->seqnum == 0xffff)
+@@ -457,7 +464,7 @@ static void vhci_tx_urb(struct urb *urb)
+ list_add_tail(&priv->list, &vdev->priv_tx);
+
+ wake_up(&vdev->waitq_tx);
+- spin_unlock(&vdev->priv_lock);
++ spin_unlock_irqrestore(&vdev->priv_lock, flags);
+ }
+
+ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+@@ -466,15 +473,16 @@ static int vhci_urb_enqueue(struct usb_h
+ struct device *dev = &urb->dev->dev;
+ int ret = 0;
+ struct vhci_device *vdev;
++ unsigned long flags;
+
+ /* patch to usb_sg_init() is in 2.5.60 */
+ BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length);
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+
+ if (urb->status != -EINPROGRESS) {
+ dev_err(dev, "URB already unlinked!, status %d\n", urb->status);
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+ return urb->status;
+ }
+
+@@ -486,7 +494,7 @@ static int vhci_urb_enqueue(struct usb_h
+ vdev->ud.status == VDEV_ST_ERROR) {
+ dev_err(dev, "enqueue for inactive port %d\n", vdev->rhport);
+ spin_unlock(&vdev->ud.lock);
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+ return -ENODEV;
+ }
+ spin_unlock(&vdev->ud.lock);
+@@ -559,14 +567,14 @@ static int vhci_urb_enqueue(struct usb_h
+
+ out:
+ vhci_tx_urb(urb);
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ return 0;
+
+ no_need_xmit:
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ no_need_unlink:
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+ if (!ret)
+ usb_hcd_giveback_urb(vhci_to_hcd(the_controller),
+ urb, urb->status);
+@@ -623,14 +631,15 @@ static int vhci_urb_dequeue(struct usb_h
+ {
+ struct vhci_priv *priv;
+ struct vhci_device *vdev;
++ unsigned long flags;
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+
+ priv = urb->hcpriv;
+ if (!priv) {
+ /* URB was never linked! or will be soon given back by
+ * vhci_rx. */
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+ return -EIDRM;
+ }
+
+@@ -639,7 +648,7 @@ static int vhci_urb_dequeue(struct usb_h
+
+ ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (ret) {
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+ return ret;
+ }
+ }
+@@ -664,10 +673,10 @@ static int vhci_urb_dequeue(struct usb_h
+ */
+ usb_hcd_unlink_urb_from_ep(hcd, 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);
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+
+ } else {
+ /* tcp connection is alive */
+@@ -679,7 +688,7 @@ static int vhci_urb_dequeue(struct usb_h
+ unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC);
+ if (!unlink) {
+ spin_unlock(&vdev->priv_lock);
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+ usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
+ return -ENOMEM;
+ }
+@@ -698,7 +707,7 @@ static int vhci_urb_dequeue(struct usb_h
+ spin_unlock(&vdev->priv_lock);
+ }
+
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ usbip_dbg_vhci_hc("leave\n");
+ return 0;
+@@ -707,8 +716,9 @@ static int vhci_urb_dequeue(struct usb_h
+ static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
+ {
+ struct vhci_unlink *unlink, *tmp;
++ unsigned long flags;
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+ spin_lock(&vdev->priv_lock);
+
+ list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
+@@ -742,19 +752,19 @@ static void vhci_device_unlink_cleanup(s
+ list_del(&unlink->list);
+
+ spin_unlock(&vdev->priv_lock);
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
+ urb->status);
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+ spin_lock(&vdev->priv_lock);
+
+ kfree(unlink);
+ }
+
+ spin_unlock(&vdev->priv_lock);
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+ }
+
+ /*
+@@ -821,8 +831,9 @@ static void vhci_shutdown_connection(str
+ static void vhci_device_reset(struct usbip_device *ud)
+ {
+ struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
++ unsigned long flags;
+
+- spin_lock(&ud->lock);
++ spin_lock_irqsave(&ud->lock, flags);
+
+ vdev->speed = 0;
+ vdev->devid = 0;
+@@ -836,14 +847,16 @@ static void vhci_device_reset(struct usb
+ }
+ ud->status = VDEV_ST_NULL;
+
+- spin_unlock(&ud->lock);
++ spin_unlock_irqrestore(&ud->lock, flags);
+ }
+
+ static void vhci_device_unusable(struct usbip_device *ud)
+ {
+- spin_lock(&ud->lock);
++ unsigned long flags;
++
++ spin_lock_irqsave(&ud->lock, flags);
+ ud->status = VDEV_ST_ERROR;
+- spin_unlock(&ud->lock);
++ spin_unlock_irqrestore(&ud->lock, flags);
+ }
+
+ static void vhci_device_init(struct vhci_device *vdev)
+@@ -933,12 +946,13 @@ static int vhci_get_frame_number(struct
+ static int vhci_bus_suspend(struct usb_hcd *hcd)
+ {
+ struct vhci_hcd *vhci = hcd_to_vhci(hcd);
++ unsigned long flags;
+
+ dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__);
+
+- spin_lock(&vhci->lock);
++ spin_lock_irqsave(&vhci->lock, flags);
+ hcd->state = HC_STATE_SUSPENDED;
+- spin_unlock(&vhci->lock);
++ spin_unlock_irqrestore(&vhci->lock, flags);
+
+ return 0;
+ }
+@@ -947,15 +961,16 @@ static int vhci_bus_resume(struct usb_hc
+ {
+ struct vhci_hcd *vhci = hcd_to_vhci(hcd);
+ int rc = 0;
++ unsigned long flags;
+
+ dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__);
+
+- spin_lock(&vhci->lock);
++ spin_lock_irqsave(&vhci->lock, flags);
+ if (!HCD_HW_ACCESSIBLE(hcd))
+ rc = -ESHUTDOWN;
+ else
+ hcd->state = HC_STATE_RUNNING;
+- spin_unlock(&vhci->lock);
++ spin_unlock_irqrestore(&vhci->lock, flags);
+
+ return rc;
+ }
+@@ -1053,17 +1068,18 @@ static int vhci_hcd_suspend(struct platf
+ int rhport = 0;
+ int connected = 0;
+ int ret = 0;
++ unsigned long flags;
+
+ hcd = platform_get_drvdata(pdev);
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+
+ for (rhport = 0; rhport < VHCI_NPORTS; rhport++)
+ if (the_controller->port_status[rhport] &
+ USB_PORT_STAT_CONNECTION)
+ connected += 1;
+
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ if (connected > 0) {
+ dev_info(&pdev->dev,
+--- a/drivers/usb/usbip/vhci_rx.c
++++ b/drivers/usb/usbip/vhci_rx.c
+@@ -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(struct
+
+ usbip_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(struct
+ return;
+ }
+
+- 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(struct
+ static 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;
+ }
+--- a/drivers/usb/usbip/vhci_sysfs.c
++++ b/drivers/usb/usbip/vhci_sysfs.c
+@@ -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 device
+ spin_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 devic
+ int 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");
+--- a/drivers/usb/usbip/vhci_tx.c
++++ b/drivers/usb/usbip/vhci_tx.c
+@@ -47,16 +47,17 @@ static void setup_cmd_submit_pdu(struct
+ static 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 v
+ static 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;
+ }