diff options
author | Wolfgang Grandegger <wg@grandegger.com> | 2017-09-14 12:37:14 -0400 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2017-10-19 07:05:54 -0400 |
commit | 97819f943063b622eca44d3644067c190dc75039 (patch) | |
tree | b6da0141e32b12829a7c23601835853bd043fccf /drivers/net | |
parent | 72d92e865d1560723e1957ee3f393688c49ca5bf (diff) |
can: gs_usb: fix busy loop if no more TX context is available
If sending messages with no cable connected, it quickly happens that
there is no more TX context available. Then "gs_can_start_xmit()"
returns with "NETDEV_TX_BUSY" and the upper layer does retry
immediately keeping the CPU busy. To fix that issue, I moved
"atomic_dec(&dev->active_tx_urbs)" from "gs_usb_xmit_callback()" to
the TX done handling in "gs_usb_receive_bulk_callback()". Renaming
"active_tx_urbs" to "active_tx_contexts" and moving it into
"gs_[alloc|free]_tx_context()" would also make sense.
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/can/usb/gs_usb.c | 10 |
1 files changed, 2 insertions, 8 deletions
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index afcc1312dbaf..68ac3e88a8ce 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c | |||
@@ -375,6 +375,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) | |||
375 | 375 | ||
376 | gs_free_tx_context(txc); | 376 | gs_free_tx_context(txc); |
377 | 377 | ||
378 | atomic_dec(&dev->active_tx_urbs); | ||
379 | |||
378 | netif_wake_queue(netdev); | 380 | netif_wake_queue(netdev); |
379 | } | 381 | } |
380 | 382 | ||
@@ -463,14 +465,6 @@ static void gs_usb_xmit_callback(struct urb *urb) | |||
463 | urb->transfer_buffer_length, | 465 | urb->transfer_buffer_length, |
464 | urb->transfer_buffer, | 466 | urb->transfer_buffer, |
465 | urb->transfer_dma); | 467 | urb->transfer_dma); |
466 | |||
467 | atomic_dec(&dev->active_tx_urbs); | ||
468 | |||
469 | if (!netif_device_present(netdev)) | ||
470 | return; | ||
471 | |||
472 | if (netif_queue_stopped(netdev)) | ||
473 | netif_wake_queue(netdev); | ||
474 | } | 468 | } |
475 | 469 | ||
476 | static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, | 470 | static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, |