Skip to content

Commit 9b5b363

Browse files
edumazetkuba-moo
authored andcommitted
ip_tunnel: use exit_batch_rtnl() method
exit_batch_rtnl() is called while RTNL is held, and devices to be unregistered can be queued in the dev_kill_list. This saves one rtnl_lock()/rtnl_unlock() pair and one unregister_netdevice_many() call. This patch takes care of ipip, ip_vti, and ip_gre tunnels. Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Antoine Tenart <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent de02dea commit 9b5b363

File tree

5 files changed

+31
-22
lines changed

5 files changed

+31
-22
lines changed

include/net/ip_tunnels.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,8 @@ int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
284284
struct rtnl_link_ops *ops, char *devname);
285285

286286
void ip_tunnel_delete_nets(struct list_head *list_net, unsigned int id,
287-
struct rtnl_link_ops *ops);
287+
struct rtnl_link_ops *ops,
288+
struct list_head *dev_to_kill);
288289

289290
void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
290291
const struct iphdr *tnl_params, const u8 protocol);

net/ipv4/ip_gre.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,14 +1025,16 @@ static int __net_init ipgre_init_net(struct net *net)
10251025
return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
10261026
}
10271027

1028-
static void __net_exit ipgre_exit_batch_net(struct list_head *list_net)
1028+
static void __net_exit ipgre_exit_batch_rtnl(struct list_head *list_net,
1029+
struct list_head *dev_to_kill)
10291030
{
1030-
ip_tunnel_delete_nets(list_net, ipgre_net_id, &ipgre_link_ops);
1031+
ip_tunnel_delete_nets(list_net, ipgre_net_id, &ipgre_link_ops,
1032+
dev_to_kill);
10311033
}
10321034

10331035
static struct pernet_operations ipgre_net_ops = {
10341036
.init = ipgre_init_net,
1035-
.exit_batch = ipgre_exit_batch_net,
1037+
.exit_batch_rtnl = ipgre_exit_batch_rtnl,
10361038
.id = &ipgre_net_id,
10371039
.size = sizeof(struct ip_tunnel_net),
10381040
};
@@ -1697,14 +1699,16 @@ static int __net_init ipgre_tap_init_net(struct net *net)
16971699
return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
16981700
}
16991701

1700-
static void __net_exit ipgre_tap_exit_batch_net(struct list_head *list_net)
1702+
static void __net_exit ipgre_tap_exit_batch_rtnl(struct list_head *list_net,
1703+
struct list_head *dev_to_kill)
17011704
{
1702-
ip_tunnel_delete_nets(list_net, gre_tap_net_id, &ipgre_tap_ops);
1705+
ip_tunnel_delete_nets(list_net, gre_tap_net_id, &ipgre_tap_ops,
1706+
dev_to_kill);
17031707
}
17041708

17051709
static struct pernet_operations ipgre_tap_net_ops = {
17061710
.init = ipgre_tap_init_net,
1707-
.exit_batch = ipgre_tap_exit_batch_net,
1711+
.exit_batch_rtnl = ipgre_tap_exit_batch_rtnl,
17081712
.id = &gre_tap_net_id,
17091713
.size = sizeof(struct ip_tunnel_net),
17101714
};
@@ -1715,14 +1719,16 @@ static int __net_init erspan_init_net(struct net *net)
17151719
&erspan_link_ops, "erspan0");
17161720
}
17171721

1718-
static void __net_exit erspan_exit_batch_net(struct list_head *net_list)
1722+
static void __net_exit erspan_exit_batch_rtnl(struct list_head *net_list,
1723+
struct list_head *dev_to_kill)
17191724
{
1720-
ip_tunnel_delete_nets(net_list, erspan_net_id, &erspan_link_ops);
1725+
ip_tunnel_delete_nets(net_list, erspan_net_id, &erspan_link_ops,
1726+
dev_to_kill);
17211727
}
17221728

17231729
static struct pernet_operations erspan_net_ops = {
17241730
.init = erspan_init_net,
1725-
.exit_batch = erspan_exit_batch_net,
1731+
.exit_batch_rtnl = erspan_exit_batch_rtnl,
17261732
.id = &erspan_net_id,
17271733
.size = sizeof(struct ip_tunnel_net),
17281734
};

net/ipv4/ip_tunnel.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,19 +1130,17 @@ static void ip_tunnel_destroy(struct net *net, struct ip_tunnel_net *itn,
11301130
}
11311131

11321132
void ip_tunnel_delete_nets(struct list_head *net_list, unsigned int id,
1133-
struct rtnl_link_ops *ops)
1133+
struct rtnl_link_ops *ops,
1134+
struct list_head *dev_to_kill)
11341135
{
11351136
struct ip_tunnel_net *itn;
11361137
struct net *net;
1137-
LIST_HEAD(list);
11381138

1139-
rtnl_lock();
1139+
ASSERT_RTNL();
11401140
list_for_each_entry(net, net_list, exit_list) {
11411141
itn = net_generic(net, id);
1142-
ip_tunnel_destroy(net, itn, &list, ops);
1142+
ip_tunnel_destroy(net, itn, dev_to_kill, ops);
11431143
}
1144-
unregister_netdevice_many(&list);
1145-
rtnl_unlock();
11461144
}
11471145
EXPORT_SYMBOL_GPL(ip_tunnel_delete_nets);
11481146

net/ipv4/ip_vti.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,14 +510,16 @@ static int __net_init vti_init_net(struct net *net)
510510
return 0;
511511
}
512512

513-
static void __net_exit vti_exit_batch_net(struct list_head *list_net)
513+
static void __net_exit vti_exit_batch_rtnl(struct list_head *list_net,
514+
struct list_head *dev_to_kill)
514515
{
515-
ip_tunnel_delete_nets(list_net, vti_net_id, &vti_link_ops);
516+
ip_tunnel_delete_nets(list_net, vti_net_id, &vti_link_ops,
517+
dev_to_kill);
516518
}
517519

518520
static struct pernet_operations vti_net_ops = {
519521
.init = vti_init_net,
520-
.exit_batch = vti_exit_batch_net,
522+
.exit_batch_rtnl = vti_exit_batch_rtnl,
521523
.id = &vti_net_id,
522524
.size = sizeof(struct ip_tunnel_net),
523525
};

net/ipv4/ipip.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,14 +592,16 @@ static int __net_init ipip_init_net(struct net *net)
592592
return ip_tunnel_init_net(net, ipip_net_id, &ipip_link_ops, "tunl0");
593593
}
594594

595-
static void __net_exit ipip_exit_batch_net(struct list_head *list_net)
595+
static void __net_exit ipip_exit_batch_rtnl(struct list_head *list_net,
596+
struct list_head *dev_to_kill)
596597
{
597-
ip_tunnel_delete_nets(list_net, ipip_net_id, &ipip_link_ops);
598+
ip_tunnel_delete_nets(list_net, ipip_net_id, &ipip_link_ops,
599+
dev_to_kill);
598600
}
599601

600602
static struct pernet_operations ipip_net_ops = {
601603
.init = ipip_init_net,
602-
.exit_batch = ipip_exit_batch_net,
604+
.exit_batch_rtnl = ipip_exit_batch_rtnl,
603605
.id = &ipip_net_id,
604606
.size = sizeof(struct ip_tunnel_net),
605607
};

0 commit comments

Comments
 (0)