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

Commit 4907abc6 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

net: dynamically allocate fqdir structures



Following patch will add rcu grace period before fqdir
rhashtable destruction, so we need to dynamically allocate
fqdir structures to not force expensive synchronize_rcu() calls
in netns dismantle path.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a39aca67
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -105,14 +105,25 @@ struct inet_frags {
int inet_frags_init(struct inet_frags *);
void inet_frags_fini(struct inet_frags *);

static inline int fqdir_init(struct fqdir *fqdir, struct inet_frags *f,
static inline int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f,
			     struct net *net)
{
	struct fqdir *fqdir = kzalloc(sizeof(*fqdir), GFP_KERNEL);
	int res;

	if (!fqdir)
		return -ENOMEM;
	fqdir->f = f;
	fqdir->net = net;
	atomic_long_set(&fqdir->mem, 0);
	return rhashtable_init(&fqdir->rhashtable, &fqdir->f->rhash_params);
	res = rhashtable_init(&fqdir->rhashtable, &fqdir->f->rhash_params);
	if (res < 0) {
		kfree(fqdir);
		return res;
	}
	*fqdirp = fqdir;
	return 0;
}

void fqdir_exit(struct fqdir *fqdir);

void inet_frag_kill(struct inet_frag_queue *q);
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ struct netns_sysctl_lowpan {

struct netns_ieee802154_lowpan {
	struct netns_sysctl_lowpan sysctl;
	struct fqdir		fqdir;
	struct fqdir		*fqdir;
};

#endif
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ struct netns_ipv4 {

	struct inet_peer_base	*peers;
	struct sock  * __percpu	*tcp_sk;
	struct fqdir		fqdir;
	struct fqdir		*fqdir;
#ifdef CONFIG_NETFILTER
	struct xt_table		*iptable_filter;
	struct xt_table		*iptable_mangle;
+2 −2
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ struct netns_ipv6 {
	struct ipv6_devconf	*devconf_all;
	struct ipv6_devconf	*devconf_dflt;
	struct inet_peer_base	*peers;
	struct fqdir		fqdir;
	struct fqdir		*fqdir;
#ifdef CONFIG_NETFILTER
	struct xt_table		*ip6table_filter;
	struct xt_table		*ip6table_mangle;
@@ -116,7 +116,7 @@ struct netns_ipv6 {

#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
struct netns_nf_frag {
	struct fqdir	fqdir;
	struct fqdir	*fqdir;
};
#endif

+13 −11
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ fq_find(struct net *net, const struct lowpan_802154_cb *cb,
	key.src = *src;
	key.dst = *dst;

	q = inet_frag_find(&ieee802154_lowpan->fqdir, &key);
	q = inet_frag_find(ieee802154_lowpan->fqdir, &key);
	if (!q)
		return NULL;

@@ -377,11 +377,11 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
			table[0].procname = NULL;
	}

	table[0].data	= &ieee802154_lowpan->fqdir.high_thresh;
	table[0].extra1	= &ieee802154_lowpan->fqdir.low_thresh;
	table[1].data	= &ieee802154_lowpan->fqdir.low_thresh;
	table[1].extra2	= &ieee802154_lowpan->fqdir.high_thresh;
	table[2].data	= &ieee802154_lowpan->fqdir.timeout;
	table[0].data	= &ieee802154_lowpan->fqdir->high_thresh;
	table[0].extra1	= &ieee802154_lowpan->fqdir->low_thresh;
	table[1].data	= &ieee802154_lowpan->fqdir->low_thresh;
	table[1].extra2	= &ieee802154_lowpan->fqdir->high_thresh;
	table[2].data	= &ieee802154_lowpan->fqdir->timeout;

	hdr = register_net_sysctl(net, "net/ieee802154/6lowpan", table);
	if (hdr == NULL)
@@ -449,16 +449,18 @@ static int __net_init lowpan_frags_init_net(struct net *net)
		net_ieee802154_lowpan(net);
	int res;

	ieee802154_lowpan->fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH;
	ieee802154_lowpan->fqdir.low_thresh = IPV6_FRAG_LOW_THRESH;
	ieee802154_lowpan->fqdir.timeout = IPV6_FRAG_TIMEOUT;

	res = fqdir_init(&ieee802154_lowpan->fqdir, &lowpan_frags, net);
	if (res < 0)
		return res;

	ieee802154_lowpan->fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH;
	ieee802154_lowpan->fqdir->low_thresh = IPV6_FRAG_LOW_THRESH;
	ieee802154_lowpan->fqdir->timeout = IPV6_FRAG_TIMEOUT;

	res = lowpan_frags_ns_sysctl_register(net);
	if (res < 0)
		fqdir_exit(&ieee802154_lowpan->fqdir);
		fqdir_exit(ieee802154_lowpan->fqdir);
	return res;
}

@@ -468,7 +470,7 @@ static void __net_exit lowpan_frags_exit_net(struct net *net)
		net_ieee802154_lowpan(net);

	lowpan_frags_ns_sysctl_unregister(net);
	fqdir_exit(&ieee802154_lowpan->fqdir);
	fqdir_exit(ieee802154_lowpan->fqdir);
}

static struct pernet_operations lowpan_frags_ops = {
Loading