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]
Unified · Split
| @@ -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); |
| @@ -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) \ |