diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-11-18 12:32:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-21 16:38:08 -0500 |
commit | a2d7ec58ac09f30ab726f216827f7c7095b2a98f (patch) | |
tree | 1b733090406abc18c42308e84703dcb703e15125 /net/netfilter | |
parent | 9205fd9ccab8ef51ad771c1917eed7b2f2225d45 (diff) |
netfilter: use jump_label for nf_hooks
On configs where CONFIG_JUMP_LABEL=y, we can replace in fast path a
load/compare/conditional jump by a single jump with no dcache reference.
Jump target is modified as soon as nf_hooks[pf][hook] switches from
empty state to non empty states. jump_label state is kept outside of
nf_hooks array so has no cost on cpu caches.
This patch removes the test on CONFIG_NETFILTER_DEBUG : No need to call
nf_hook_slow() at all if nf_hooks[pf][hook] is empty, this didnt give
useful information, but slowed down things a lot.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Patrick McHardy <kaber@trash.net>
CC: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/core.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index afca6c78948c..4aa0f4b19bd8 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
@@ -54,6 +54,12 @@ EXPORT_SYMBOL_GPL(nf_unregister_afinfo); | |||
54 | 54 | ||
55 | struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; | 55 | struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; |
56 | EXPORT_SYMBOL(nf_hooks); | 56 | EXPORT_SYMBOL(nf_hooks); |
57 | |||
58 | #if defined(CONFIG_JUMP_LABEL) | ||
59 | struct jump_label_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; | ||
60 | EXPORT_SYMBOL(nf_hooks_needed); | ||
61 | #endif | ||
62 | |||
57 | static DEFINE_MUTEX(nf_hook_mutex); | 63 | static DEFINE_MUTEX(nf_hook_mutex); |
58 | 64 | ||
59 | int nf_register_hook(struct nf_hook_ops *reg) | 65 | int nf_register_hook(struct nf_hook_ops *reg) |
@@ -70,6 +76,9 @@ int nf_register_hook(struct nf_hook_ops *reg) | |||
70 | } | 76 | } |
71 | list_add_rcu(®->list, elem->list.prev); | 77 | list_add_rcu(®->list, elem->list.prev); |
72 | mutex_unlock(&nf_hook_mutex); | 78 | mutex_unlock(&nf_hook_mutex); |
79 | #if defined(CONFIG_JUMP_LABEL) | ||
80 | jump_label_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); | ||
81 | #endif | ||
73 | return 0; | 82 | return 0; |
74 | } | 83 | } |
75 | EXPORT_SYMBOL(nf_register_hook); | 84 | EXPORT_SYMBOL(nf_register_hook); |
@@ -79,7 +88,9 @@ void nf_unregister_hook(struct nf_hook_ops *reg) | |||
79 | mutex_lock(&nf_hook_mutex); | 88 | mutex_lock(&nf_hook_mutex); |
80 | list_del_rcu(®->list); | 89 | list_del_rcu(®->list); |
81 | mutex_unlock(&nf_hook_mutex); | 90 | mutex_unlock(&nf_hook_mutex); |
82 | 91 | #if defined(CONFIG_JUMP_LABEL) | |
92 | jump_label_dec(&nf_hooks_needed[reg->pf][reg->hooknum]); | ||
93 | #endif | ||
83 | synchronize_net(); | 94 | synchronize_net(); |
84 | } | 95 | } |
85 | EXPORT_SYMBOL(nf_unregister_hook); | 96 | EXPORT_SYMBOL(nf_unregister_hook); |