mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 22:51:42 +00:00
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>
This commit is contained in:
parent
fccaf71011
commit
395264d509
@ -202,6 +202,7 @@ static inline int notifier_to_errno(int ret)
|
|||||||
#define NETDEV_BONDING_OLDTYPE 0x000E
|
#define NETDEV_BONDING_OLDTYPE 0x000E
|
||||||
#define NETDEV_BONDING_NEWTYPE 0x000F
|
#define NETDEV_BONDING_NEWTYPE 0x000F
|
||||||
#define NETDEV_POST_INIT 0x0010
|
#define NETDEV_POST_INIT 0x0010
|
||||||
|
#define NETDEV_UNREGISTER_PERNET 0x0011
|
||||||
|
|
||||||
#define SYS_DOWN 0x0001 /* Notify of system down */
|
#define SYS_DOWN 0x0001 /* Notify of system down */
|
||||||
#define SYS_RESTART SYS_DOWN
|
#define SYS_RESTART SYS_DOWN
|
||||||
|
@ -1344,6 +1344,7 @@ rollback:
|
|||||||
nb->notifier_call(nb, NETDEV_DOWN, dev);
|
nb->notifier_call(nb, NETDEV_DOWN, dev);
|
||||||
}
|
}
|
||||||
nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
|
nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
|
||||||
|
nb->notifier_call(nb, NETDEV_UNREGISTER_PERNET, dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4721,7 +4722,8 @@ static void net_set_todo(struct net_device *dev)
|
|||||||
|
|
||||||
static void rollback_registered_many(struct list_head *head)
|
static void rollback_registered_many(struct list_head *head)
|
||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev, *aux, *fdev;
|
||||||
|
LIST_HEAD(pernet_list);
|
||||||
|
|
||||||
BUG_ON(dev_boot_phase);
|
BUG_ON(dev_boot_phase);
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
@ -4779,8 +4781,24 @@ static void rollback_registered_many(struct list_head *head)
|
|||||||
|
|
||||||
synchronize_net();
|
synchronize_net();
|
||||||
|
|
||||||
list_for_each_entry(dev, head, unreg_list)
|
list_for_each_entry_safe(dev, aux, head, unreg_list) {
|
||||||
|
int new_net = 1;
|
||||||
|
list_for_each_entry(fdev, &pernet_list, unreg_list) {
|
||||||
|
if (dev_net(dev) == dev_net(fdev)) {
|
||||||
|
new_net = 0;
|
||||||
|
dev_put(dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (new_net)
|
||||||
|
list_move(&dev->unreg_list, &pernet_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(dev, aux, &pernet_list, unreg_list) {
|
||||||
|
call_netdevice_notifiers(NETDEV_UNREGISTER_PERNET, dev);
|
||||||
|
list_move(&dev->unreg_list, head);
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rollback_registered(struct net_device *dev)
|
static void rollback_registered(struct net_device *dev)
|
||||||
@ -5074,6 +5092,8 @@ static void netdev_wait_allrefs(struct net_device *dev)
|
|||||||
|
|
||||||
/* Rebroadcast unregister notification */
|
/* Rebroadcast unregister notification */
|
||||||
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
|
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
|
||||||
|
/* don't resend NETDEV_UNREGISTER_PERNET, _PERNET users
|
||||||
|
* should have already handle it the first time */
|
||||||
|
|
||||||
if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
|
if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
|
||||||
&dev->state)) {
|
&dev->state)) {
|
||||||
@ -5385,6 +5405,10 @@ EXPORT_SYMBOL(unregister_netdevice_queue);
|
|||||||
* unregister_netdevice_many - unregister many devices
|
* unregister_netdevice_many - unregister many devices
|
||||||
* @head: list of devices
|
* @head: list of devices
|
||||||
*
|
*
|
||||||
|
* WARNING: Calling this modifies the given list
|
||||||
|
* (in rollback_registered_many). It may change the order of the elements
|
||||||
|
* in the list. However, you can assume it does not add or delete elements
|
||||||
|
* to/from the list.
|
||||||
*/
|
*/
|
||||||
void unregister_netdevice_many(struct list_head *head)
|
void unregister_netdevice_many(struct list_head *head)
|
||||||
{
|
{
|
||||||
@ -5504,6 +5528,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
|
|||||||
this device. They should clean all the things.
|
this device. They should clean all the things.
|
||||||
*/
|
*/
|
||||||
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
|
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
|
||||||
|
call_netdevice_notifiers(NETDEV_UNREGISTER_PERNET, dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush the unicast and multicast chains
|
* Flush the unicast and multicast chains
|
||||||
|
Loading…
Reference in New Issue
Block a user