aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch')
-rw-r--r--target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch91
1 files changed, 91 insertions, 0 deletions
diff --git a/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch b/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch
new file mode 100644
index 0000000000..35800c4acf
--- /dev/null
+++ b/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch
@@ -0,0 +1,91 @@
+From 4e645b47c4f000a503b9c90163ad905786b9bc1d Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Fri, 1 Dec 2017 00:21:02 +0100
+Subject: [PATCH 02/11] netfilter: core: make nf_unregister_net_hooks simple
+ wrapper again
+
+This reverts commit d3ad2c17b4047
+("netfilter: core: batch nf_unregister_net_hooks synchronize_net calls").
+
+Nothing wrong with it. However, followup patch will delay freeing of hooks
+with call_rcu, so all synchronize_net() calls become obsolete and there
+is no need anymore for this batching.
+
+This revert causes a temporary performance degradation when destroying
+network namespace, but its resolved with the upcoming call_rcu conversion.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ net/netfilter/core.c | 59 +++-------------------------------------------------
+ 1 file changed, 3 insertions(+), 56 deletions(-)
+
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -395,63 +395,10 @@ EXPORT_SYMBOL(nf_register_net_hooks);
+ void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
+ unsigned int hookcount)
+ {
+- struct nf_hook_entries *to_free[16], *p;
+- struct nf_hook_entries __rcu **pp;
+- unsigned int i, j, n;
++ unsigned int i;
+
+- mutex_lock(&nf_hook_mutex);
+- for (i = 0; i < hookcount; i++) {
+- pp = nf_hook_entry_head(net, &reg[i]);
+- if (!pp)
+- continue;
+-
+- p = nf_entry_dereference(*pp);
+- if (WARN_ON_ONCE(!p))
+- continue;
+- __nf_unregister_net_hook(p, &reg[i]);
+- }
+- mutex_unlock(&nf_hook_mutex);
+-
+- do {
+- n = min_t(unsigned int, hookcount, ARRAY_SIZE(to_free));
+-
+- mutex_lock(&nf_hook_mutex);
+-
+- for (i = 0, j = 0; i < hookcount && j < n; i++) {
+- pp = nf_hook_entry_head(net, &reg[i]);
+- if (!pp)
+- continue;
+-
+- p = nf_entry_dereference(*pp);
+- if (!p)
+- continue;
+-
+- to_free[j] = __nf_hook_entries_try_shrink(pp);
+- if (to_free[j])
+- ++j;
+- }
+-
+- mutex_unlock(&nf_hook_mutex);
+-
+- if (j) {
+- unsigned int nfq;
+-
+- synchronize_net();
+-
+- /* need 2nd synchronize_net() if nfqueue is used, skb
+- * can get reinjected right before nf_queue_hook_drop()
+- */
+- nfq = nf_queue_nf_hook_drop(net);
+- if (nfq)
+- synchronize_net();
+-
+- for (i = 0; i < j; i++)
+- kvfree(to_free[i]);
+- }
+-
+- reg += n;
+- hookcount -= n;
+- } while (hookcount > 0);
++ for (i = 0; i < hookcount; i++)
++ nf_unregister_net_hook(net, &reg[i]);
+ }
+ EXPORT_SYMBOL(nf_unregister_net_hooks);
+