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
3459 struct list_head *iter;3459 struct list_head *iter;
3460 struct slave *slave;3460 struct slave *slave;
3461 3461
3462 spin_lock_nested(&bond->stats_lock, bond_get_nest_level(bond_dev));3462 spin_lock(&bond->stats_lock);
3463 memcpy(stats, &bond->bond_stats, sizeof(*stats));3463 memcpy(stats, &bond->bond_stats, sizeof(*stats));
3464 3464
3465 rcu_read_lock();3465 rcu_read_lock();
@@ -4297,8 +4297,6 @@ void bond_setup(struct net_device *bond_dev) · 831 unmodified lines
4297{4297{
4298 struct bonding *bond = netdev_priv(bond_dev);4298 struct bonding *bond = netdev_priv(bond_dev);
4299 4299
4300 spin_lock_init(&bond->mode_lock);
4301 spin_lock_init(&bond->stats_lock);
4302 bond->params = bonding_defaults;4300 bond->params = bonding_defaults;
4303 4301
4304 /* Initialize pointers */4302 /* Initialize pointers */
@@ -4367,6 +4365,7 @@ static void bond_uninit(struct net_device *bond_dev) · 62 unmodified lines
4367 4365
4368 list_del(&bond->bond_list);4366 list_del(&bond->bond_list);
4369 4367
4368 lockdep_unregister_key(&bond->stats_lock_key);
4370 bond_debug_unregister(bond);4369 bond_debug_unregister(bond);
4371}4370}
4372 4371
@@ -4772,6 +4771,11 @@ static int bond_init(struct net_device *bond_dev) · 399 unmodified lines
4772 4771
4773 bond->nest_level = SINGLE_DEPTH_NESTING;4772 bond->nest_level = SINGLE_DEPTH_NESTING;
4774 4773
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
4775 list_add_tail(&bond->bond_list, &bn->dev_list);4779 list_add_tail(&bond->bond_list, &bn->dev_list);
4776 4780
4777 bond_prepare_sysfs_group(bond);4781 bond_prepare_sysfs_group(bond);
include/net/bonding.h+1−0
@@ -239,6 +239,7 @@ struct bonding { · 238 unmodified lines
239 struct dentry *debug_dir;239 struct dentry *debug_dir;
240#endif /* CONFIG_DEBUG_FS */240#endif /* CONFIG_DEBUG_FS */
241 struct rtnl_link_stats64 bond_stats;241 struct rtnl_link_stats64 bond_stats;
242 struct lock_class_key stats_lock_key;
242};243};
243 244
244#define bond_slave_get_rcu(dev) \245#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