Skip to content

Commit 089bca2

Browse files
TaeheeYoodavem330
authored andcommitted
bonding: use dynamic lockdep key instead of subclass
All bonding device has same lockdep key and subclass is initialized with nest_level. But actual nest_level value can be changed when a lower device is attached. And at this moment, the subclass should be updated but it seems to be unsafe. So this patch makes bonding use dynamic lockdep key instead of the subclass. Test commands: ip link add bond0 type bond for i in {1..5} do let A=$i-1 ip link add bond$i type bond ip link set bond$i master bond$A done ip link set bond5 master bond0 Splat looks like: [ 307.992912] WARNING: possible recursive locking detected [ 307.993656] 5.4.0-rc3+ #96 Tainted: G W [ 307.994367] -------------------------------------------- [ 307.995092] ip/761 is trying to acquire lock: [ 307.995710] ffff8880513aac60 (&(&bond->stats_lock)->rlock#2/2){+.+.}, at: bond_get_stats+0xb8/0x500 [bonding] [ 307.997045] but task is already holding lock: [ 307.997923] ffff88805fcbac60 (&(&bond->stats_lock)->rlock#2/2){+.+.}, at: bond_get_stats+0xb8/0x500 [bonding] [ 307.999215] other info that might help us debug this: [ 308.000251] Possible unsafe locking scenario: [ 308.001137] CPU0 [ 308.001533] ---- [ 308.001915] lock(&(&bond->stats_lock)->rlock#2/2); [ 308.002609] lock(&(&bond->stats_lock)->rlock#2/2); [ 308.003302] *** DEADLOCK *** [ 308.004310] May be due to missing lock nesting notation [ 308.005319] 3 locks held by ip/761: [ 308.005830] #0: ffffffff9fcc42b0 (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x466/0x8a0 [ 308.006894] #1: ffff88805fcbac60 (&(&bond->stats_lock)->rlock#2/2){+.+.}, at: bond_get_stats+0xb8/0x500 [bonding] [ 308.008243] #2: ffffffff9f9219c0 (rcu_read_lock){....}, at: bond_get_stats+0x9f/0x500 [bonding] [ 308.009422] stack backtrace: [ 308.010124] CPU: 0 PID: 761 Comm: ip Tainted: G W 5.4.0-rc3+ #96 [ 308.011097] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 308.012179] Call Trace: [ 308.012601] dump_stack+0x7c/0xbb [ 308.013089] __lock_acquire+0x269d/0x3de0 [ 308.013669] ? register_lock_class+0x14d0/0x14d0 [ 308.014318] lock_acquire+0x164/0x3b0 [ 308.014858] ? bond_get_stats+0xb8/0x500 [bonding] [ 308.015520] _raw_spin_lock_nested+0x2e/0x60 [ 308.016129] ? bond_get_stats+0xb8/0x500 [bonding] [ 308.017215] bond_get_stats+0xb8/0x500 [bonding] [ 308.018454] ? bond_arp_rcv+0xf10/0xf10 [bonding] [ 308.019710] ? rcu_read_lock_held+0x90/0xa0 [ 308.020605] ? rcu_read_lock_sched_held+0xc0/0xc0 [ 308.021286] ? bond_get_stats+0x9f/0x500 [bonding] [ 308.021953] dev_get_stats+0x1ec/0x270 [ 308.022508] bond_get_stats+0x1d1/0x500 [bonding] Fixes: d3fff6c ("net: add netdev_lockdep_set_classes() helper") Signed-off-by: Taehee Yoo <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 65de65d commit 089bca2

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

drivers/net/bonding/bond_main.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -3459,7 +3459,7 @@ static void bond_get_stats(struct net_device *bond_dev,
34593459
struct list_head *iter;
34603460
struct slave *slave;
34613461

3462-
spin_lock_nested(&bond->stats_lock, bond_get_nest_level(bond_dev));
3462+
spin_lock(&bond->stats_lock);
34633463
memcpy(stats, &bond->bond_stats, sizeof(*stats));
34643464

34653465
rcu_read_lock();
@@ -4297,8 +4297,6 @@ void bond_setup(struct net_device *bond_dev)
42974297
{
42984298
struct bonding *bond = netdev_priv(bond_dev);
42994299

4300-
spin_lock_init(&bond->mode_lock);
4301-
spin_lock_init(&bond->stats_lock);
43024300
bond->params = bonding_defaults;
43034301

43044302
/* Initialize pointers */
@@ -4367,6 +4365,7 @@ static void bond_uninit(struct net_device *bond_dev)
43674365

43684366
list_del(&bond->bond_list);
43694367

4368+
lockdep_unregister_key(&bond->stats_lock_key);
43704369
bond_debug_unregister(bond);
43714370
}
43724371

@@ -4772,6 +4771,11 @@ static int bond_init(struct net_device *bond_dev)
47724771

47734772
bond->nest_level = SINGLE_DEPTH_NESTING;
47744773

4774+
spin_lock_init(&bond->mode_lock);
4775+
spin_lock_init(&bond->stats_lock);
4776+
lockdep_register_key(&bond->stats_lock_key);
4777+
lockdep_set_class(&bond->stats_lock, &bond->stats_lock_key);
4778+
47754779
list_add_tail(&bond->bond_list, &bn->dev_list);
47764780

47774781
bond_prepare_sysfs_group(bond);

include/net/bonding.h

+1
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ struct bonding {
239239
struct dentry *debug_dir;
240240
#endif /* CONFIG_DEBUG_FS */
241241
struct rtnl_link_stats64 bond_stats;
242+
struct lock_class_key stats_lock_key;
242243
};
243244

244245
#define bond_slave_get_rcu(dev) \

0 commit comments

Comments
 (0)