aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorOctavian Purdila <opurdila@ixiacom.com>2009-11-16 08:49:35 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-18 08:03:03 -0500
commit395264d509aec45149745843d9a737140a1ece16 (patch)
tree3a62939d8989232f5bb15f6386ed649ef8de8001 /net/core/dev.c
parentfccaf71011b171883efee5bae321eac4760584d1 (diff)
net: introduce NETDEV_UNREGISTER_PERNET
This new event is called once for each unique net namespace in batched unregister operations (with the argument set to a random device from that namespace) and once per device in non-batched unregister operations. It allows us to factorize some device unregister work such as clearing the routing cache. Signed-off-by: Octavian Purdila <opurdila@ixiacom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index c3e0578d29d1..e25fe5d9343b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1344,6 +1344,7 @@ rollback:
1344 nb->notifier_call(nb, NETDEV_DOWN, dev); 1344 nb->notifier_call(nb, NETDEV_DOWN, dev);
1345 } 1345 }
1346 nb->notifier_call(nb, NETDEV_UNREGISTER, dev); 1346 nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
1347 nb->notifier_call(nb, NETDEV_UNREGISTER_PERNET, dev);
1347 } 1348 }
1348 } 1349 }
1349 1350
@@ -4721,7 +4722,8 @@ static void net_set_todo(struct net_device *dev)
4721 4722
4722static void rollback_registered_many(struct list_head *head) 4723static void rollback_registered_many(struct list_head *head)
4723{ 4724{
4724 struct net_device *dev; 4725 struct net_device *dev, *aux, *fdev;
4726 LIST_HEAD(pernet_list);
4725 4727
4726 BUG_ON(dev_boot_phase); 4728 BUG_ON(dev_boot_phase);
4727 ASSERT_RTNL(); 4729 ASSERT_RTNL();
@@ -4779,8 +4781,24 @@ static void rollback_registered_many(struct list_head *head)
4779 4781
4780 synchronize_net(); 4782 synchronize_net();
4781 4783
4782 list_for_each_entry(dev, head, unreg_list) 4784 list_for_each_entry_safe(dev, aux, head, unreg_list) {
4785 int new_net = 1;
4786 list_for_each_entry(fdev, &pernet_list, unreg_list) {
4787 if (dev_net(dev) == dev_net(fdev)) {
4788 new_net = 0;
4789 dev_put(dev);
4790 break;
4791 }
4792 }
4793 if (new_net)
4794 list_move(&dev->unreg_list, &pernet_list);
4795 }
4796
4797 list_for_each_entry_safe(dev, aux, &pernet_list, unreg_list) {
4798 call_netdevice_notifiers(NETDEV_UNREGISTER_PERNET, dev);
4799 list_move(&dev->unreg_list, head);
4783 dev_put(dev); 4800 dev_put(dev);
4801 }
4784} 4802}
4785 4803
4786static void rollback_registered(struct net_device *dev) 4804static void rollback_registered(struct net_device *dev)
@@ -5074,6 +5092,8 @@ static void netdev_wait_allrefs(struct net_device *dev)
5074 5092
5075 /* Rebroadcast unregister notification */ 5093 /* Rebroadcast unregister notification */
5076 call_netdevice_notifiers(NETDEV_UNREGISTER, dev); 5094 call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
5095 /* don't resend NETDEV_UNREGISTER_PERNET, _PERNET users
5096 * should have already handle it the first time */
5077 5097
5078 if (test_bit(__LINK_STATE_LINKWATCH_PENDING, 5098 if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
5079 &dev->state)) { 5099 &dev->state)) {
@@ -5385,6 +5405,10 @@ EXPORT_SYMBOL(unregister_netdevice_queue);
5385 * unregister_netdevice_many - unregister many devices 5405 * unregister_netdevice_many - unregister many devices
5386 * @head: list of devices 5406 * @head: list of devices
5387 * 5407 *
5408 * WARNING: Calling this modifies the given list
5409 * (in rollback_registered_many). It may change the order of the elements
5410 * in the list. However, you can assume it does not add or delete elements
5411 * to/from the list.
5388 */ 5412 */
5389void unregister_netdevice_many(struct list_head *head) 5413void unregister_netdevice_many(struct list_head *head)
5390{ 5414{
@@ -5504,6 +5528,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
5504 this device. They should clean all the things. 5528 this device. They should clean all the things.
5505 */ 5529 */
5506 call_netdevice_notifiers(NETDEV_UNREGISTER, dev); 5530 call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
5531 call_netdevice_notifiers(NETDEV_UNREGISTER_PERNET, dev);
5507 5532
5508 /* 5533 /*
5509 * Flush the unicast and multicast chains 5534 * Flush the unicast and multicast chains