From mboxrd@z Thu Jan 1 00:00:00 1970 From: Pablo Neira Ayuso Subject: [PATCH 6/7] netfilter: nf_conntrack: decrement global counter after object release Date: Thu, 21 Nov 2013 10:05:27 +0100 Message-ID: <1385024728-4057-7-git-send-email-pablo@netfilter.org> References: <1385024728-4057-1-git-send-email-pablo@netfilter.org> Cc: davem@davemloft.net, netdev@vger.kernel.org To: netfilter-devel@vger.kernel.org Return-path: Received: from mail.us.es ([193.147.175.20]:34723 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752587Ab3KUJGD (ORCPT ); Thu, 21 Nov 2013 04:06:03 -0500 In-Reply-To: <1385024728-4057-1-git-send-email-pablo@netfilter.org> Sender: netfilter-devel-owner@vger.kernel.org List-ID: 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] [] dump_stack+0x45/0x56 [ 1136.321405] [] warn_slowpath_common+0x78/0xa0 [ 1136.321410] [] warn_slowpath_fmt+0x47/0x50 [ 1136.321414] [] debug_print_object+0x83/0xa0 [ 1136.321420] [] ? execute_in_process_context+0x90/0x90 [ 1136.321424] [] debug_check_no_obj_freed+0x20b/0x250 [ 1136.321429] [] ? kmem_cache_destroy+0x92/0x100 [ 1136.321433] [] kmem_cache_free+0x125/0x210 [ 1136.321436] [] kmem_cache_destroy+0x92/0x100 [ 1136.321443] [] nf_conntrack_cleanup_net_list+0x126/0x160 [nf_conntrack] [ 1136.321449] [] nf_conntrack_pernet_exit+0x6d/0x80 [nf_conntrack] [ 1136.321453] [] ops_exit_list.isra.3+0x53/0x60 [ 1136.321457] [] cleanup_net+0x100/0x1b0 [ 1136.321460] [] process_one_work+0x18e/0x430 [ 1136.321463] [] worker_thread+0x119/0x390 [ 1136.321467] [] ? manage_workers.isra.23+0x2a0/0x2a0 [ 1136.321470] [] kthread+0xbb/0xc0 [ 1136.321472] [] ? kthread_create_on_node+0x110/0x110 [ 1136.321477] [] ret_from_fork+0x7c/0xb0 [ 1136.321479] [] ? kthread_create_on_node+0x110/0x110 [ 1136.321481] ---[ end trace 25f53c192da70825 ]--- Reported-by: Linus Torvalds Signed-off-by: Pablo Neira Ayuso --- 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); -- 1.7.10.4