Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: usb: Convert tasklet API to new bottom half workqueue mechanism

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>
Link: https://patch.msgid.link/20250618173923.950510-1-jun.miao@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Jun Miao and committed by
Jakub Kicinski
2c04d279 deb21a6e

+19 -19
+18 -18
drivers/net/usb/usbnet.c
··· 461 461 462 462 __skb_queue_tail(&dev->done, skb); 463 463 if (dev->done.qlen == 1) 464 - tasklet_schedule(&dev->bh); 464 + queue_work(system_bh_wq, &dev->bh_work); 465 465 spin_unlock(&dev->done.lock); 466 466 spin_unlock_irqrestore(&list->lock, flags); 467 467 return old_state; ··· 549 549 default: 550 550 netif_dbg(dev, rx_err, dev->net, 551 551 "rx submit, %d\n", retval); 552 - tasklet_schedule (&dev->bh); 552 + queue_work(system_bh_wq, &dev->bh_work); 553 553 break; 554 554 case 0: 555 555 __usbnet_queue_skb(&dev->rxq, skb, rx_start); ··· 709 709 num++; 710 710 } 711 711 712 - tasklet_schedule(&dev->bh); 712 + queue_work(system_bh_wq, &dev->bh_work); 713 713 714 714 netif_dbg(dev, rx_status, dev->net, 715 715 "paused rx queue disabled, %d skbs requeued\n", num); ··· 778 778 { 779 779 if (netif_running(dev->net)) { 780 780 (void) unlink_urbs (dev, &dev->rxq); 781 - tasklet_schedule(&dev->bh); 781 + queue_work(system_bh_wq, &dev->bh_work); 782 782 } 783 783 } 784 784 EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs); ··· 861 861 /* deferred work (timer, softirq, task) must also stop */ 862 862 dev->flags = 0; 863 863 timer_delete_sync(&dev->delay); 864 - tasklet_kill(&dev->bh); 864 + disable_work_sync(&dev->bh_work); 865 865 cancel_work_sync(&dev->kevent); 866 866 867 867 /* We have cyclic dependencies. Those calls are needed 868 868 * to break a cycle. We cannot fall into the gaps because 869 869 * we have a flag 870 870 */ 871 - tasklet_kill(&dev->bh); 871 + disable_work_sync(&dev->bh_work); 872 872 timer_delete_sync(&dev->delay); 873 873 cancel_work_sync(&dev->kevent); 874 874 ··· 955 955 clear_bit(EVENT_RX_KILL, &dev->flags); 956 956 957 957 // delay posting reads until we're fully open 958 - tasklet_schedule (&dev->bh); 958 + queue_work(system_bh_wq, &dev->bh_work); 959 959 if (info->manage_power) { 960 960 retval = info->manage_power(dev, 1); 961 961 if (retval < 0) { ··· 1123 1123 */ 1124 1124 } else { 1125 1125 /* submitting URBs for reading packets */ 1126 - tasklet_schedule(&dev->bh); 1126 + queue_work(system_bh_wq, &dev->bh_work); 1127 1127 } 1128 1128 1129 1129 /* hard_mtu or rx_urb_size may change during link change */ ··· 1198 1198 } else { 1199 1199 clear_bit (EVENT_RX_HALT, &dev->flags); 1200 1200 if (!usbnet_going_away(dev)) 1201 - tasklet_schedule(&dev->bh); 1201 + queue_work(system_bh_wq, &dev->bh_work); 1202 1202 } 1203 1203 } 1204 1204 1205 - /* tasklet could resubmit itself forever if memory is tight */ 1205 + /* work could resubmit itself forever if memory is tight */ 1206 1206 if (test_bit (EVENT_RX_MEMORY, &dev->flags)) { 1207 1207 struct urb *urb = NULL; 1208 1208 int resched = 1; ··· 1224 1224 fail_lowmem: 1225 1225 if (resched) 1226 1226 if (!usbnet_going_away(dev)) 1227 - tasklet_schedule(&dev->bh); 1227 + queue_work(system_bh_wq, &dev->bh_work); 1228 1228 } 1229 1229 } 1230 1230 ··· 1325 1325 struct usbnet *dev = netdev_priv(net); 1326 1326 1327 1327 unlink_urbs (dev, &dev->txq); 1328 - tasklet_schedule (&dev->bh); 1328 + queue_work(system_bh_wq, &dev->bh_work); 1329 1329 /* this needs to be handled individually because the generic layer 1330 1330 * doesn't know what is sufficient and could not restore private 1331 1331 * information if a remedy of an unconditional reset were used. ··· 1547 1547 1548 1548 /*-------------------------------------------------------------------------*/ 1549 1549 1550 - // tasklet (work deferred from completions, in_irq) or timer 1550 + // work (work deferred from completions, in_irq) or timer 1551 1551 1552 1552 static void usbnet_bh (struct timer_list *t) 1553 1553 { ··· 1601 1601 "rxqlen %d --> %d\n", 1602 1602 temp, dev->rxq.qlen); 1603 1603 if (dev->rxq.qlen < RX_QLEN(dev)) 1604 - tasklet_schedule (&dev->bh); 1604 + queue_work(system_bh_wq, &dev->bh_work); 1605 1605 } 1606 1606 if (dev->txq.qlen < TX_QLEN (dev)) 1607 1607 netif_wake_queue (dev->net); 1608 1608 } 1609 1609 } 1610 1610 1611 - static void usbnet_bh_tasklet(struct tasklet_struct *t) 1611 + static void usbnet_bh_work(struct work_struct *work) 1612 1612 { 1613 - struct usbnet *dev = from_tasklet(dev, t, bh); 1613 + struct usbnet *dev = from_work(dev, work, bh_work); 1614 1614 1615 1615 usbnet_bh(&dev->delay); 1616 1616 } ··· 1742 1742 skb_queue_head_init (&dev->txq); 1743 1743 skb_queue_head_init (&dev->done); 1744 1744 skb_queue_head_init(&dev->rxq_pause); 1745 - tasklet_setup(&dev->bh, usbnet_bh_tasklet); 1745 + INIT_WORK(&dev->bh_work, usbnet_bh_work); 1746 1746 INIT_WORK (&dev->kevent, usbnet_deferred_kevent); 1747 1747 init_usb_anchor(&dev->deferred); 1748 1748 timer_setup(&dev->delay, usbnet_bh, 0); ··· 1971 1971 1972 1972 if (!(dev->txq.qlen >= TX_QLEN(dev))) 1973 1973 netif_tx_wake_all_queues(dev->net); 1974 - tasklet_schedule (&dev->bh); 1974 + queue_work(system_bh_wq, &dev->bh_work); 1975 1975 } 1976 1976 } 1977 1977
+1 -1
include/linux/usb/usbnet.h
··· 58 58 unsigned interrupt_count; 59 59 struct mutex interrupt_mutex; 60 60 struct usb_anchor deferred; 61 - struct tasklet_struct bh; 61 + struct work_struct bh_work; 62 62 63 63 struct work_struct kevent; 64 64 unsigned long flags;