drivers/net/mctp/mctp-usb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
The tx queue can become permanently stuck in a stopped state due to a
race condition between the URB submission path and its completion
callback.
The URB completion callback can run immediately after usb_submit_urb()
returns, before the submitting function calls netif_stop_queue(). If
this occurs, the queue state management becomes desynchronized, leading
to a stall where the queue is never woken.
Fix this by moving the netif_stop_queue() call to before submitting the
URB. This closes the race window by ensuring the network stack is aware
the queue is stopped before the URB completion can possibly run.
Fixes: 0791c0327a6e ("net: mctp: Add MCTP USB transport driver")
Signed-off-by: Jinliang Wang <jinliangw@google.com>
---
v3:
- target net tree, add fixes tag
v2:
- remove duplicate comment in commit message
---
drivers/net/mctp/mctp-usb.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c
index 36ccc53b1797..ef860cfc629f 100644
--- a/drivers/net/mctp/mctp-usb.c
+++ b/drivers/net/mctp/mctp-usb.c
@@ -96,11 +96,13 @@ static netdev_tx_t mctp_usb_start_xmit(struct sk_buff *skb,
skb->data, skb->len,
mctp_usb_out_complete, skb);
+ /* Stops TX queue first to prevent race condition with URB complete */
+ netif_stop_queue(dev);
rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (rc)
+ if (rc) {
+ netif_wake_queue(dev);
goto err_drop;
- else
- netif_stop_queue(dev);
+ }
return NETDEV_TX_OK;
--
2.51.1.821.gb6fe4d2222-goog
Hi Jinliang, > The tx queue can become permanently stuck in a stopped state due to a > race condition between the URB submission path and its completion > callback. > > The URB completion callback can run immediately after usb_submit_urb() > returns, before the submitting function calls netif_stop_queue(). If > this occurs, the queue state management becomes desynchronized, leading > to a stall where the queue is never woken. > > Fix this by moving the netif_stop_queue() call to before submitting the > URB. This closes the race window by ensuring the network stack is aware > the queue is stopped before the URB completion can possibly run. Thanks! Acked-by: Jeremy Kerr <jk@codeconstruct.com.au> Cheers, Jeremy
© 2016 - 2026 Red Hat, Inc.