* [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism
@ 2025-06-18 17:39 Jun Miao
2025-06-19 22:50 ` patchwork-bot+netdevbpf
2025-07-04 16:40 ` [bug report] " Oleksij Rempel
0 siblings, 2 replies; 6+ messages in thread
From: Jun Miao @ 2025-06-18 17:39 UTC (permalink / raw)
To: sbhatta, kuba, oneukum
Cc: netdev, linux-usb, linux-kernel, qiang.zhang, jun.miao
Migrate tasklet APIs to the new bottom half workqueue mechanism. It
replaces all occurrences of tasklet usage with the appropriate workqueue
APIs throughout the usbnet driver. This transition ensures compatibility
with the latest design and enhances performance.
Signed-off-by: Jun Miao <jun.miao@intel.com>
---
v1->v2:
Check patch warning, delete the more spaces.
v2->v3:
Fix the kernel test robot noticed the following build errors:
>> drivers/net/usb/usbnet.c:1974:47: error: 'struct usbnet' has no member named 'bh'
v3->v4:
Keep "GFP_ATOMIC" flag as it is.
If someone want to change the flags (which Im not sure is correct) it should be a separate commit.
v4->v5:
As suggested by Jakub, we have used the system workqueue to schedule on(system_bh_wq),
replace the workqueue with work in usbnet_bh_workqueue() and the comments.
v5->v6:
Delete the "suggested by" review comments in commit message.
---
drivers/net/usb/usbnet.c | 36 ++++++++++++++++++------------------
include/linux/usb/usbnet.h | 2 +-
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index c39dfa17813a..234d47bbfec8 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -461,7 +461,7 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb,
__skb_queue_tail(&dev->done, skb);
if (dev->done.qlen == 1)
- tasklet_schedule(&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
spin_unlock(&dev->done.lock);
spin_unlock_irqrestore(&list->lock, flags);
return old_state;
@@ -549,7 +549,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
default:
netif_dbg(dev, rx_err, dev->net,
"rx submit, %d\n", retval);
- tasklet_schedule (&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
break;
case 0:
__usbnet_queue_skb(&dev->rxq, skb, rx_start);
@@ -709,7 +709,7 @@ void usbnet_resume_rx(struct usbnet *dev)
num++;
}
- tasklet_schedule(&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
netif_dbg(dev, rx_status, dev->net,
"paused rx queue disabled, %d skbs requeued\n", num);
@@ -778,7 +778,7 @@ void usbnet_unlink_rx_urbs(struct usbnet *dev)
{
if (netif_running(dev->net)) {
(void) unlink_urbs (dev, &dev->rxq);
- tasklet_schedule(&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
}
}
EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
@@ -861,14 +861,14 @@ int usbnet_stop (struct net_device *net)
/* deferred work (timer, softirq, task) must also stop */
dev->flags = 0;
timer_delete_sync(&dev->delay);
- tasklet_kill(&dev->bh);
+ disable_work_sync(&dev->bh_work);
cancel_work_sync(&dev->kevent);
/* We have cyclic dependencies. Those calls are needed
* to break a cycle. We cannot fall into the gaps because
* we have a flag
*/
- tasklet_kill(&dev->bh);
+ disable_work_sync(&dev->bh_work);
timer_delete_sync(&dev->delay);
cancel_work_sync(&dev->kevent);
@@ -955,7 +955,7 @@ int usbnet_open (struct net_device *net)
clear_bit(EVENT_RX_KILL, &dev->flags);
// delay posting reads until we're fully open
- tasklet_schedule (&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
if (info->manage_power) {
retval = info->manage_power(dev, 1);
if (retval < 0) {
@@ -1123,7 +1123,7 @@ static void __handle_link_change(struct usbnet *dev)
*/
} else {
/* submitting URBs for reading packets */
- tasklet_schedule(&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
}
/* hard_mtu or rx_urb_size may change during link change */
@@ -1198,11 +1198,11 @@ usbnet_deferred_kevent (struct work_struct *work)
} else {
clear_bit (EVENT_RX_HALT, &dev->flags);
if (!usbnet_going_away(dev))
- tasklet_schedule(&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
}
}
- /* tasklet could resubmit itself forever if memory is tight */
+ /* work could resubmit itself forever if memory is tight */
if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
struct urb *urb = NULL;
int resched = 1;
@@ -1224,7 +1224,7 @@ usbnet_deferred_kevent (struct work_struct *work)
fail_lowmem:
if (resched)
if (!usbnet_going_away(dev))
- tasklet_schedule(&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
}
}
@@ -1325,7 +1325,7 @@ void usbnet_tx_timeout (struct net_device *net, unsigned int txqueue)
struct usbnet *dev = netdev_priv(net);
unlink_urbs (dev, &dev->txq);
- tasklet_schedule (&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
/* this needs to be handled individually because the generic layer
* doesn't know what is sufficient and could not restore private
* information if a remedy of an unconditional reset were used.
@@ -1547,7 +1547,7 @@ static inline void usb_free_skb(struct sk_buff *skb)
/*-------------------------------------------------------------------------*/
-// tasklet (work deferred from completions, in_irq) or timer
+// work (work deferred from completions, in_irq) or timer
static void usbnet_bh (struct timer_list *t)
{
@@ -1601,16 +1601,16 @@ static void usbnet_bh (struct timer_list *t)
"rxqlen %d --> %d\n",
temp, dev->rxq.qlen);
if (dev->rxq.qlen < RX_QLEN(dev))
- tasklet_schedule (&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
}
if (dev->txq.qlen < TX_QLEN (dev))
netif_wake_queue (dev->net);
}
}
-static void usbnet_bh_tasklet(struct tasklet_struct *t)
+static void usbnet_bh_work(struct work_struct *work)
{
- struct usbnet *dev = from_tasklet(dev, t, bh);
+ struct usbnet *dev = from_work(dev, work, bh_work);
usbnet_bh(&dev->delay);
}
@@ -1742,7 +1742,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
skb_queue_head_init (&dev->txq);
skb_queue_head_init (&dev->done);
skb_queue_head_init(&dev->rxq_pause);
- tasklet_setup(&dev->bh, usbnet_bh_tasklet);
+ INIT_WORK(&dev->bh_work, usbnet_bh_work);
INIT_WORK (&dev->kevent, usbnet_deferred_kevent);
init_usb_anchor(&dev->deferred);
timer_setup(&dev->delay, usbnet_bh, 0);
@@ -1971,7 +1971,7 @@ int usbnet_resume (struct usb_interface *intf)
if (!(dev->txq.qlen >= TX_QLEN(dev)))
netif_tx_wake_all_queues(dev->net);
- tasklet_schedule (&dev->bh);
+ queue_work(system_bh_wq, &dev->bh_work);
}
}
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 0b9f1e598e3a..208682f77179 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -58,7 +58,7 @@ struct usbnet {
unsigned interrupt_count;
struct mutex interrupt_mutex;
struct usb_anchor deferred;
- struct tasklet_struct bh;
+ struct work_struct bh_work;
struct work_struct kevent;
unsigned long flags;
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism
2025-06-18 17:39 [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism Jun Miao
@ 2025-06-19 22:50 ` patchwork-bot+netdevbpf
2025-07-04 16:40 ` [bug report] " Oleksij Rempel
1 sibling, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-06-19 22:50 UTC (permalink / raw)
To: Jun Miao
Cc: sbhatta, kuba, oneukum, netdev, linux-usb, linux-kernel,
qiang.zhang
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 18 Jun 2025 13:39:23 -0400 you wrote:
> Migrate tasklet APIs to the new bottom half workqueue mechanism. It
> replaces all occurrences of tasklet usage with the appropriate workqueue
> APIs throughout the usbnet driver. This transition ensures compatibility
> with the latest design and enhances performance.
>
> Signed-off-by: Jun Miao <jun.miao@intel.com>
>
> [...]
Here is the summary with links:
- [v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism
https://git.kernel.org/netdev/net-next/c/2c04d279e857
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* [bug report] [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism
2025-06-18 17:39 [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism Jun Miao
2025-06-19 22:50 ` patchwork-bot+netdevbpf
@ 2025-07-04 16:40 ` Oleksij Rempel
2025-07-05 6:07 ` qiang.zhang
1 sibling, 1 reply; 6+ messages in thread
From: Oleksij Rempel @ 2025-07-04 16:40 UTC (permalink / raw)
To: Jun Miao
Cc: sbhatta, kuba, oneukum, netdev, linux-usb, linux-kernel,
qiang.zhang
Hi Jun,
On Wed, Jun 18, 2025 at 01:39:23PM -0400, Jun Miao wrote:
> Migrate tasklet APIs to the new bottom half workqueue mechanism. It
> replaces all occurrences of tasklet usage with the appropriate workqueue
> APIs throughout the usbnet driver. This transition ensures compatibility
> with the latest design and enhances performance.
After applying this patch, the smsc95xx driver fails after one down/up
cycle.
Here is how I can reproduce the issue:
nmcli device set enu1u1 managed no
ip a a 10.10.10.1/24 dev enu1u1
ping -c 4 10.10.10.3
ip l s dev enu1u1 down
ip l s dev enu1u1 up
ping -c 4 10.10.10.3
The second ping does not reach the host. Networking also fails on other
interfaces.
After some delay, the following trace appears:
[ 846.838527] INFO: task kworker/u16:1:308 blocked for more than 120 seconds.
[ 846.838596] Not tainted 6.16.0-rc3-00963-g4fcedea9cdf2-dirty #32
[ 846.838666] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 846.838697] task:kworker/u16:1 state:D stack:0 pid:308 tgid:308 ppid:2
task_flags:0x4208060 flags:0x00000010
[ 846.838776] Workqueue: events_unbound linkwatch_event
[ 846.838851] Call trace:
[ 846.838880] __switch_to+0x1d0/0x330 (T)
[ 846.838933] __schedule+0xa88/0x2a90
[ 846.838980] schedule+0x114/0x428
[ 846.839010] schedule_preempt_disabled+0x80/0x118
[ 846.839036] __mutex_lock+0x764/0xba8
[ 846.839060] mutex_lock_nested+0x28/0x38
[ 846.839084] rtnl_lock+0x20/0x30
[ 846.839115] linkwatch_event+0x18/0x70
[ 846.839141] process_one_work+0x760/0x17b0
[ 846.839175] worker_thread+0x768/0xce8
[ 846.839208] kthread+0x3bc/0x690
[ 846.839237] ret_from_fork+0x10/0x20
[ 846.839359] INFO: task kworker/u16:1:308 is blocked on a mutex likely
owned by task ip:899.
[ 846.839381] task:ip state:D stack:0 pid:899
tgid:899 ppid:1 task_flags:0x400100 flags:0x00000019
[ 846.839419] Call trace:
[ 846.839432] __switch_to+0x1d0/0x330 (T)
[ 846.839466] __schedule+0xa88/0x2a90
[ 846.839495] schedule+0x114/0x428
[ 846.839524] schedule_timeout+0xec/0x220
[ 846.839551] wait_skb_queue_empty+0xa0/0x168
[ 846.839581] usbnet_terminate_urbs+0x150/0x2c8
[ 846.839609] usbnet_stop+0x41c/0x608
[ 846.839636] __dev_close_many+0x1fc/0x4b8
[ 846.839668] __dev_change_flags+0x33c/0x500
[ 846.839694] netif_change_flags+0x7c/0x158
[ 846.839718] do_setlink.isra.0+0x2040/0x2eb8
[ 846.839745] rtnl_newlink+0xd88/0x16c8
[ 846.839770] rtnetlink_rcv_msg+0x654/0x8c8
[ 846.839795] netlink_rcv_skb+0x19c/0x350
[ 846.839823] rtnetlink_rcv+0x1c/0x30
[ 846.839848] netlink_unicast+0x3c4/0x668
[ 846.839873] netlink_sendmsg+0x620/0xa10
[ 846.839899] ____sys_sendmsg+0x2f8/0x788
[ 846.839924] ___sys_sendmsg+0xf0/0x178
[ 846.839950] __sys_sendmsg+0x104/0x198
[ 846.839975] __arm64_sys_sendmsg+0x74/0xa8
[ 846.840000] el0_svc_common.constprop.0+0xe4/0x338
[ 846.840033] do_el0_svc+0x44/0x60
[ 846.840061] el0_svc+0x3c/0xb0
[ 846.840089] el0t_64_sync_handler+0x104/0x130
[ 846.840117] el0t_64_sync+0x154/0x158
[ 846.840164]
[ 846.840164] Showing all locks held in the system:
[ 846.840199] 1 lock held by khungtaskd/41:
[ 846.840216] #0: ffffffc08424ede0 (rcu_read_lock){....}-{1:3}, at: debug_show_all_locks+0x14/0x1b0
[ 846.840309] 3 locks held by kworker/u16:2/47:
[ 846.840325] #0: ffffff800926a148 ((wq_completion)ipv6_addrconf){+.+.}-{0:0}, at: process_one_work+0x698/0x17b0
[ 846.840406] #1: ffffffc0860f7c00 ((work_completion)(&(&net->ipv6.addr_chk_work)->work)){+.+.}-{0:0}, at: process_one_work+0x6bc/0x17b0
[ 846.840484] #2: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x20/0x30
[ 846.840568] 2 locks held by pr/ttymxc1/60:
[ 846.840595] 5 locks held by sugov:0/84:
[ 846.840618] 2 locks held by systemd-journal/124:
[ 846.840639] 3 locks held by kworker/u16:1/308:
[ 846.840655] #0: ffffff8005d00148 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x698/0x17b0
[ 846.840733] #1: ffffffc087307c00 ((linkwatch_work).work){+.+.}-{0:0}, at: process_one_work+0x6bc/0x17b0
[ 846.840810] #2: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x20/0x30
[ 846.840894] 1 lock held by ip/899:
[ 846.840910] #0: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x5e8/0x16c8
[ 846.840982] 2 locks held by sshd/901:
[ 846.840998] #0: ffffff800aee06b0 (nlk_cb_mutex-ROUTE){+.+.}-{4:4}, at: __netlink_dump_start+0x100/0x800
[ 846.841073] #1: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_dumpit+0x128/0x1a8
[ 846.841149] 2 locks held by sshd/903:
[ 846.841165] #0: ffffff800b1c76b0 (nlk_cb_mutex-ROUTE){+.+.}-{4:4}, at: __netlink_dump_start+0x100/0x800
[ 846.841237] #1: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_dumpit+0x128/0x1a8
Reverting this patch recovers smsc95xx functionality.
Best Regards,
Oleksij
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [bug report] [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism
2025-07-04 16:40 ` [bug report] " Oleksij Rempel
@ 2025-07-05 6:07 ` qiang.zhang
2025-07-05 6:41 ` qiang.zhang
0 siblings, 1 reply; 6+ messages in thread
From: qiang.zhang @ 2025-07-05 6:07 UTC (permalink / raw)
To: Oleksij Rempel, Jun Miao
Cc: sbhatta, kuba, oneukum, netdev, linux-usb, linux-kernel
>
> Hi Jun,
>
> On Wed, Jun 18, 2025 at 01:39:23PM -0400, Jun Miao wrote:
>
> >
> > Migrate tasklet APIs to the new bottom half workqueue mechanism. It
> >
> > replaces all occurrences of tasklet usage with the appropriate workqueue
> >
> > APIs throughout the usbnet driver. This transition ensures compatibility
> >
> > with the latest design and enhances performance.
> >
>
> After applying this patch, the smsc95xx driver fails after one down/up
>
> cycle.
Hello, Oleksij
Please try follow patch base on Jun Miao's patchs:
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 9564478a79cc..554f1a1cf247 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -953,6 +953,7 @@ int usbnet_open (struct net_device *net)
dev->pkt_cnt = 0;
dev->pkt_err = 0;
clear_bit(EVENT_RX_KILL, &dev->flags);
+ enable_work(&dev->bh_work);
// delay posting reads until we're fully open
queue_work(system_bh_wq, &dev->bh_work);
Thanks
Zqiang
>
> Here is how I can reproduce the issue:
>
> nmcli device set enu1u1 managed no
>
> ip a a 10.10.10.1/24 dev enu1u1
>
> ping -c 4 10.10.10.3
>
> ip l s dev enu1u1 down
>
> ip l s dev enu1u1 up
>
> ping -c 4 10.10.10.3
>
> The second ping does not reach the host. Networking also fails on other
>
> interfaces.
>
> After some delay, the following trace appears:
>
> [ 846.838527] INFO: task kworker/u16:1:308 blocked for more than 120 seconds.
>
> [ 846.838596] Not tainted 6.16.0-rc3-00963-g4fcedea9cdf2-dirty #32
>
> [ 846.838666] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>
> [ 846.838697] task:kworker/u16:1 state:D stack:0 pid:308 tgid:308 ppid:2
>
> task_flags:0x4208060 flags:0x00000010
>
> [ 846.838776] Workqueue: events_unbound linkwatch_event
>
> [ 846.838851] Call trace:
>
> [ 846.838880] __switch_to+0x1d0/0x330 (T)
>
> [ 846.838933] __schedule+0xa88/0x2a90
>
> [ 846.838980] schedule+0x114/0x428
>
> [ 846.839010] schedule_preempt_disabled+0x80/0x118
>
> [ 846.839036] __mutex_lock+0x764/0xba8
>
> [ 846.839060] mutex_lock_nested+0x28/0x38
>
> [ 846.839084] rtnl_lock+0x20/0x30
>
> [ 846.839115] linkwatch_event+0x18/0x70
>
> [ 846.839141] process_one_work+0x760/0x17b0
>
> [ 846.839175] worker_thread+0x768/0xce8
>
> [ 846.839208] kthread+0x3bc/0x690
>
> [ 846.839237] ret_from_fork+0x10/0x20
>
> [ 846.839359] INFO: task kworker/u16:1:308 is blocked on a mutex likely
>
> owned by task ip:899.
>
> [ 846.839381] task:ip state:D stack:0 pid:899
>
> tgid:899 ppid:1 task_flags:0x400100 flags:0x00000019
>
> [ 846.839419] Call trace:
>
> [ 846.839432] __switch_to+0x1d0/0x330 (T)
>
> [ 846.839466] __schedule+0xa88/0x2a90
>
> [ 846.839495] schedule+0x114/0x428
>
> [ 846.839524] schedule_timeout+0xec/0x220
>
> [ 846.839551] wait_skb_queue_empty+0xa0/0x168
>
> [ 846.839581] usbnet_terminate_urbs+0x150/0x2c8
>
> [ 846.839609] usbnet_stop+0x41c/0x608
>
> [ 846.839636] __dev_close_many+0x1fc/0x4b8
>
> [ 846.839668] __dev_change_flags+0x33c/0x500
>
> [ 846.839694] netif_change_flags+0x7c/0x158
>
> [ 846.839718] do_setlink.isra.0+0x2040/0x2eb8
>
> [ 846.839745] rtnl_newlink+0xd88/0x16c8
>
> [ 846.839770] rtnetlink_rcv_msg+0x654/0x8c8
>
> [ 846.839795] netlink_rcv_skb+0x19c/0x350
>
> [ 846.839823] rtnetlink_rcv+0x1c/0x30
>
> [ 846.839848] netlink_unicast+0x3c4/0x668
>
> [ 846.839873] netlink_sendmsg+0x620/0xa10
>
> [ 846.839899] ____sys_sendmsg+0x2f8/0x788
>
> [ 846.839924] ___sys_sendmsg+0xf0/0x178
>
> [ 846.839950] __sys_sendmsg+0x104/0x198
>
> [ 846.839975] __arm64_sys_sendmsg+0x74/0xa8
>
> [ 846.840000] el0_svc_common.constprop.0+0xe4/0x338
>
> [ 846.840033] do_el0_svc+0x44/0x60
>
> [ 846.840061] el0_svc+0x3c/0xb0
>
> [ 846.840089] el0t_64_sync_handler+0x104/0x130
>
> [ 846.840117] el0t_64_sync+0x154/0x158
>
> [ 846.840164]
>
> [ 846.840164] Showing all locks held in the system:
>
> [ 846.840199] 1 lock held by khungtaskd/41:
>
> [ 846.840216] #0: ffffffc08424ede0 (rcu_read_lock){....}-{1:3}, at: debug_show_all_locks+0x14/0x1b0
>
> [ 846.840309] 3 locks held by kworker/u16:2/47:
>
> [ 846.840325] #0: ffffff800926a148 ((wq_completion)ipv6_addrconf){+.+.}-{0:0}, at: process_one_work+0x698/0x17b0
>
> [ 846.840406] #1: ffffffc0860f7c00 ((work_completion)(&(&net->ipv6.addr_chk_work)->work)){+.+.}-{0:0}, at: process_one_work+0x6bc/0x17b0
>
> [ 846.840484] #2: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x20/0x30
>
> [ 846.840568] 2 locks held by pr/ttymxc1/60:
>
> [ 846.840595] 5 locks held by sugov:0/84:
>
> [ 846.840618] 2 locks held by systemd-journal/124:
>
> [ 846.840639] 3 locks held by kworker/u16:1/308:
>
> [ 846.840655] #0: ffffff8005d00148 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x698/0x17b0
>
> [ 846.840733] #1: ffffffc087307c00 ((linkwatch_work).work){+.+.}-{0:0}, at: process_one_work+0x6bc/0x17b0
>
> [ 846.840810] #2: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x20/0x30
>
> [ 846.840894] 1 lock held by ip/899:
>
> [ 846.840910] #0: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x5e8/0x16c8
>
> [ 846.840982] 2 locks held by sshd/901:
>
> [ 846.840998] #0: ffffff800aee06b0 (nlk_cb_mutex-ROUTE){+.+.}-{4:4}, at: __netlink_dump_start+0x100/0x800
>
> [ 846.841073] #1: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_dumpit+0x128/0x1a8
>
> [ 846.841149] 2 locks held by sshd/903:
>
> [ 846.841165] #0: ffffff800b1c76b0 (nlk_cb_mutex-ROUTE){+.+.}-{4:4}, at: __netlink_dump_start+0x100/0x800
>
> [ 846.841237] #1: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_dumpit+0x128/0x1a8
>
> Reverting this patch recovers smsc95xx functionality.
>
> Best Regards,
>
> Oleksij
>
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [bug report] [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism
2025-07-05 6:07 ` qiang.zhang
@ 2025-07-05 6:41 ` qiang.zhang
2025-07-07 7:09 ` Oleksij Rempel
0 siblings, 1 reply; 6+ messages in thread
From: qiang.zhang @ 2025-07-05 6:41 UTC (permalink / raw)
To: Oleksij Rempel, Jun Miao
Cc: sbhatta, kuba, oneukum, netdev, linux-usb, linux-kernel
>
> >
> > Hi Jun,
> >
> >
> >
> > On Wed, Jun 18, 2025 at 01:39:23PM -0400, Jun Miao wrote:
> >
> >
> >
> >
> >
> > Migrate tasklet APIs to the new bottom half workqueue mechanism. It
> >
> >
> >
> > replaces all occurrences of tasklet usage with the appropriate workqueue
> >
> >
> >
> > APIs throughout the usbnet driver. This transition ensures compatibility
> >
> >
> >
> > with the latest design and enhances performance.
> >
> >
> >
> >
> >
> > After applying this patch, the smsc95xx driver fails after one down/up
> >
> >
> >
> > cycle.
> >
>
> Hello, Oleksij
>
> Please try follow patch base on Jun Miao's patchs:
>
Sorry, please ignore previous, try it:
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 9564478a79cc..6a3cca104af9 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -861,14 +861,14 @@ int usbnet_stop (struct net_device *net)
/* deferred work (timer, softirq, task) must also stop */
dev->flags = 0;
timer_delete_sync(&dev->delay);
- disable_work_sync(&dev->bh_work);
+ cancel_work_sync(&dev->bh_work);
cancel_work_sync(&dev->kevent);
/* We have cyclic dependencies. Those calls are needed
* to break a cycle. We cannot fall into the gaps because
* we have a flag
*/
- disable_work_sync(&dev->bh_work);
+ cancel_work_sync(&dev->bh_work);
timer_delete_sync(&dev->delay);
cancel_work_sync(&dev->kevent);
> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
>
> index 9564478a79cc..554f1a1cf247 100644
>
> --- a/drivers/net/usb/usbnet.c
>
> +++ b/drivers/net/usb/usbnet.c
>
> @@ -953,6 +953,7 @@ int usbnet_open (struct net_device *net)
>
> dev->pkt_cnt = 0;
>
> dev->pkt_err = 0;
>
> clear_bit(EVENT_RX_KILL, &dev->flags);
>
> + enable_work(&dev->bh_work);
>
>
>
> // delay posting reads until we're fully open
>
> queue_work(system_bh_wq, &dev->bh_work);
>
> Thanks
>
> Zqiang
>
> >
> > Here is how I can reproduce the issue:
> >
> >
> >
> > nmcli device set enu1u1 managed no
> >
> >
> >
> > ip a a 10.10.10.1/24 dev enu1u1
> >
> >
> >
> > ping -c 4 10.10.10.3
> >
> >
> >
> > ip l s dev enu1u1 down
> >
> >
> >
> > ip l s dev enu1u1 up
> >
> >
> >
> > ping -c 4 10.10.10.3
> >
> >
> >
> > The second ping does not reach the host. Networking also fails on other
> >
> >
> >
> > interfaces.
> >
> >
> >
> > After some delay, the following trace appears:
> >
> >
> >
> > [ 846.838527] INFO: task kworker/u16:1:308 blocked for more than 120 seconds.
> >
> >
> >
> > [ 846.838596] Not tainted 6.16.0-rc3-00963-g4fcedea9cdf2-dirty #32
> >
> >
> >
> > [ 846.838666] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> >
> >
> >
> > [ 846.838697] task:kworker/u16:1 state:D stack:0 pid:308 tgid:308 ppid:2
> >
> >
> >
> > task_flags:0x4208060 flags:0x00000010
> >
> >
> >
> > [ 846.838776] Workqueue: events_unbound linkwatch_event
> >
> >
> >
> > [ 846.838851] Call trace:
> >
> >
> >
> > [ 846.838880] __switch_to+0x1d0/0x330 (T)
> >
> >
> >
> > [ 846.838933] __schedule+0xa88/0x2a90
> >
> >
> >
> > [ 846.838980] schedule+0x114/0x428
> >
> >
> >
> > [ 846.839010] schedule_preempt_disabled+0x80/0x118
> >
> >
> >
> > [ 846.839036] __mutex_lock+0x764/0xba8
> >
> >
> >
> > [ 846.839060] mutex_lock_nested+0x28/0x38
> >
> >
> >
> > [ 846.839084] rtnl_lock+0x20/0x30
> >
> >
> >
> > [ 846.839115] linkwatch_event+0x18/0x70
> >
> >
> >
> > [ 846.839141] process_one_work+0x760/0x17b0
> >
> >
> >
> > [ 846.839175] worker_thread+0x768/0xce8
> >
> >
> >
> > [ 846.839208] kthread+0x3bc/0x690
> >
> >
> >
> > [ 846.839237] ret_from_fork+0x10/0x20
> >
> >
> >
> > [ 846.839359] INFO: task kworker/u16:1:308 is blocked on a mutex likely
> >
> >
> >
> > owned by task ip:899.
> >
> >
> >
> > [ 846.839381] task:ip state:D stack:0 pid:899
> >
> >
> >
> > tgid:899 ppid:1 task_flags:0x400100 flags:0x00000019
> >
> >
> >
> > [ 846.839419] Call trace:
> >
> >
> >
> > [ 846.839432] __switch_to+0x1d0/0x330 (T)
> >
> >
> >
> > [ 846.839466] __schedule+0xa88/0x2a90
> >
> >
> >
> > [ 846.839495] schedule+0x114/0x428
> >
> >
> >
> > [ 846.839524] schedule_timeout+0xec/0x220
> >
> >
> >
> > [ 846.839551] wait_skb_queue_empty+0xa0/0x168
> >
> >
> >
> > [ 846.839581] usbnet_terminate_urbs+0x150/0x2c8
> >
> >
> >
> > [ 846.839609] usbnet_stop+0x41c/0x608
> >
> >
> >
> > [ 846.839636] __dev_close_many+0x1fc/0x4b8
> >
> >
> >
> > [ 846.839668] __dev_change_flags+0x33c/0x500
> >
> >
> >
> > [ 846.839694] netif_change_flags+0x7c/0x158
> >
> >
> >
> > [ 846.839718] do_setlink.isra.0+0x2040/0x2eb8
> >
> >
> >
> > [ 846.839745] rtnl_newlink+0xd88/0x16c8
> >
> >
> >
> > [ 846.839770] rtnetlink_rcv_msg+0x654/0x8c8
> >
> >
> >
> > [ 846.839795] netlink_rcv_skb+0x19c/0x350
> >
> >
> >
> > [ 846.839823] rtnetlink_rcv+0x1c/0x30
> >
> >
> >
> > [ 846.839848] netlink_unicast+0x3c4/0x668
> >
> >
> >
> > [ 846.839873] netlink_sendmsg+0x620/0xa10
> >
> >
> >
> > [ 846.839899] ____sys_sendmsg+0x2f8/0x788
> >
> >
> >
> > [ 846.839924] ___sys_sendmsg+0xf0/0x178
> >
> >
> >
> > [ 846.839950] __sys_sendmsg+0x104/0x198
> >
> >
> >
> > [ 846.839975] __arm64_sys_sendmsg+0x74/0xa8
> >
> >
> >
> > [ 846.840000] el0_svc_common.constprop.0+0xe4/0x338
> >
> >
> >
> > [ 846.840033] do_el0_svc+0x44/0x60
> >
> >
> >
> > [ 846.840061] el0_svc+0x3c/0xb0
> >
> >
> >
> > [ 846.840089] el0t_64_sync_handler+0x104/0x130
> >
> >
> >
> > [ 846.840117] el0t_64_sync+0x154/0x158
> >
> >
> >
> > [ 846.840164]
> >
> >
> >
> > [ 846.840164] Showing all locks held in the system:
> >
> >
> >
> > [ 846.840199] 1 lock held by khungtaskd/41:
> >
> >
> >
> > [ 846.840216] #0: ffffffc08424ede0 (rcu_read_lock){....}-{1:3}, at: debug_show_all_locks+0x14/0x1b0
> >
> >
> >
> > [ 846.840309] 3 locks held by kworker/u16:2/47:
> >
> >
> >
> > [ 846.840325] #0: ffffff800926a148 ((wq_completion)ipv6_addrconf){+.+.}-{0:0}, at: process_one_work+0x698/0x17b0
> >
> >
> >
> > [ 846.840406] #1: ffffffc0860f7c00 ((work_completion)(&(&net->ipv6.addr_chk_work)->work)){+.+.}-{0:0}, at: process_one_work+0x6bc/0x17b0
> >
> >
> >
> > [ 846.840484] #2: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x20/0x30
> >
> >
> >
> > [ 846.840568] 2 locks held by pr/ttymxc1/60:
> >
> >
> >
> > [ 846.840595] 5 locks held by sugov:0/84:
> >
> >
> >
> > [ 846.840618] 2 locks held by systemd-journal/124:
> >
> >
> >
> > [ 846.840639] 3 locks held by kworker/u16:1/308:
> >
> >
> >
> > [ 846.840655] #0: ffffff8005d00148 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x698/0x17b0
> >
> >
> >
> > [ 846.840733] #1: ffffffc087307c00 ((linkwatch_work).work){+.+.}-{0:0}, at: process_one_work+0x6bc/0x17b0
> >
> >
> >
> > [ 846.840810] #2: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock+0x20/0x30
> >
> >
> >
> > [ 846.840894] 1 lock held by ip/899:
> >
> >
> >
> > [ 846.840910] #0: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x5e8/0x16c8
> >
> >
> >
> > [ 846.840982] 2 locks held by sshd/901:
> >
> >
> >
> > [ 846.840998] #0: ffffff800aee06b0 (nlk_cb_mutex-ROUTE){+.+.}-{4:4}, at: __netlink_dump_start+0x100/0x800
> >
> >
> >
> > [ 846.841073] #1: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_dumpit+0x128/0x1a8
> >
> >
> >
> > [ 846.841149] 2 locks held by sshd/903:
> >
> >
> >
> > [ 846.841165] #0: ffffff800b1c76b0 (nlk_cb_mutex-ROUTE){+.+.}-{4:4}, at: __netlink_dump_start+0x100/0x800
> >
> >
> >
> > [ 846.841237] #1: ffffffc084924408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_dumpit+0x128/0x1a8
> >
> >
> >
> > Reverting this patch recovers smsc95xx functionality.
> >
> >
> >
> > Best Regards,
> >
> >
> >
> > Oleksij
> >
>
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [bug report] [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism
2025-07-05 6:41 ` qiang.zhang
@ 2025-07-07 7:09 ` Oleksij Rempel
0 siblings, 0 replies; 6+ messages in thread
From: Oleksij Rempel @ 2025-07-07 7:09 UTC (permalink / raw)
To: qiang.zhang
Cc: Jun Miao, sbhatta, kuba, oneukum, netdev, linux-usb, linux-kernel
Hello, Zqiang
On Sat, Jul 05, 2025 at 06:41:20AM +0000, qiang.zhang@linux.dev wrote:
> > Hello, Oleksij
> >
> > Please try follow patch base on Jun Miao's patchs:
> >
>
> Sorry, please ignore previous, try it:
>
> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
> index 9564478a79cc..6a3cca104af9 100644
> --- a/drivers/net/usb/usbnet.c
> +++ b/drivers/net/usb/usbnet.c
> @@ -861,14 +861,14 @@ int usbnet_stop (struct net_device *net)
> /* deferred work (timer, softirq, task) must also stop */
> dev->flags = 0;
> timer_delete_sync(&dev->delay);
> - disable_work_sync(&dev->bh_work);
> + cancel_work_sync(&dev->bh_work);
> cancel_work_sync(&dev->kevent);
>
> /* We have cyclic dependencies. Those calls are needed
> * to break a cycle. We cannot fall into the gaps because
> * we have a flag
> */
> - disable_work_sync(&dev->bh_work);
> + cancel_work_sync(&dev->bh_work);
> timer_delete_sync(&dev->delay);
> cancel_work_sync(&dev->kevent);
It seems to work now, thank you!
Tested on LAN9512 and ASIX AX88772B.
You can add my:
Reported-by: Oleksij Rempel <o.rempel@pengutronix.de>
Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
Best Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-07-07 7:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-18 17:39 [PATCH v6] net: usb: Convert tasklet API to new bottom half workqueue mechanism Jun Miao
2025-06-19 22:50 ` patchwork-bot+netdevbpf
2025-07-04 16:40 ` [bug report] " Oleksij Rempel
2025-07-05 6:07 ` qiang.zhang
2025-07-05 6:41 ` qiang.zhang
2025-07-07 7:09 ` Oleksij Rempel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).