[lkml]   [2012]   [Mar]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[ 09/12] net/usbnet: avoid recursive locking in usbnet_stop()
    2.6.32-longterm review patch.  If anyone has any objections, please let me know.


    From: Sebastian Siewior <>

    commit 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d upstream.

    |kernel BUG at kernel/rtmutex.c:724!
    |[<c029599c>] (rt_spin_lock_slowlock+0x108/0x2bc) from [<c01c2330>] (defer_bh+0x1c/0xb4)
    |[<c01c2330>] (defer_bh+0x1c/0xb4) from [<c01c3afc>] (rx_complete+0x14c/0x194)
    |[<c01c3afc>] (rx_complete+0x14c/0x194) from [<c01cac88>] (usb_hcd_giveback_urb+0xa0/0xf0)
    |[<c01cac88>] (usb_hcd_giveback_urb+0xa0/0xf0) from [<c01e1ff4>] (musb_giveback+0x34/0x40)
    |[<c01e1ff4>] (musb_giveback+0x34/0x40) from [<c01e2b1c>] (musb_advance_schedule+0xb4/0x1c0)
    |[<c01e2b1c>] (musb_advance_schedule+0xb4/0x1c0) from [<c01e2ca8>] (musb_cleanup_urb.isra.9+0x80/0x8c)
    |[<c01e2ca8>] (musb_cleanup_urb.isra.9+0x80/0x8c) from [<c01e2ed0>] (musb_urb_dequeue+0xec/0x108)
    |[<c01e2ed0>] (musb_urb_dequeue+0xec/0x108) from [<c01cbb90>] (unlink1+0xbc/0xcc)
    |[<c01cbb90>] (unlink1+0xbc/0xcc) from [<c01cc2ec>] (usb_hcd_unlink_urb+0x54/0xa8)
    |[<c01cc2ec>] (usb_hcd_unlink_urb+0x54/0xa8) from [<c01c2a84>] (unlink_urbs.isra.17+0x2c/0x58)
    |[<c01c2a84>] (unlink_urbs.isra.17+0x2c/0x58) from [<c01c2b44>] (usbnet_terminate_urbs+0x94/0x10c)
    |[<c01c2b44>] (usbnet_terminate_urbs+0x94/0x10c) from [<c01c2d68>] (usbnet_stop+0x100/0x15c)
    |[<c01c2d68>] (usbnet_stop+0x100/0x15c) from [<c020f718>] (__dev_close_many+0x94/0xc8)

    defer_bh() takes the lock which is hold during unlink_urbs(). The safe
    walk suggest that the skb will be removed from the list and this is done
    by defer_bh() so it seems to be okay to drop the lock here.

    Reported-by: Aníbal Almeida Pinto <>
    Signed-off-by: Sebastian Andrzej Siewior <>
    Acked-by: Oliver Neukum <>
    Signed-off-by: David S. Miller <>

    diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
    index fae0fbd..81b96e3 100644
    --- a/drivers/net/usb/usbnet.c
    +++ b/drivers/net/usb/usbnet.c
    @@ -589,6 +589,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
    entry = (struct skb_data *) skb->cb;
    urb = entry->urb;

    + spin_unlock_irqrestore(&q->lock, flags);
    // during some PM-driven resume scenarios,
    // these (async) unlinks complete immediately
    retval = usb_unlink_urb (urb);
    @@ -596,6 +597,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
    netdev_dbg(dev->net, "unlink urb err, %d\n", retval);
    + spin_lock_irqsave(&q->lock, flags);
    spin_unlock_irqrestore (&q->lock, flags);
    return count;

    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2012-03-12 01:53    [W:0.021 / U:19.076 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site