netfilter: nf_conntrack: decrement global counter after object release

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Nov 22 17:59:06 EST 2013


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=0c3c6c00c69649f4749642b3e5d82125fde1600c
Commit:     0c3c6c00c69649f4749642b3e5d82125fde1600c
Parent:     8691a9a3382f17fbf1ed808c956672c70369a2e0
Author:     Pablo Neira Ayuso <pablo at netfilter.org>
AuthorDate: Mon Nov 18 12:53:59 2013 +0100
Committer:  Pablo Neira Ayuso <pablo at netfilter.org>
CommitDate: Mon Nov 18 14:07:19 2013 +0100

    netfilter: nf_conntrack: decrement global counter after object release
    
    nf_conntrack_free() decrements our counter (net->ct.count)
    before releasing the conntrack object. That counter is used in the
    nf_conntrack_cleanup_net_list path to check if it's time to
    kmem_cache_destroy our cache of conntrack objects. I think we have
    a race there that should be easier to trigger (although still hard)
    with CONFIG_DEBUG_OBJECTS_FREE as object releases become slowier
    according to the following splat:
    
    [ 1136.321305] WARNING: CPU: 2 PID: 2483 at lib/debugobjects.c:260
    debug_print_object+0x83/0xa0()
    [ 1136.321311] ODEBUG: free active (active state 0) object type:
    timer_list hint: delayed_work_timer_fn+0x0/0x20
    ...
    [ 1136.321390] Call Trace:
    [ 1136.321398]  [<ffffffff8160d4a2>] dump_stack+0x45/0x56
    [ 1136.321405]  [<ffffffff810514e8>] warn_slowpath_common+0x78/0xa0
    [ 1136.321410]  [<ffffffff81051557>] warn_slowpath_fmt+0x47/0x50
    [ 1136.321414]  [<ffffffff812f8883>] debug_print_object+0x83/0xa0
    [ 1136.321420]  [<ffffffff8106aa90>] ? execute_in_process_context+0x90/0x90
    [ 1136.321424]  [<ffffffff812f99fb>] debug_check_no_obj_freed+0x20b/0x250
    [ 1136.321429]  [<ffffffff8112e7f2>] ? kmem_cache_destroy+0x92/0x100
    [ 1136.321433]  [<ffffffff8115d945>] kmem_cache_free+0x125/0x210
    [ 1136.321436]  [<ffffffff8112e7f2>] kmem_cache_destroy+0x92/0x100
    [ 1136.321443]  [<ffffffffa046b806>] nf_conntrack_cleanup_net_list+0x126/0x160 [nf_conntrack]
    [ 1136.321449]  [<ffffffffa046c43d>] nf_conntrack_pernet_exit+0x6d/0x80 [nf_conntrack]
    [ 1136.321453]  [<ffffffff81511cc3>] ops_exit_list.isra.3+0x53/0x60
    [ 1136.321457]  [<ffffffff815124f0>] cleanup_net+0x100/0x1b0
    [ 1136.321460]  [<ffffffff8106b31e>] process_one_work+0x18e/0x430
    [ 1136.321463]  [<ffffffff8106bf49>] worker_thread+0x119/0x390
    [ 1136.321467]  [<ffffffff8106be30>] ? manage_workers.isra.23+0x2a0/0x2a0
    [ 1136.321470]  [<ffffffff8107210b>] kthread+0xbb/0xc0
    [ 1136.321472]  [<ffffffff81072050>] ? kthread_create_on_node+0x110/0x110
    [ 1136.321477]  [<ffffffff8161b8fc>] ret_from_fork+0x7c/0xb0
    [ 1136.321479]  [<ffffffff81072050>] ? kthread_create_on_node+0x110/0x110
    [ 1136.321481] ---[ end trace 25f53c192da70825 ]---
    
    Reported-by: Linus Torvalds <torvalds at linux-foundation.org>
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
---
 net/netfilter/nf_conntrack_core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index e22d950..43549eb 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -764,9 +764,10 @@ 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);
 	nf_ct_ext_free(ct);
 	kmem_cache_free(net->ct.nf_conntrack_cachep, ct);
+	smp_mb__before_atomic_dec();
+	atomic_dec(&net->ct.count);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_free);
 



More information about the linux-mtd-cvs mailing list