Skip to content

Commit 1acdb76

Browse files
edumazetNipaLocal
authored andcommitted
usbnet: avoid a possible crash in dql_completed()
syzbot reported a crash [1] in dql_completed() after recent usbnet BQL adoption. The reason for the crash is that netdev_reset_queue() is called too soon. It should be called after cancel_work_sync(&dev->bh_work) to make sure no more TX completion can happen. [1] kernel BUG at lib/dynamic_queue_limits.c:99 ! Oops: invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 1 UID: 0 PID: 5197 Comm: udevd Tainted: G L syzkaller #0 PREEMPT(full) Tainted: [L]=SOFTLOCKUP Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025 RIP: 0010:dql_completed+0xbe1/0xbf0 lib/dynamic_queue_limits.c:99 Call Trace: <IRQ> netdev_tx_completed_queue include/linux/netdevice.h:3864 [inline] netdev_completed_queue include/linux/netdevice.h:3894 [inline] usbnet_bh+0x793/0x1020 drivers/net/usb/usbnet.c:1601 process_one_work kernel/workqueue.c:3257 [inline] process_scheduled_works+0xad1/0x1770 kernel/workqueue.c:3340 bh_worker+0x2b1/0x600 kernel/workqueue.c:3611 tasklet_action+0xc/0x70 kernel/softirq.c:952 handle_softirqs+0x27d/0x850 kernel/softirq.c:622 __do_softirq kernel/softirq.c:656 [inline] invoke_softirq kernel/softirq.c:496 [inline] __irq_exit_rcu+0xca/0x1f0 kernel/softirq.c:723 irq_exit_rcu+0x9/0x30 kernel/softirq.c:739 Fixes: 7ff14c5 ("usbnet: Add support for Byte Queue Limits (BQL)") Reported-by: syzbot+5b55e49f8bbd84631a9c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6945644f.a70a0220.207337.0113.GAE@google.com/T/#u Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Simon Schippers <simon.schippers@tu-dortmund.de> Signed-off-by: NipaLocal <nipa@local>
1 parent 1ed9671 commit 1acdb76

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

drivers/net/usb/usbnet.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,6 @@ int usbnet_stop(struct net_device *net)
831831

832832
clear_bit(EVENT_DEV_OPEN, &dev->flags);
833833
netif_stop_queue(net);
834-
netdev_reset_queue(net);
835834

836835
netif_info(dev, ifdown, dev->net,
837836
"stop stats: rx/tx %lu/%lu, errs %lu/%lu\n",
@@ -875,6 +874,8 @@ int usbnet_stop(struct net_device *net)
875874
timer_delete_sync(&dev->delay);
876875
cancel_work_sync(&dev->kevent);
877876

877+
netdev_reset_queue(net);
878+
878879
if (!pm)
879880
usb_autopm_put_interface(dev->intf);
880881

0 commit comments

Comments
 (0)