diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-07-18 20:18:09 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-07-24 12:23:16 +0200 |
commit | 9f08ea848117ab521efcfd3e004d8e1a0edc640c (patch) | |
tree | d1c5ac609cee2c686ca887707497477ac792537b /net/netfilter/nf_tables_core.c | |
parent | 56a97e701c49ff66dd1a5e5e02775209ab5147d3 (diff) |
netfilter: nf_tables: keep chain counters away from hot path
These chain counters are only used by the iptables-compat tool, that
allow users to use the x_tables extensions from the existing nf_tables
framework. This patch makes nf_tables by ~5% for the general usecase,
ie. native nft users, where no chain counters are used at all.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nf_tables_core.c')
-rw-r--r-- | net/netfilter/nf_tables_core.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 65dbeadcb118..c5bab08b0d73 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -114,6 +114,22 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr, return true; } +DEFINE_STATIC_KEY_FALSE(nft_counters_enabled); + +static noinline void nft_update_chain_stats(const struct nft_chain *chain, + const struct nft_pktinfo *pkt) +{ + struct nft_stats *stats; + + local_bh_disable(); + stats = this_cpu_ptr(rcu_dereference(nft_base_chain(chain)->stats)); + u64_stats_update_begin(&stats->syncp); + stats->pkts++; + stats->bytes += pkt->skb->len; + u64_stats_update_end(&stats->syncp); + local_bh_enable(); +} + struct nft_jumpstack { const struct nft_chain *chain; const struct nft_rule *rule; @@ -130,7 +146,6 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) struct nft_regs regs; unsigned int stackptr = 0; struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; - struct nft_stats *stats; int rulenum; unsigned int gencursor = nft_genmask_cur(net); struct nft_traceinfo info; @@ -220,13 +235,8 @@ next_rule: nft_trace_packet(&info, basechain, NULL, -1, NFT_TRACETYPE_POLICY); - rcu_read_lock_bh(); - stats = this_cpu_ptr(rcu_dereference(nft_base_chain(basechain)->stats)); - u64_stats_update_begin(&stats->syncp); - stats->pkts++; - stats->bytes += pkt->skb->len; - u64_stats_update_end(&stats->syncp); - rcu_read_unlock_bh(); + if (static_branch_unlikely(&nft_counters_enabled)) + nft_update_chain_stats(basechain, pkt); return nft_base_chain(basechain)->policy; } |