Skip to content

Commit 369f61b

Browse files
TaeheeYoodavem330
authored andcommitted
team: fix nested locking lockdep warning
team interface could be nested and it's lock variable could be nested too. But this lock uses static lockdep key and there is no nested locking handling code such as mutex_lock_nested() and so on. so the Lockdep would warn about the circular locking scenario that couldn't happen. In order to fix, this patch makes the team module to use dynamic lock key instead of static key. Test commands: ip link add team0 type team ip link add team1 type team ip link set team0 master team1 ip link set team0 nomaster ip link set team1 master team0 ip link set team1 nomaster Splat that looks like: [ 40.364352] WARNING: possible recursive locking detected [ 40.364964] 5.4.0-rc3+ thesofproject#96 Not tainted [ 40.365405] -------------------------------------------- [ 40.365973] ip/750 is trying to acquire lock: [ 40.366542] ffff888060b34c40 (&team->lock){+.+.}, at: team_set_mac_address+0x151/0x290 [team] [ 40.367689] but task is already holding lock: [ 40.368729] ffff888051201c40 (&team->lock){+.+.}, at: team_del_slave+0x29/0x60 [team] [ 40.370280] other info that might help us debug this: [ 40.371159] Possible unsafe locking scenario: [ 40.371942] CPU0 [ 40.372338] ---- [ 40.372673] lock(&team->lock); [ 40.373115] lock(&team->lock); [ 40.373549] *** DEADLOCK *** [ 40.374432] May be due to missing lock nesting notation [ 40.375338] 2 locks held by ip/750: [ 40.375851] #0: ffffffffabcc42b0 (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x466/0x8a0 [ 40.376927] #1: ffff888051201c40 (&team->lock){+.+.}, at: team_del_slave+0x29/0x60 [team] [ 40.377989] stack backtrace: [ 40.378650] CPU: 0 PID: 750 Comm: ip Not tainted 5.4.0-rc3+ thesofproject#96 [ 40.379368] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 40.380574] Call Trace: [ 40.381208] dump_stack+0x7c/0xbb [ 40.381959] __lock_acquire+0x269d/0x3de0 [ 40.382817] ? register_lock_class+0x14d0/0x14d0 [ 40.383784] ? check_chain_key+0x236/0x5d0 [ 40.384518] lock_acquire+0x164/0x3b0 [ 40.385074] ? team_set_mac_address+0x151/0x290 [team] [ 40.385805] __mutex_lock+0x14d/0x14c0 [ 40.386371] ? team_set_mac_address+0x151/0x290 [team] [ 40.387038] ? team_set_mac_address+0x151/0x290 [team] [ 40.387632] ? mutex_lock_io_nested+0x1380/0x1380 [ 40.388245] ? team_del_slave+0x60/0x60 [team] [ 40.388752] ? rcu_read_lock_sched_held+0x90/0xc0 [ 40.389304] ? rcu_read_lock_bh_held+0xa0/0xa0 [ 40.389819] ? lock_acquire+0x164/0x3b0 [ 40.390285] ? lockdep_rtnl_is_held+0x16/0x20 [ 40.390797] ? team_port_get_rtnl+0x90/0xe0 [team] [ 40.391353] ? __module_text_address+0x13/0x140 [ 40.391886] ? team_set_mac_address+0x151/0x290 [team] [ 40.392547] team_set_mac_address+0x151/0x290 [team] [ 40.393111] dev_set_mac_address+0x1f0/0x3f0 [ ... ] Fixes: 3d249d4 ("net: introduce ethernet teaming device") Signed-off-by: Taehee Yoo <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 089bca2 commit 369f61b

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

drivers/net/team/team.c

+13-3
Original file line numberDiff line numberDiff line change
@@ -1615,7 +1615,6 @@ static int team_init(struct net_device *dev)
16151615
int err;
16161616

16171617
team->dev = dev;
1618-
mutex_init(&team->lock);
16191618
team_set_no_mode(team);
16201619

16211620
team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats);
@@ -1642,6 +1641,9 @@ static int team_init(struct net_device *dev)
16421641
goto err_options_register;
16431642
netif_carrier_off(dev);
16441643

1644+
lockdep_register_key(&team->team_lock_key);
1645+
__mutex_init(&team->lock, "team->team_lock_key", &team->team_lock_key);
1646+
16451647
return 0;
16461648

16471649
err_options_register:
@@ -1671,6 +1673,7 @@ static void team_uninit(struct net_device *dev)
16711673
team_queue_override_fini(team);
16721674
mutex_unlock(&team->lock);
16731675
netdev_change_features(dev);
1676+
lockdep_unregister_key(&team->team_lock_key);
16741677
}
16751678

16761679
static void team_destructor(struct net_device *dev)
@@ -1974,8 +1977,15 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
19741977
err = team_port_del(team, port_dev);
19751978
mutex_unlock(&team->lock);
19761979

1977-
if (!err)
1978-
netdev_change_features(dev);
1980+
if (err)
1981+
return err;
1982+
1983+
if (netif_is_team_master(port_dev)) {
1984+
lockdep_unregister_key(&team->team_lock_key);
1985+
lockdep_register_key(&team->team_lock_key);
1986+
lockdep_set_class(&team->lock, &team->team_lock_key);
1987+
}
1988+
netdev_change_features(dev);
19791989

19801990
return err;
19811991
}

include/linux/if_team.h

+1
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ struct team {
223223
atomic_t count_pending;
224224
struct delayed_work dw;
225225
} mcast_rejoin;
226+
struct lock_class_key team_lock_key;
226227
long mode_priv[TEAM_MODE_PRIV_LONGS];
227228
};
228229

0 commit comments

Comments
 (0)