net: Introduce unregister_netdevice_queue()
authorEric Dumazet <eric.dumazet@gmail.com>
Tue, 27 Oct 2009 07:03:04 +0000 (07:03 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 28 Oct 2009 09:22:06 +0000 (02:22 -0700)
This patchs adds an unreg_list anchor to struct net_device, and
introduces an unregister_netdevice_queue() function, able to queue
a net_device to a list instead of immediately unregister it.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netdevice.h
net/core/dev.c

index 8380009..0ded0a4 100644 (file)
@@ -683,6 +683,7 @@ struct net_device
 
        struct list_head        dev_list;
        struct list_head        napi_list;
+       struct list_head        unreg_list;
 
        /* Net device features */
        unsigned long           features;
@@ -1116,7 +1117,13 @@ extern int               dev_close(struct net_device *dev);
 extern void            dev_disable_lro(struct net_device *dev);
 extern int             dev_queue_xmit(struct sk_buff *skb);
 extern int             register_netdevice(struct net_device *dev);
-extern void            unregister_netdevice(struct net_device *dev);
+extern void            unregister_netdevice_queue(struct net_device *dev,
+                                                  struct list_head *head);
+static inline void unregister_netdevice(struct net_device *dev)
+{
+       unregister_netdevice_queue(dev, NULL);
+}
+
 extern void            free_netdev(struct net_device *dev);
 extern void            synchronize_net(void);
 extern int             register_netdevice_notifier(struct notifier_block *nb);
index 950c13f..ff94e2b 100644 (file)
@@ -5245,25 +5245,31 @@ void synchronize_net(void)
 EXPORT_SYMBOL(synchronize_net);
 
 /**
- *     unregister_netdevice - remove device from the kernel
+ *     unregister_netdevice_queue - remove device from the kernel
  *     @dev: device
- *
+ *     @head: list
+
  *     This function shuts down a device interface and removes it
  *     from the kernel tables.
+ *     If head not NULL, device is queued to be unregistered later.
  *
  *     Callers must hold the rtnl semaphore.  You may want
  *     unregister_netdev() instead of this.
  */
 
-void unregister_netdevice(struct net_device *dev)
+void unregister_netdevice_queue(struct net_device *dev, struct list_head *head)
 {
        ASSERT_RTNL();
 
-       rollback_registered(dev);
-       /* Finish processing unregister after unlock */
-       net_set_todo(dev);
+       if (head) {
+               list_add_tail(&dev->unreg_list, head);
+       } else {
+               rollback_registered(dev);
+               /* Finish processing unregister after unlock */
+               net_set_todo(dev);
+       }
 }
-EXPORT_SYMBOL(unregister_netdevice);
+EXPORT_SYMBOL(unregister_netdevice_queue);
 
 /**
  *     unregister_netdev - remove device from the kernel