FAILED: patch "[PATCH] net: usbnet: Avoid potential RCU stall on LINK_CHANGE event" failed to apply to 5.10-stable tree
Subsystems (5)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 0d9cfc9b8cb17dbc29a98792d36ec39a1cf1395f
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025081258-value-bobbing-e1b7@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0d9cfc9b8cb17dbc29a98792d36ec39a1cf1395f Mon Sep 17 00:00:00 2001
From: John Ernberg <[email protected]>
Date: Wed, 23 Jul 2025 10:25:35 +0000
Subject: [PATCH] net: usbnet: Avoid potential RCU stall on LINK_CHANGE event
The Gemalto Cinterion PLS83-W modem (cdc_ether) is emitting confusing link up and down events when the WWAN interface is activated on the modem-side.
Interrupt URBs will in consecutive polls grab:
* Link Connected
* Link Disconnected
* Link Connected
Where the last Connected is then a stable link state.
When the system is under load this may cause the unlink_urbs() work in __handle_link_change() to not complete before the next usbnet_link_change() call turns the carrier on again, allowing rx_submit() to queue new SKBs.
In that event the URB queue is filled faster than it can drain, ending up in a RCU stall:
rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 0-.... } 33108 jiffies s: 201 root: 0x1/.
rcu: blocking rcu_node structures (internal RCU debug):
Sending NMI from CPU 1 to CPUs 0:
NMI backtrace for cpu 0
Call trace:
arch_local_irq_enable+0x4/0x8
local_bh_enable+0x18/0x20
__netdev_alloc_skb+0x18c/0x1cc
rx_submit+0x68/0x1f8 [usbnet]
rx_alloc_submit+0x4c/0x74 [usbnet]
usbnet_bh+0x1d8/0x218 [usbnet]
usbnet_bh_tasklet+0x10/0x18 [usbnet]
tasklet_action_common+0xa8/0x110
tasklet_action+0x2c/0x34
handle_softirqs+0x2cc/0x3a0
__do_softirq+0x10/0x18
____do_softirq+0xc/0x14
call_on_irq_stack+0x24/0x34
do_softirq_own_stack+0x18/0x20
__irq_exit_rcu+0xa8/0xb8
irq_exit_rcu+0xc/0x30
el1_interrupt+0x34/0x48
el1h_64_irq_handler+0x14/0x1c
el1h_64_irq+0x68/0x6c
_raw_spin_unlock_irqrestore+0x38/0x48
xhci_urb_dequeue+0x1ac/0x45c [xhci_hcd]
unlink1+0xd4/0xdc [usbcore]
usb_hcd_unlink_urb+0x70/0xb0 [usbcore]
usb_unlink_urb+0x24/0x44 [usbcore]
unlink_urbs.constprop.0.isra.0+0x64/0xa8 [usbnet]
__handle_link_change+0x34/0x70 [usbnet]
usbnet_deferred_kevent+0x1c0/0x320 [usbnet]
process_scheduled_works+0x2d0/0x48c
worker_thread+0x150/0x1dc
kthread+0xd8/0xe8
ret_from_fork+0x10/0x20Get around the problem by delaying the carrier on to the scheduled work.
This needs a new flag to keep track of the necessary action.
The carrier ok check cannot be removed as it remains required for the LINK_RESET event flow.
drivers/net/usb/usbnet.c +8 -3
@@ -1122,6 +1122,9 @@ static void __handle_link_change(struct usbnet *dev)* tx queue is stopped by netcore after link becomes off */ }else { +if (test_and_clear_bit (EVENT_LINK_CARRIER_ON , &dev->flags)) +netif_carrier_on (dev->net); +/* submitting URBs for reading packets */ tasklet_schedule (&dev->bh); }
@@ -2009,10 +2012,12 @@ EXPORT_SYMBOL(usbnet_manage_power);void usbnet_link_change (struct usbnet *dev,bool link,bool need_reset) {/* update link after link is reseted */ -if (link && !need_reset) -netif_carrier_on (dev->net); -else +if (link && !need_reset) { +set_bit (EVENT_LINK_CARRIER_ON , &dev->flags); + }else { +clear_bit (EVENT_LINK_CARRIER_ON , &dev->flags);netif_carrier_off (dev->net); + }if (need_reset && link)usbnet_defer_kevent (dev,EVENT_LINK_RESET );
include/linux/usb/usbnet.h +1 -0
@@ -76,6 +76,7 @@ struct usbnet {# define EVENT_LINK_CHANGE 11# define EVENT_SET_RX_MODE 12# define EVENT_NO_IP_ALIGN 13 +# define EVENT_LINK_CARRIER_ON 14/* This one is special, as it indicates that the device is going away * there are cyclic dependencies between tasklet, timer and bh * that must be broken
Sasha Levin
maintainerPATCH 1/1 net: usbnet: Avoid potential RCU stall on LINK_CHANGE event
From: John Ernberg <[email protected]>
[ Upstream commit 0d9cfc9b8cb17dbc29a98792d36ec39a1cf1395f ]
The Gemalto Cinterion PLS83-W modem (cdc_ether) is emitting confusing link up and down events when the WWAN interface is activated on the modem-side.
Interrupt URBs will in consecutive polls grab:
* Link Connected
* Link Disconnected
* Link Connected
Where the last Connected is then a stable link state.
When the system is under load this may cause the unlink_urbs() work in __handle_link_change() to not complete before the next usbnet_link_change() call turns the carrier on again, allowing rx_submit() to queue new SKBs.
In that event the URB queue is filled faster than it can drain, ending up in a RCU stall:
rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 0-.... } 33108 jiffies s: 201 root: 0x1/.
rcu: blocking rcu_node structures (internal RCU debug):
Sending NMI from CPU 1 to CPUs 0:
NMI backtrace for cpu 0
Call trace:
arch_local_irq_enable+0x4/0x8
local_bh_enable+0x18/0x20
__netdev_alloc_skb+0x18c/0x1cc
rx_submit+0x68/0x1f8 [usbnet]
rx_alloc_submit+0x4c/0x74 [usbnet]
usbnet_bh+0x1d8/0x218 [usbnet]
usbnet_bh_tasklet+0x10/0x18 [usbnet]
tasklet_action_common+0xa8/0x110
tasklet_action+0x2c/0x34
handle_softirqs+0x2cc/0x3a0
__do_softirq+0x10/0x18
____do_softirq+0xc/0x14
call_on_irq_stack+0x24/0x34
do_softirq_own_stack+0x18/0x20
__irq_exit_rcu+0xa8/0xb8
irq_exit_rcu+0xc/0x30
el1_interrupt+0x34/0x48
el1h_64_irq_handler+0x14/0x1c
el1h_64_irq+0x68/0x6c
_raw_spin_unlock_irqrestore+0x38/0x48
xhci_urb_dequeue+0x1ac/0x45c [xhci_hcd]
unlink1+0xd4/0xdc [usbcore]
usb_hcd_unlink_urb+0x70/0xb0 [usbcore]
usb_unlink_urb+0x24/0x44 [usbcore]
unlink_urbs.constprop.0.isra.0+0x64/0xa8 [usbnet]
__handle_link_change+0x34/0x70 [usbnet]
usbnet_deferred_kevent+0x1c0/0x320 [usbnet]
process_scheduled_works+0x2d0/0x48c
worker_thread+0x150/0x1dc
kthread+0xd8/0xe8
ret_from_fork+0x10/0x20Get around the problem by delaying the carrier on to the scheduled work.
This needs a new flag to keep track of the necessary action.
The carrier ok check cannot be removed as it remains required for the LINK_RESET event flow.
--- drivers/net/usb/usbnet.c | 11 ++++++++--- include/linux/usb/usbnet.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-)
drivers/net/usb/usbnet.c +8 -3
@@ -1080,6 +1080,9 @@ static void __handle_link_change(struct usbnet *dev)* tx queue is stopped by netcore after link becomes off */ }else { +if (test_and_clear_bit (EVENT_LINK_CARRIER_ON , &dev->flags)) +netif_carrier_on (dev->net); +/* submitting URBs for reading packets */ tasklet_schedule (&dev->bh); }
@@ -1960,10 +1963,12 @@ EXPORT_SYMBOL(usbnet_manage_power);void usbnet_link_change (struct usbnet *dev,bool link,bool need_reset) {/* update link after link is reseted */ -if (link && !need_reset) -netif_carrier_on (dev->net); -else +if (link && !need_reset) { +set_bit (EVENT_LINK_CARRIER_ON , &dev->flags); + }else { +clear_bit (EVENT_LINK_CARRIER_ON , &dev->flags);netif_carrier_off (dev->net); + }if (need_reset && link)usbnet_defer_kevent (dev,EVENT_LINK_RESET );
include/linux/usb/usbnet.h +1 -0
@@ -83,6 +83,7 @@ struct usbnet {# define EVENT_LINK_CHANGE 11# define EVENT_SET_RX_MODE 12# define EVENT_NO_IP_ALIGN 13 +# define EVENT_LINK_CARRIER_ON 14u32 rx_speed;/* in bps - NOT Mbps */ u32 tx_speed;/* in bps - NOT Mbps */ };
Signature · 1 line
2.39.5