diff options
author | Eric Dumazet <edumazet@google.com> | 2019-05-24 19:03:39 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-27 00:08:05 +0300 |
commit | 4907abc605e328d61bee56e4e89db4f56ade2090 (patch) | |
tree | 764e708aaa78091e2a8ccb046cfbf8a59aa10c88 /net/ipv6 | |
parent | a39aca678a0626941aa99c18c1c452ca758e7865 (diff) | |
download | linux-4907abc605e328d61bee56e4e89db4f56ade2090.tar.xz |
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/ipv6')
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 27 | ||||
-rw-r--r-- | net/ipv6/proc.c | 4 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 24 |
3 files changed, 28 insertions, 27 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index b6f7385ed93c..c5d59fa568d6 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -90,12 +90,12 @@ static int nf_ct_frag6_sysctl_register(struct net *net) goto err_alloc; } - table[0].data = &net->nf_frag.fqdir.timeout; - table[1].data = &net->nf_frag.fqdir.low_thresh; - table[1].extra2 = &net->nf_frag.fqdir.high_thresh; - table[2].data = &net->nf_frag.fqdir.high_thresh; - table[2].extra1 = &net->nf_frag.fqdir.low_thresh; - table[2].extra2 = &init_net.nf_frag.fqdir.high_thresh; + table[0].data = &net->nf_frag.fqdir->timeout; + table[1].data = &net->nf_frag.fqdir->low_thresh; + table[1].extra2 = &net->nf_frag.fqdir->high_thresh; + table[2].data = &net->nf_frag.fqdir->high_thresh; + table[2].extra1 = &net->nf_frag.fqdir->low_thresh; + table[2].extra2 = &init_net.nf_frag.fqdir->high_thresh; hdr = register_net_sysctl(net, "net/netfilter", table); if (hdr == NULL) @@ -162,7 +162,7 @@ static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user, }; struct inet_frag_queue *q; - q = inet_frag_find(&net->nf_frag.fqdir, &key); + q = inet_frag_find(net->nf_frag.fqdir, &key); if (!q) return NULL; @@ -489,23 +489,24 @@ static int nf_ct_net_init(struct net *net) { int res; - net->nf_frag.fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH; - net->nf_frag.fqdir.low_thresh = IPV6_FRAG_LOW_THRESH; - net->nf_frag.fqdir.timeout = IPV6_FRAG_TIMEOUT; - res = fqdir_init(&net->nf_frag.fqdir, &nf_frags, net); if (res < 0) return res; + + net->nf_frag.fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH; + net->nf_frag.fqdir->low_thresh = IPV6_FRAG_LOW_THRESH; + net->nf_frag.fqdir->timeout = IPV6_FRAG_TIMEOUT; + res = nf_ct_frag6_sysctl_register(net); if (res < 0) - fqdir_exit(&net->nf_frag.fqdir); + fqdir_exit(net->nf_frag.fqdir); return res; } static void nf_ct_net_exit(struct net *net) { nf_ct_frags6_sysctl_unregister(net); - fqdir_exit(&net->nf_frag.fqdir); + fqdir_exit(net->nf_frag.fqdir); } static struct pernet_operations nf_ct_net_ops = { diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index f3e3118393c4..0bbefc440bcd 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -48,8 +48,8 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "RAW6: inuse %d\n", sock_prot_inuse_get(net, &rawv6_prot)); seq_printf(seq, "FRAG6: inuse %u memory %lu\n", - atomic_read(&net->ipv6.fqdir.rhashtable.nelems), - frag_mem_limit(&net->ipv6.fqdir)); + atomic_read(&net->ipv6.fqdir->rhashtable.nelems), + frag_mem_limit(net->ipv6.fqdir)); return 0; } diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index a6f26aa648fb..836ea964cf14 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -98,7 +98,7 @@ fq_find(struct net *net, __be32 id, const struct ipv6hdr *hdr, int iif) IPV6_ADDR_LINKLOCAL))) key.iif = 0; - q = inet_frag_find(&net->ipv6.fqdir, &key); + q = inet_frag_find(net->ipv6.fqdir, &key); if (!q) return NULL; @@ -443,11 +443,11 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net) goto err_alloc; } - table[0].data = &net->ipv6.fqdir.high_thresh; - table[0].extra1 = &net->ipv6.fqdir.low_thresh; - table[1].data = &net->ipv6.fqdir.low_thresh; - table[1].extra2 = &net->ipv6.fqdir.high_thresh; - table[2].data = &net->ipv6.fqdir.timeout; + table[0].data = &net->ipv6.fqdir->high_thresh; + table[0].extra1 = &net->ipv6.fqdir->low_thresh; + table[1].data = &net->ipv6.fqdir->low_thresh; + table[1].extra2 = &net->ipv6.fqdir->high_thresh; + table[2].data = &net->ipv6.fqdir->timeout; hdr = register_net_sysctl(net, "net/ipv6", table); if (!hdr) @@ -510,24 +510,24 @@ static int __net_init ipv6_frags_init_net(struct net *net) { int res; - net->ipv6.fqdir.high_thresh = IPV6_FRAG_HIGH_THRESH; - net->ipv6.fqdir.low_thresh = IPV6_FRAG_LOW_THRESH; - net->ipv6.fqdir.timeout = IPV6_FRAG_TIMEOUT; - res = fqdir_init(&net->ipv6.fqdir, &ip6_frags, net); if (res < 0) return res; + net->ipv6.fqdir->high_thresh = IPV6_FRAG_HIGH_THRESH; + net->ipv6.fqdir->low_thresh = IPV6_FRAG_LOW_THRESH; + net->ipv6.fqdir->timeout = IPV6_FRAG_TIMEOUT; + res = ip6_frags_ns_sysctl_register(net); if (res < 0) - fqdir_exit(&net->ipv6.fqdir); + fqdir_exit(net->ipv6.fqdir); return res; } static void __net_exit ipv6_frags_exit_net(struct net *net) { ip6_frags_ns_sysctl_unregister(net); - fqdir_exit(&net->ipv6.fqdir); + fqdir_exit(net->ipv6.fqdir); } static struct pernet_operations ip6_frags_ops = { |