mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
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>
This commit is contained in:
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
Block a user