Skip to content

Commit 39f3901

Browse files
committed
netfilter: nft_hash: no need for rcu in the hash set destroy path
The sets are released from the rcu callback, after the rule is removed from the chain list, which implies that nfnetlink cannot update the hashes (thus, no resizing may occur) and no packets are walking on the set anymore. This resolves a lockdep splat in the nft_hash_destroy() path since the nfnl mutex is not held there. =============================== [ INFO: suspicious RCU usage. ] 3.16.0-rc2+ #168 Not tainted ------------------------------- net/netfilter/nft_hash.c:362 suspicious rcu_dereference_protected() usage! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 1 1 lock held by ksoftirqd/0/3: #0: (rcu_callback){......}, at: [<ffffffff81096393>] rcu_process_callbacks+0x27e/0x4c7 stack backtrace: CPU: 0 PID: 3 Comm: ksoftirqd/0 Not tainted 3.16.0-rc2+ #168 Hardware name: LENOVO 23259H1/23259H1, BIOS G2ET32WW (1.12 ) 05/30/2012 0000000000000001 ffff88011769bb98 ffffffff8142c922 0000000000000006 ffff880117694090 ffff88011769bbc8 ffffffff8107c3ff ffff8800cba52400 ffff8800c476bea8 ffff8800c476bea8 ffff8800cba52400 ffff88011769bc08 Call Trace: [<ffffffff8142c922>] dump_stack+0x4e/0x68 [<ffffffff8107c3ff>] lockdep_rcu_suspicious+0xfa/0x103 [<ffffffffa079931e>] nft_hash_destroy+0x50/0x137 [nft_hash] [<ffffffffa078cd57>] nft_set_destroy+0x11/0x2a [nf_tables] Signed-off-by: Pablo Neira Ayuso <[email protected]> Acked-by: Thomas Graf <[email protected]>
1 parent bec6bfb commit 39f3901

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

net/netfilter/nft_hash.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,17 @@ static int nft_hash_init(const struct nft_set *set,
180180
static void nft_hash_destroy(const struct nft_set *set)
181181
{
182182
const struct rhashtable *priv = nft_set_priv(set);
183-
const struct bucket_table *tbl;
183+
const struct bucket_table *tbl = priv->tbl;
184184
struct nft_hash_elem *he, *next;
185185
unsigned int i;
186186

187-
tbl = rht_dereference(priv->tbl, priv);
188-
for (i = 0; i < tbl->size; i++)
189-
rht_for_each_entry_safe(he, next, tbl->buckets[i], priv, node)
187+
for (i = 0; i < tbl->size; i++) {
188+
for (he = rht_entry(tbl->buckets[i], struct nft_hash_elem, node);
189+
he != NULL; he = next) {
190+
next = rht_entry(he->node.next, struct nft_hash_elem, node);
190191
nft_hash_elem_destroy(set, he);
191-
192+
}
193+
}
192194
rhashtable_destroy(priv);
193195
}
194196

0 commit comments

Comments
 (0)