History

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]

Taehee Yoo committed 7 years ago

Commit 089bca21 parent 65de65d2 files · +8 −3Browse files

Unified · Split

2 files
  1. drivers/net/bonding/bond_main.c +7 −3
  2. include/net/bonding.h +1 −0
drivers/net/bonding/bond_main.c+7−3
@@ -3459,7 +3459,7 @@ static void bond_get_stats(struct net_device *bond_dev, · 3458 unmodified lines
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) · 831 unmodified lines
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) · 62 unmodified lines
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) · 399 unmodified lines
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−0
@@ -239,6 +239,7 @@ struct bonding { · 238 unmodified lines
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) \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t