]> www.infradead.org Git - users/hch/misc.git/commitdiff
net: introduce netdev_napi_exit()
authorEric Dumazet <edumazet@google.com>
Fri, 17 Jan 2025 23:21:13 +0000 (23:21 +0000)
committerJakub Kicinski <kuba@kernel.org>
Sun, 19 Jan 2025 01:41:21 +0000 (17:41 -0800)
After 1b23cdbd2bbc ("net: protect netdev->napi_list with netdev_lock()")
it makes sense to iterate through dev->napi_list while holding
the device lock.

Also call synchronize_net() at most one time.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250117232113.1612899-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/dev.c

index fab4899b83f745a3c13c982775e287b1ff2f547d..d7cbe6ff5249a5c22dd7e0e4c929a535e1f28612 100644 (file)
@@ -11568,6 +11568,22 @@ free_dev:
 }
 EXPORT_SYMBOL(alloc_netdev_mqs);
 
+static void netdev_napi_exit(struct net_device *dev)
+{
+       if (!list_empty(&dev->napi_list)) {
+               struct napi_struct *p, *n;
+
+               netdev_lock(dev);
+               list_for_each_entry_safe(p, n, &dev->napi_list, dev_list)
+                       __netif_napi_del_locked(p);
+               netdev_unlock(dev);
+
+               synchronize_net();
+       }
+
+       kvfree(dev->napi_config);
+}
+
 /**
  * free_netdev - free network device
  * @dev: device
@@ -11579,8 +11595,6 @@ EXPORT_SYMBOL(alloc_netdev_mqs);
  */
 void free_netdev(struct net_device *dev)
 {
-       struct napi_struct *p, *n;
-
        might_sleep();
 
        /* When called immediately after register_netdevice() failed the unwind
@@ -11602,10 +11616,7 @@ void free_netdev(struct net_device *dev)
        /* Flush device addresses */
        dev_addr_flush(dev);
 
-       list_for_each_entry_safe(p, n, &dev->napi_list, dev_list)
-               netif_napi_del(p);
-
-       kvfree(dev->napi_config);
+       netdev_napi_exit(dev);
 
        ref_tracker_dir_exit(&dev->refcnt_tracker);
 #ifdef CONFIG_PCPU_DEV_REFCNT