aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <dada1@cosmosbay.com>2009-03-24 09:26:50 -0400
committerPatrick McHardy <kaber@trash.net>2009-03-24 09:26:50 -0400
commit1d45209d89e647e9f27e4afa1f47338df73bc112 (patch)
treea86c8e51811eafbedee01347b1a5c4e76d748b81
parentdd5b6ce6fd465eab90357711c8e8124dc3a31ff0 (diff)
netfilter: nf_conntrack: Reduce conntrack count in nf_conntrack_free()
We use RCU to defer freeing of conntrack structures. In DOS situation, RCU might accumulate about 10.000 elements per CPU in its internal queues. To get accurate conntrack counts (at the expense of slightly more RAM used), we might consider conntrack counter not taking into account "about to be freed elements, waiting in RCU queues". We thus decrement it in nf_conntrack_free(), not in the RCU callback. Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> Tested-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--net/netfilter/nf_conntrack_core.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ebc275600125..55befe59e1c0 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -517,16 +517,17 @@ EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
517static void nf_conntrack_free_rcu(struct rcu_head *head) 517static void nf_conntrack_free_rcu(struct rcu_head *head)
518{ 518{
519 struct nf_conn *ct = container_of(head, struct nf_conn, rcu); 519 struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
520 struct net *net = nf_ct_net(ct);
521 520
522 nf_ct_ext_free(ct); 521 nf_ct_ext_free(ct);
523 kmem_cache_free(nf_conntrack_cachep, ct); 522 kmem_cache_free(nf_conntrack_cachep, ct);
524 atomic_dec(&net->ct.count);
525} 523}
526 524
527void nf_conntrack_free(struct nf_conn *ct) 525void nf_conntrack_free(struct nf_conn *ct)
528{ 526{
527 struct net *net = nf_ct_net(ct);
528
529 nf_ct_ext_destroy(ct); 529 nf_ct_ext_destroy(ct);
530 atomic_dec(&net->ct.count);
530 call_rcu(&ct->rcu, nf_conntrack_free_rcu); 531 call_rcu(&ct->rcu, nf_conntrack_free_rcu);
531} 532}
532EXPORT_SYMBOL_GPL(nf_conntrack_free); 533EXPORT_SYMBOL_GPL(nf_conntrack_free);