summaryrefslogtreecommitdiff
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2021-04-14 18:12:53 +0200
committerSteffen Klassert <steffen.klassert@secunet.com>2021-04-19 12:25:11 +0200
commit6218fe186109b93a2fa2343e13981e016e9961ab (patch)
treea28194aa53b05dd3dcebbddbffed0e2ba9626e63 /net/xfrm/xfrm_user.c
parent7baf867fef7cc65d666792e9d1b911beffe74ad7 (diff)
xfrm: avoid synchronize_rcu during netns destruction
Use the new exit_pre hook to NULL the netlink socket. The net namespace core will do a synchronize_rcu() between the exit_pre and exit/exit_batch handlers. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index df8bc8fc724c..f0aecee4d539 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -3480,18 +3480,22 @@ static int __net_init xfrm_user_net_init(struct net *net)
return 0;
}
+static void __net_exit xfrm_user_net_pre_exit(struct net *net)
+{
+ RCU_INIT_POINTER(net->xfrm.nlsk, NULL);
+}
+
static void __net_exit xfrm_user_net_exit(struct list_head *net_exit_list)
{
struct net *net;
- list_for_each_entry(net, net_exit_list, exit_list)
- RCU_INIT_POINTER(net->xfrm.nlsk, NULL);
- synchronize_net();
+
list_for_each_entry(net, net_exit_list, exit_list)
netlink_kernel_release(net->xfrm.nlsk_stash);
}
static struct pernet_operations xfrm_user_net_ops = {
.init = xfrm_user_net_init,
+ .pre_exit = xfrm_user_net_pre_exit,
.exit_batch = xfrm_user_net_exit,
};