bonding: Convert more locks to _bh, acquire rtnl, for new locking

Convert more lock acquisitions to _bh flavor to avoid deadlock
with workqueue activity and add acquisition of RTNL in appropriate places.
Affects ALB mode, as well as core bonding functions and sysfs.

Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by Jay Vosburgh and committed by Jeff Garzik 6603a6f2 059fe7a5

+29 -23
+8 -8
drivers/net/bonding/bond_alb.c
··· 128 128 129 129 static inline void _lock_tx_hashtbl(struct bonding *bond) 130 130 { 131 - spin_lock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); 131 + spin_lock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); 132 132 } 133 133 134 134 static inline void _unlock_tx_hashtbl(struct bonding *bond) 135 135 { 136 - spin_unlock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); 136 + spin_unlock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); 137 137 } 138 138 139 139 /* Caller must hold tx_hashtbl lock */ ··· 305 305 /*********************** rlb specific functions ***************************/ 306 306 static inline void _lock_rx_hashtbl(struct bonding *bond) 307 307 { 308 - spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); 308 + spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); 309 309 } 310 310 311 311 static inline void _unlock_rx_hashtbl(struct bonding *bond) 312 312 { 313 - spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); 313 + spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); 314 314 } 315 315 316 316 /* when an ARP REPLY is received from a client update its info ··· 472 472 473 473 _unlock_rx_hashtbl(bond); 474 474 475 - write_lock(&bond->curr_slave_lock); 475 + write_lock_bh(&bond->curr_slave_lock); 476 476 477 477 if (slave != bond->curr_active_slave) { 478 478 rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr); 479 479 } 480 480 481 - write_unlock(&bond->curr_slave_lock); 481 + write_unlock_bh(&bond->curr_slave_lock); 482 482 } 483 483 484 484 static void rlb_update_client(struct rlb_client_info *client_info) ··· 1519 1519 /* caller must hold the bond lock for write since the mac addresses 1520 1520 * are compared and may be swapped. 1521 1521 */ 1522 - write_lock_bh(&bond->lock); 1522 + read_lock(&bond->lock); 1523 1523 1524 1524 res = alb_handle_addr_collision_on_attach(bond, slave); 1525 1525 1526 - write_unlock_bh(&bond->lock); 1526 + read_unlock(&bond->lock); 1527 1527 1528 1528 if (res) { 1529 1529 return res;
+10 -10
drivers/net/bonding/bond_main.c
··· 1846 1846 */ 1847 1847 void bond_destroy(struct bonding *bond) 1848 1848 { 1849 + unregister_netdevice(bond->dev); 1849 1850 bond_deinit(bond->dev); 1850 1851 bond_destroy_sysfs_entry(bond); 1851 - unregister_netdevice(bond->dev); 1852 1852 } 1853 1853 1854 1854 /* ··· 2057 2057 info->bond_mode = bond->params.mode; 2058 2058 info->miimon = bond->params.miimon; 2059 2059 2060 - read_lock_bh(&bond->lock); 2060 + read_lock(&bond->lock); 2061 2061 info->num_slaves = bond->slave_cnt; 2062 - read_unlock_bh(&bond->lock); 2062 + read_unlock(&bond->lock); 2063 2063 2064 2064 return 0; 2065 2065 } ··· 2074 2074 return -ENODEV; 2075 2075 } 2076 2076 2077 - read_lock_bh(&bond->lock); 2077 + read_lock(&bond->lock); 2078 2078 2079 2079 bond_for_each_slave(bond, slave, i) { 2080 2080 if (i == (int)info->slave_id) { ··· 2083 2083 } 2084 2084 } 2085 2085 2086 - read_unlock_bh(&bond->lock); 2086 + read_unlock(&bond->lock); 2087 2087 2088 2088 if (found) { 2089 2089 strcpy(info->slave_name, slave->dev->name); ··· 3078 3078 3079 3079 /* make sure the bond won't be taken away */ 3080 3080 read_lock(&dev_base_lock); 3081 - read_lock_bh(&bond->lock); 3081 + read_lock(&bond->lock); 3082 3082 3083 3083 if (*pos == 0) { 3084 3084 return SEQ_START_TOKEN; ··· 3112 3112 { 3113 3113 struct bonding *bond = seq->private; 3114 3114 3115 - read_unlock_bh(&bond->lock); 3115 + read_unlock(&bond->lock); 3116 3116 read_unlock(&dev_base_lock); 3117 3117 } 3118 3118 ··· 3821 3821 if (mii->reg_num == 1) { 3822 3822 struct bonding *bond = bond_dev->priv; 3823 3823 mii->val_out = 0; 3824 - read_lock_bh(&bond->lock); 3824 + read_lock(&bond->lock); 3825 3825 read_lock(&bond->curr_slave_lock); 3826 3826 if (netif_carrier_ok(bond->dev)) { 3827 3827 mii->val_out = BMSR_LSTATUS; 3828 3828 } 3829 3829 read_unlock(&bond->curr_slave_lock); 3830 - read_unlock_bh(&bond->lock); 3830 + read_unlock(&bond->lock); 3831 3831 } 3832 3832 3833 3833 return 0; ··· 4473 4473 bond_mc_list_destroy(bond); 4474 4474 /* Release the bonded slaves */ 4475 4475 bond_release_all(bond_dev); 4476 - bond_deinit(bond_dev); 4477 4476 unregister_netdevice(bond_dev); 4477 + bond_deinit(bond_dev); 4478 4478 } 4479 4479 4480 4480 #ifdef CONFIG_PROC_FS
+11 -5
drivers/net/bonding/bond_sysfs.c
··· 229 229 int i, res = 0; 230 230 struct bonding *bond = to_bond(d); 231 231 232 - read_lock_bh(&bond->lock); 232 + read_lock(&bond->lock); 233 233 bond_for_each_slave(bond, slave, i) { 234 234 if (res > (PAGE_SIZE - IFNAMSIZ)) { 235 235 /* not enough space for another interface name */ ··· 240 240 } 241 241 res += sprintf(buf + res, "%s ", slave->dev->name); 242 242 } 243 - read_unlock_bh(&bond->lock); 243 + read_unlock(&bond->lock); 244 244 res += sprintf(buf + res, "\n"); 245 245 res++; 246 246 return res; ··· 282 282 283 283 /* Got a slave name in ifname. Is it already in the list? */ 284 284 found = 0; 285 - read_lock_bh(&bond->lock); 285 + read_lock(&bond->lock); 286 286 bond_for_each_slave(bond, slave, i) 287 287 if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { 288 288 printk(KERN_ERR DRV_NAME 289 289 ": %s: Interface %s is already enslaved!\n", 290 290 bond->dev->name, ifname); 291 291 ret = -EPERM; 292 - read_unlock_bh(&bond->lock); 292 + read_unlock(&bond->lock); 293 293 goto out; 294 294 } 295 295 296 - read_unlock_bh(&bond->lock); 296 + read_unlock(&bond->lock); 297 297 printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n", 298 298 bond->dev->name, ifname); 299 299 dev = dev_get_by_name(&init_net, ifname); ··· 1133 1133 } 1134 1134 out: 1135 1135 write_unlock_bh(&bond->lock); 1136 + 1137 + rtnl_unlock(); 1138 + 1136 1139 return count; 1137 1140 } 1138 1141 static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary); ··· 1193 1190 struct bonding *bond = to_bond(d); 1194 1191 int count; 1195 1192 1193 + rtnl_lock(); 1196 1194 1197 1195 read_lock(&bond->curr_slave_lock); 1198 1196 curr = bond->curr_active_slave; ··· 1273 1269 } 1274 1270 out: 1275 1271 write_unlock_bh(&bond->lock); 1272 + rtnl_unlock(); 1273 + 1276 1274 return count; 1277 1275 1278 1276 }