Commit ee403248 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski

net: remove default_device_exit()

For some reason default_device_ops kept two exit method:

1) default_device_exit() is called for each netns being dismantled in
a cleanup_net() round. This acquires rtnl for each invocation.

2) default_device_exit_batch() is called once with the list of all netns
int the batch, allowing for a single rtnl invocation.

Get rid of the .exit() method to handle the logic from
default_device_exit_batch(), to decrease the number of rtnl acquisition
to one.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 16a41634
...@@ -10850,14 +10850,14 @@ static struct pernet_operations __net_initdata netdev_net_ops = { ...@@ -10850,14 +10850,14 @@ static struct pernet_operations __net_initdata netdev_net_ops = {
.exit = netdev_exit, .exit = netdev_exit,
}; };
static void __net_exit default_device_exit(struct net *net) static void __net_exit default_device_exit_net(struct net *net)
{ {
struct net_device *dev, *aux; struct net_device *dev, *aux;
/* /*
* Push all migratable network devices back to the * Push all migratable network devices back to the
* initial network namespace * initial network namespace
*/ */
rtnl_lock(); ASSERT_RTNL();
for_each_netdev_safe(net, dev, aux) { for_each_netdev_safe(net, dev, aux) {
int err; int err;
char fb_name[IFNAMSIZ]; char fb_name[IFNAMSIZ];
...@@ -10881,22 +10881,22 @@ static void __net_exit default_device_exit(struct net *net) ...@@ -10881,22 +10881,22 @@ static void __net_exit default_device_exit(struct net *net)
BUG(); BUG();
} }
} }
rtnl_unlock();
} }
static void __net_exit rtnl_lock_unregistering(struct list_head *net_list) static void __net_exit rtnl_lock_unregistering(struct list_head *net_list)
{ {
/* Return with the rtnl_lock held when there are no network /* Return (with the rtnl_lock held) when there are no network
* devices unregistering in any network namespace in net_list. * devices unregistering in any network namespace in net_list.
*/ */
struct net *net;
bool unregistering;
DEFINE_WAIT_FUNC(wait, woken_wake_function); DEFINE_WAIT_FUNC(wait, woken_wake_function);
bool unregistering;
struct net *net;
ASSERT_RTNL();
add_wait_queue(&netdev_unregistering_wq, &wait); add_wait_queue(&netdev_unregistering_wq, &wait);
for (;;) { for (;;) {
unregistering = false; unregistering = false;
rtnl_lock();
list_for_each_entry(net, net_list, exit_list) { list_for_each_entry(net, net_list, exit_list) {
if (net->dev_unreg_count > 0) { if (net->dev_unreg_count > 0) {
unregistering = true; unregistering = true;
...@@ -10908,6 +10908,7 @@ static void __net_exit rtnl_lock_unregistering(struct list_head *net_list) ...@@ -10908,6 +10908,7 @@ static void __net_exit rtnl_lock_unregistering(struct list_head *net_list)
__rtnl_unlock(); __rtnl_unlock();
wait_woken(&wait, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); wait_woken(&wait, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
rtnl_lock();
} }
remove_wait_queue(&netdev_unregistering_wq, &wait); remove_wait_queue(&netdev_unregistering_wq, &wait);
} }
...@@ -10923,6 +10924,11 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list) ...@@ -10923,6 +10924,11 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list)
struct net *net; struct net *net;
LIST_HEAD(dev_kill_list); LIST_HEAD(dev_kill_list);
rtnl_lock();
list_for_each_entry(net, net_list, exit_list) {
default_device_exit_net(net);
cond_resched();
}
/* To prevent network device cleanup code from dereferencing /* To prevent network device cleanup code from dereferencing
* loopback devices or network devices that have been freed * loopback devices or network devices that have been freed
* wait here for all pending unregistrations to complete, * wait here for all pending unregistrations to complete,
...@@ -10935,6 +10941,7 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list) ...@@ -10935,6 +10941,7 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list)
* default_device_exit_batch. * default_device_exit_batch.
*/ */
rtnl_lock_unregistering(net_list); rtnl_lock_unregistering(net_list);
list_for_each_entry(net, net_list, exit_list) { list_for_each_entry(net, net_list, exit_list) {
for_each_netdev_reverse(net, dev) { for_each_netdev_reverse(net, dev) {
if (dev->rtnl_link_ops && dev->rtnl_link_ops->dellink) if (dev->rtnl_link_ops && dev->rtnl_link_ops->dellink)
...@@ -10948,7 +10955,6 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list) ...@@ -10948,7 +10955,6 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list)
} }
static struct pernet_operations __net_initdata default_device_ops = { static struct pernet_operations __net_initdata default_device_ops = {
.exit = default_device_exit,
.exit_batch = default_device_exit_batch, .exit_batch = default_device_exit_batch,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment