From 41de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 29 Jan 2012 13:47:52 +0000 Subject: drivers/net: Remove alloc_etherdev error messages alloc_etherdev has a generic OOM/unable to alloc message. Remove the duplicative messages after alloc_etherdev calls. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net/usb/usbnet.c') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index fae0fbd8bc88..b924f46c963c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1334,10 +1334,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) // set up our own records net = alloc_etherdev(sizeof(*dev)); - if (!net) { - dbg ("can't kmalloc dev"); + if (!net) goto out; - } /* netdev_printk() needs this so do it as early as possible */ SET_NETDEV_DEV(net, &udev->dev); -- cgit v1.2.3 From 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Wed, 7 Mar 2012 10:19:28 +0000 Subject: net/usbnet: avoid recursive locking in usbnet_stop() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit |kernel BUG at kernel/rtmutex.c:724! |[] (rt_spin_lock_slowlock+0x108/0x2bc) from [] (defer_bh+0x1c/0xb4) |[] (defer_bh+0x1c/0xb4) from [] (rx_complete+0x14c/0x194) |[] (rx_complete+0x14c/0x194) from [] (usb_hcd_giveback_urb+0xa0/0xf0) |[] (usb_hcd_giveback_urb+0xa0/0xf0) from [] (musb_giveback+0x34/0x40) |[] (musb_giveback+0x34/0x40) from [] (musb_advance_schedule+0xb4/0x1c0) |[] (musb_advance_schedule+0xb4/0x1c0) from [] (musb_cleanup_urb.isra.9+0x80/0x8c) |[] (musb_cleanup_urb.isra.9+0x80/0x8c) from [] (musb_urb_dequeue+0xec/0x108) |[] (musb_urb_dequeue+0xec/0x108) from [] (unlink1+0xbc/0xcc) |[] (unlink1+0xbc/0xcc) from [] (usb_hcd_unlink_urb+0x54/0xa8) |[] (usb_hcd_unlink_urb+0x54/0xa8) from [] (unlink_urbs.isra.17+0x2c/0x58) |[] (unlink_urbs.isra.17+0x2c/0x58) from [] (usbnet_terminate_urbs+0x94/0x10c) |[] (usbnet_terminate_urbs+0x94/0x10c) from [] (usbnet_stop+0x100/0x15c) |[] (usbnet_stop+0x100/0x15c) from [] (__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. Cc: stable@kernel.org Reported-by: Aníbal Almeida Pinto Signed-off-by: Sebastian Andrzej Siewior Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/usb/usbnet.c') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index fae0fbd8bc88..81b96e303757 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); else count++; + spin_lock_irqsave(&q->lock, flags); } spin_unlock_irqrestore (&q->lock, flags); return count; -- cgit v1.2.3 From 7bdd402706cf26bfef9050dfee3f229b7f33ee4f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 14 Mar 2012 06:56:25 +0000 Subject: net/usbnet: reserve headroom on rx skbs network drivers should reserve some headroom on incoming skbs so that we dont need expensive reallocations, eg forwarding packets in tunnels. This NET_SKB_PAD padding is done in various helpers, like __netdev_alloc_skb_ip_align() in this patch, combining NET_SKB_PAD and NET_IP_ALIGN magic. Signed-off-by: Eric Dumazet Cc: Oliver Neukum Cc: Greg Kroah-Hartman Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/usb/usbnet.c') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 81b96e303757..59681f01a54e 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -328,13 +328,13 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) unsigned long lockflags; size_t size = dev->rx_urb_size; - if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) { + skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); + if (!skb) { netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); usbnet_defer_kevent (dev, EVENT_RX_MEMORY); usb_free_urb (urb); return -ENOMEM; } - skb_reserve (skb, NET_IP_ALIGN); entry = (struct skb_data *) skb->cb; entry->urb = urb; -- cgit v1.2.3 From 1aa9bc5b2f4cf8c48944fb9a607bf1dd674e2c10 Mon Sep 17 00:00:00 2001 From: Alexey Orishko Date: Wed, 14 Mar 2012 04:00:24 +0000 Subject: usbnet: use netif_tx_wake_queue instead of netif_start_queue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If host is going to autosuspend function with two interfaces and if IP packet has arrived in-between of two usbnet_suspend() callbacks, i.e usbnet_resume() is called in-between, tx data flow is stopped. When autosuspend timer expires and device is put to autosuspend again, tx queue is waked up and data can be sent again. This behavior might be repeated several times in a row. Tested on Intel/ARM. Reviewed-by: Sjur Brændeland Tested-by: Dmitry Tarnyagin Signed-off-by: Alexey Orishko Acked-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/usb/usbnet.c') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 83dcc530618e..5394b4eb00b0 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1535,7 +1535,7 @@ int usbnet_resume (struct usb_interface *intf) if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { if (!(dev->txq.qlen >= TX_QLEN(dev))) - netif_start_queue(dev->net); + netif_tx_wake_all_queues(dev->net); tasklet_schedule (&dev->bh); } } -- cgit v1.2.3 From 0956a8c20b23d429e79ff86d4325583fc06f9eb4 Mon Sep 17 00:00:00 2001 From: "tom.leiming@gmail.com" Date: Thu, 22 Mar 2012 03:22:18 +0000 Subject: usbnet: increase URB reference count before usb_unlink_urb Commit 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d(net/usbnet: avoid recursive locking in usbnet_stop()) fixes the recursive locking problem by releasing the skb queue lock, but it makes usb_unlink_urb racing with defer_bh, and the URB to being unlinked may be freed before or during calling usb_unlink_urb, so use-after-free problem may be triggerd inside usb_unlink_urb. The patch fixes the use-after-free problem by increasing URB reference count with skb queue lock held before calling usb_unlink_urb, so the URB won't be freed until return from usb_unlink_urb. Cc: stable@kernel.org Cc: Sebastian Andrzej Siewior Cc: Alan Stern Cc: Oliver Neukum Reported-by: Dave Jones Signed-off-by: Ming Lei Acked-by: Greg Kroah-Hartman Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/net/usb/usbnet.c') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 4b8b52ca09d8..febfdceeb9e5 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -589,6 +589,14 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) entry = (struct skb_data *) skb->cb; urb = entry->urb; + /* + * Get reference count of the URB to avoid it to be + * freed during usb_unlink_urb, which may trigger + * use-after-free problem inside usb_unlink_urb since + * usb_unlink_urb is always racing with .complete + * handler(include defer_bh). + */ + usb_get_urb(urb); spin_unlock_irqrestore(&q->lock, flags); // during some PM-driven resume scenarios, // these (async) unlinks complete immediately @@ -597,6 +605,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) netdev_dbg(dev->net, "unlink urb err, %d\n", retval); else count++; + usb_put_urb(urb); spin_lock_irqsave(&q->lock, flags); } spin_unlock_irqrestore (&q->lock, flags); -- cgit v1.2.3 From 5d5440a835710d09f0ef18da5000541ec98b537a Mon Sep 17 00:00:00 2001 From: "tom.leiming@gmail.com" Date: Thu, 22 Mar 2012 03:22:38 +0000 Subject: usbnet: don't clear urb->dev in tx_complete URB unlinking is always racing with its completion and tx_complete may be called before or during running usb_unlink_urb, so tx_complete must not clear urb->dev since it will be used in unlink path, otherwise invalid memory accesses or usb device leak may be caused inside usb_unlink_urb. Cc: stable@kernel.org Cc: Alan Stern Cc: Oliver Neukum Signed-off-by: Ming Lei Acked-by: Greg Kroah-Hartman Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/usb/usbnet.c') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index febfdceeb9e5..62f8b5cfbb56 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1037,7 +1037,6 @@ static void tx_complete (struct urb *urb) } usb_autopm_put_interface_async(dev->intf); - urb->dev = NULL; entry->state = tx_done; defer_bh(dev, skb, &dev->txq); } -- cgit v1.2.3 From 8a78335442cea429afb2b964318b6e257448ea00 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 3 Mar 2012 18:45:07 +0100 Subject: usbnet: consider device busy at each recieved packet usbnet should centrally handle busy reporting in the rx path so subdrivers need not worry. This hurts use cases which do rx only or predominantly. Signed-off-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/usb/usbnet.c') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 62f8b5cfbb56..b7b3f5b0d406 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -493,6 +493,7 @@ block: if (netif_running (dev->net) && !test_bit (EVENT_RX_HALT, &dev->flags)) { rx_submit (dev, urb, GFP_ATOMIC); + usb_mark_last_busy(dev->udev); return; } usb_free_urb (urb); -- cgit v1.2.3