netfilter: nf_conntrack: Reduce conntrack count in nf_conntrack_free()
authorEric Dumazet <dada1@cosmosbay.com>
Tue, 24 Mar 2009 13:26:50 +0000 (14:26 +0100)
committerPatrick McHardy <kaber@trash.net>
Tue, 24 Mar 2009 13:26:50 +0000 (14:26 +0100)
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>
net/netfilter/nf_conntrack_core.c

index ebc27560012591a7f4034a1443bf6e4cc97c4643..55befe59e1c038c01abe63ebc2b1e5d00a84a886 100644 (file)
@@ -517,16 +517,17 @@ EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
 static void nf_conntrack_free_rcu(struct rcu_head *head)
 {
        struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
-       struct net *net = nf_ct_net(ct);
 
        nf_ct_ext_free(ct);
        kmem_cache_free(nf_conntrack_cachep, ct);
-       atomic_dec(&net->ct.count);
 }
 
 void nf_conntrack_free(struct nf_conn *ct)
 {
+       struct net *net = nf_ct_net(ct);
+
        nf_ct_ext_destroy(ct);
+       atomic_dec(&net->ct.count);
        call_rcu(&ct->rcu, nf_conntrack_free_rcu);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_free);