aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_alb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r--drivers/net/bonding/bond_alb.c51
1 files changed, 7 insertions, 44 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 615f3bebd019..d2eadab787c5 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -177,7 +177,6 @@ static int tlb_initialize(struct bonding *bond)
177static void tlb_deinitialize(struct bonding *bond) 177static void tlb_deinitialize(struct bonding *bond)
178{ 178{
179 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 179 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
180 struct tlb_up_slave *arr;
181 180
182 spin_lock_bh(&bond->mode_lock); 181 spin_lock_bh(&bond->mode_lock);
183 182
@@ -185,10 +184,6 @@ static void tlb_deinitialize(struct bonding *bond)
185 bond_info->tx_hashtbl = NULL; 184 bond_info->tx_hashtbl = NULL;
186 185
187 spin_unlock_bh(&bond->mode_lock); 186 spin_unlock_bh(&bond->mode_lock);
188
189 arr = rtnl_dereference(bond_info->slave_arr);
190 if (arr)
191 kfree_rcu(arr, rcu);
192} 187}
193 188
194static long long compute_gap(struct slave *slave) 189static long long compute_gap(struct slave *slave)
@@ -1336,39 +1331,9 @@ out:
1336 return NETDEV_TX_OK; 1331 return NETDEV_TX_OK;
1337} 1332}
1338 1333
1339static int bond_tlb_update_slave_arr(struct bonding *bond,
1340 struct slave *skipslave)
1341{
1342 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
1343 struct slave *tx_slave;
1344 struct list_head *iter;
1345 struct tlb_up_slave *new_arr, *old_arr;
1346
1347 new_arr = kzalloc(offsetof(struct tlb_up_slave, arr[bond->slave_cnt]),
1348 GFP_ATOMIC);
1349 if (!new_arr)
1350 return -ENOMEM;
1351
1352 bond_for_each_slave(bond, tx_slave, iter) {
1353 if (!bond_slave_can_tx(tx_slave))
1354 continue;
1355 if (skipslave == tx_slave)
1356 continue;
1357 new_arr->arr[new_arr->count++] = tx_slave;
1358 }
1359
1360 old_arr = rtnl_dereference(bond_info->slave_arr);
1361 rcu_assign_pointer(bond_info->slave_arr, new_arr);
1362 if (old_arr)
1363 kfree_rcu(old_arr, rcu);
1364
1365 return 0;
1366}
1367
1368int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev) 1334int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
1369{ 1335{
1370 struct bonding *bond = netdev_priv(bond_dev); 1336 struct bonding *bond = netdev_priv(bond_dev);
1371 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
1372 struct ethhdr *eth_data; 1337 struct ethhdr *eth_data;
1373 struct slave *tx_slave = NULL; 1338 struct slave *tx_slave = NULL;
1374 u32 hash_index; 1339 u32 hash_index;
@@ -1389,12 +1354,14 @@ int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
1389 hash_index & 0xFF, 1354 hash_index & 0xFF,
1390 skb->len); 1355 skb->len);
1391 } else { 1356 } else {
1392 struct tlb_up_slave *slaves; 1357 struct bond_up_slave *slaves;
1358 unsigned int count;
1393 1359
1394 slaves = rcu_dereference(bond_info->slave_arr); 1360 slaves = rcu_dereference(bond->slave_arr);
1395 if (slaves && slaves->count) 1361 count = slaves ? ACCESS_ONCE(slaves->count) : 0;
1362 if (likely(count))
1396 tx_slave = slaves->arr[hash_index % 1363 tx_slave = slaves->arr[hash_index %
1397 slaves->count]; 1364 count];
1398 } 1365 }
1399 break; 1366 break;
1400 } 1367 }
@@ -1641,10 +1608,6 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
1641 rlb_clear_slave(bond, slave); 1608 rlb_clear_slave(bond, slave);
1642 } 1609 }
1643 1610
1644 if (bond_is_nondyn_tlb(bond))
1645 if (bond_tlb_update_slave_arr(bond, slave))
1646 pr_err("Failed to build slave-array for TLB mode.\n");
1647
1648} 1611}
1649 1612
1650void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link) 1613void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link)
@@ -1669,7 +1632,7 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
1669 } 1632 }
1670 1633
1671 if (bond_is_nondyn_tlb(bond)) { 1634 if (bond_is_nondyn_tlb(bond)) {
1672 if (bond_tlb_update_slave_arr(bond, NULL)) 1635 if (bond_update_slave_arr(bond, NULL))
1673 pr_err("Failed to build slave-array for TLB mode.\n"); 1636 pr_err("Failed to build slave-array for TLB mode.\n");
1674 } 1637 }
1675} 1638}