diff options
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 51 |
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) | |||
177 | static void tlb_deinitialize(struct bonding *bond) | 177 | static 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 | ||
194 | static long long compute_gap(struct slave *slave) | 189 | static 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 | ||
1339 | static 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 | |||
1368 | int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | 1334 | int 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 | ||
1650 | void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link) | 1613 | void 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 | } |