Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d79d792e authored by Eric W. Biederman's avatar Eric W. Biederman Committed by David S. Miller
Browse files

net: Allow xfrm_user_net_exit to batch efficiently.



xfrm.nlsk is provided by the xfrm_user module and is access via rcu from
other parts of the xfrm code.  Add xfrm.nlsk_stash a copy of xfrm.nlsk that
will never be set to NULL.  This allows the synchronize_net and
netlink_kernel_release to be deferred until a whole batch of xfrm.nlsk sockets
have been set to NULL.

Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 04dc7f6b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ struct netns_xfrm {
	struct work_struct	policy_hash_work;

	struct sock		*nlsk;
	struct sock		*nlsk_stash;

	u32			sysctl_aevent_etime;
	u32			sysctl_aevent_rseqth;
+10 −8
Original line number Diff line number Diff line
@@ -2721,22 +2721,24 @@ static int __net_init xfrm_user_net_init(struct net *net)
				     xfrm_netlink_rcv, NULL, THIS_MODULE);
	if (nlsk == NULL)
		return -ENOMEM;
	net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */
	rcu_assign_pointer(net->xfrm.nlsk, nlsk);
	return 0;
}

static void __net_exit xfrm_user_net_exit(struct net *net)
static void __net_exit xfrm_user_net_exit(struct list_head *net_exit_list)
{
	struct sock *nlsk = net->xfrm.nlsk;

	struct net *net;
	list_for_each_entry(net, net_exit_list, exit_list)
		rcu_assign_pointer(net->xfrm.nlsk, NULL);
	synchronize_rcu();
	netlink_kernel_release(nlsk);
	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,
	.exit = xfrm_user_net_exit,
	.exit_batch = xfrm_user_net_exit,
};

static int __init xfrm_user_init(void)