aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-05-24 09:03:39 -0700
committerDavid S. Miller <davem@davemloft.net>2019-05-26 14:08:05 -0700
commit4907abc605e328d61bee56e4e89db4f56ade2090 (patch)
tree764e708aaa78091e2a8ccb046cfbf8a59aa10c88 /net/ipv4
parentnet: add a net pointer to struct fqdir (diff)
downloadlinux-dev-4907abc605e328d61bee56e4e89db4f56ade2090.tar.xz
linux-dev-4907abc605e328d61bee56e4e89db4f56ade2090.zip
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: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/inet_fragment.c1
-rw-r--r--net/ipv4/ip_fragment.c32
-rw-r--r--net/ipv4/proc.c4
3 files changed, 19 insertions, 18 deletions
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index a5ec5d956793..b4432f209c71 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -150,6 +150,7 @@ void fqdir_exit(struct fqdir *fqdir)
fqdir->high_thresh = 0; /* prevent creation of new frags */
rhashtable_free_and_destroy(&fqdir->rhashtable, inet_frags_free_cb, NULL);
+ kfree(fqdir);
}
EXPORT_SYMBOL(fqdir_exit);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index d59269bbe1b6..1ffaec056821 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -209,7 +209,7 @@ static struct ipq *ip_find(struct net *net, struct iphdr *iph,
};
struct inet_frag_queue *q;
- q = inet_frag_find(&net->ipv4.fqdir, &key);
+ q = inet_frag_find(net->ipv4.fqdir, &key);
if (!q)
return NULL;
@@ -589,12 +589,12 @@ static int __net_init ip4_frags_ns_ctl_register(struct net *net)
goto err_alloc;
}
- table[0].data = &net->ipv4.fqdir.high_thresh;
- table[0].extra1 = &net->ipv4.fqdir.low_thresh;
- table[1].data = &net->ipv4.fqdir.low_thresh;
- table[1].extra2 = &net->ipv4.fqdir.high_thresh;
- table[2].data = &net->ipv4.fqdir.timeout;
- table[3].data = &net->ipv4.fqdir.max_dist;
+ table[0].data = &net->ipv4.fqdir->high_thresh;
+ table[0].extra1 = &net->ipv4.fqdir->low_thresh;
+ table[1].data = &net->ipv4.fqdir->low_thresh;
+ table[1].extra2 = &net->ipv4.fqdir->high_thresh;
+ table[2].data = &net->ipv4.fqdir->timeout;
+ table[3].data = &net->ipv4.fqdir->max_dist;
hdr = register_net_sysctl(net, "net/ipv4", table);
if (!hdr)
@@ -642,6 +642,9 @@ static int __net_init ipv4_frags_init_net(struct net *net)
{
int res;
+ res = fqdir_init(&net->ipv4.fqdir, &ip4_frags, net);
+ if (res < 0)
+ return res;
/* Fragment cache limits.
*
* The fragment memory accounting code, (tries to) account for
@@ -656,30 +659,27 @@ static int __net_init ipv4_frags_init_net(struct net *net)
* we will prune down to 3MB, making room for approx 8 big 64K
* fragments 8x128k.
*/
- net->ipv4.fqdir.high_thresh = 4 * 1024 * 1024;
- net->ipv4.fqdir.low_thresh = 3 * 1024 * 1024;
+ net->ipv4.fqdir->high_thresh = 4 * 1024 * 1024;
+ net->ipv4.fqdir->low_thresh = 3 * 1024 * 1024;
/*
* Important NOTE! Fragment queue must be destroyed before MSL expires.
* RFC791 is wrong proposing to prolongate timer each fragment arrival
* by TTL.
*/
- net->ipv4.fqdir.timeout = IP_FRAG_TIME;
+ net->ipv4.fqdir->timeout = IP_FRAG_TIME;
- net->ipv4.fqdir.max_dist = 64;
+ net->ipv4.fqdir->max_dist = 64;
- res = fqdir_init(&net->ipv4.fqdir, &ip4_frags, net);
- if (res < 0)
- return res;
res = ip4_frags_ns_ctl_register(net);
if (res < 0)
- fqdir_exit(&net->ipv4.fqdir);
+ fqdir_exit(net->ipv4.fqdir);
return res;
}
static void __net_exit ipv4_frags_exit_net(struct net *net)
{
ip4_frags_ns_ctl_unregister(net);
- fqdir_exit(&net->ipv4.fqdir);
+ fqdir_exit(net->ipv4.fqdir);
}
static struct pernet_operations ip4_frags_ops = {
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 3927e00084e8..b613572c6616 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -72,8 +72,8 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "RAW: inuse %d\n",
sock_prot_inuse_get(net, &raw_prot));
seq_printf(seq, "FRAG: inuse %u memory %lu\n",
- atomic_read(&net->ipv4.fqdir.rhashtable.nelems),
- frag_mem_limit(&net->ipv4.fqdir));
+ atomic_read(&net->ipv4.fqdir->rhashtable.nelems),
+ frag_mem_limit(net->ipv4.fqdir));
return 0;
}