netfilter: nfnetlink: place subsys mutexes in distinct lockdep classes
From time to time there are lockdep reports similar to this one:
WARNING: possible circular locking dependency detected
------------------------------------------------------
000000004f61aa56 (&table[i].mutex){+.+.}, at: nfnl_lock [nfnetlink]
but task is already holding lock:
[..] (&net->nft.commit_mutex){+.+.}, at: nf_tables_valid_genid [nf_tables]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&net->nft.commit_mutex){+.+.}:
[..]
nf_tables_valid_genid+0x18/0x60 [nf_tables]
nfnetlink_rcv_batch+0x24c/0x620 [nfnetlink]
nfnetlink_rcv+0x110/0x140 [nfnetlink]
netlink_unicast+0x12c/0x1e0
[..]
sys_sendmsg+0x18/0x40
linux_sparc_syscall+0x34/0x44
-> #0 (&table[i].mutex){+.+.}:
[..]
nfnl_lock+0x24/0x40 [nfnetlink]
ip_set_nfnl_get_byindex+0x19c/0x280 [ip_set]
set_match_v1_checkentry+0x14/0xc0 [xt_set]
xt_check_match+0x238/0x260 [x_tables]
__nft_match_init+0x160/0x180 [nft_compat]
[..]
sys_sendmsg+0x18/0x40
linux_sparc_syscall+0x34/0x44
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&net->nft.commit_mutex);
lock(&table[i].mutex);
lock(&net->nft.commit_mutex);
lock(&table[i].mutex);
Lockdep considers this an ABBA deadlock because the different nfnl subsys
mutexes reside in the same lockdep class, but this is a false positive.
CPU1 table[i] refers to the nftables subsys mutex, whereas CPU1 locks
the ipset subsys mutex.
Yi Che reported a similar lockdep splat, this time between ipset and
ctnetlink subsys mutexes.
Time to place them in distinct classes to avoid these warnings.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
pull/508/merge
parent
9446ab34ac
commit
ab6c41eefd
|
|
@ -46,6 +46,23 @@ static struct {
|
|||
const struct nfnetlink_subsystem __rcu *subsys;
|
||||
} table[NFNL_SUBSYS_COUNT];
|
||||
|
||||
static struct lock_class_key nfnl_lockdep_keys[NFNL_SUBSYS_COUNT];
|
||||
|
||||
static const char *const nfnl_lockdep_names[NFNL_SUBSYS_COUNT] = {
|
||||
[NFNL_SUBSYS_NONE] = "nfnl_subsys_none",
|
||||
[NFNL_SUBSYS_CTNETLINK] = "nfnl_subsys_ctnetlink",
|
||||
[NFNL_SUBSYS_CTNETLINK_EXP] = "nfnl_subsys_ctnetlink_exp",
|
||||
[NFNL_SUBSYS_QUEUE] = "nfnl_subsys_queue",
|
||||
[NFNL_SUBSYS_ULOG] = "nfnl_subsys_ulog",
|
||||
[NFNL_SUBSYS_OSF] = "nfnl_subsys_osf",
|
||||
[NFNL_SUBSYS_IPSET] = "nfnl_subsys_ipset",
|
||||
[NFNL_SUBSYS_ACCT] = "nfnl_subsys_acct",
|
||||
[NFNL_SUBSYS_CTNETLINK_TIMEOUT] = "nfnl_subsys_cttimeout",
|
||||
[NFNL_SUBSYS_CTHELPER] = "nfnl_subsys_cthelper",
|
||||
[NFNL_SUBSYS_NFTABLES] = "nfnl_subsys_nftables",
|
||||
[NFNL_SUBSYS_NFT_COMPAT] = "nfnl_subsys_nftcompat",
|
||||
};
|
||||
|
||||
static const int nfnl_group2type[NFNLGRP_MAX+1] = {
|
||||
[NFNLGRP_CONNTRACK_NEW] = NFNL_SUBSYS_CTNETLINK,
|
||||
[NFNLGRP_CONNTRACK_UPDATE] = NFNL_SUBSYS_CTNETLINK,
|
||||
|
|
@ -632,7 +649,7 @@ static int __init nfnetlink_init(void)
|
|||
BUG_ON(nfnl_group2type[i] == NFNL_SUBSYS_NONE);
|
||||
|
||||
for (i=0; i<NFNL_SUBSYS_COUNT; i++)
|
||||
mutex_init(&table[i].mutex);
|
||||
__mutex_init(&table[i].mutex, nfnl_lockdep_names[i], &nfnl_lockdep_keys[i]);
|
||||
|
||||
return register_pernet_subsys(&nfnetlink_net_ops);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue