aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVeaceslav Falico <vfalico@redhat.com>2013-09-25 03:20:17 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-26 16:02:05 -0400
commit6475ae4ceea2f430db1daabf6460a9f36bc97438 (patch)
treed62241c4ded183e28bc77b25a22c921f7cf402be
parentc33d78874eeb6c28909158719043fa2a5fd18f0a (diff)
bonding: rework rlb_next_rx_slave() to use bond_for_each_slave()
Currently, we're using bond_for_each_slave_from(), which is really hard to implement under RCU and/or neighbour list. Remove it and use bond_for_each_slave() instead, taking care of the last used slave. Also, rename next_rx_slave to rx_slave and store the current (last) rx_slave. CC: Jay Vosburgh <fubar@us.ibm.com> CC: Andy Gospodarek <andy@greyhouse.net> Signed-off-by: Veaceslav Falico <vfalico@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_alb.c41
-rw-r--r--drivers/net/bonding/bond_alb.h4
2 files changed, 22 insertions, 23 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index f4929cee21a6..c5b85ad5554d 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -383,30 +383,31 @@ out:
383static struct slave *rlb_next_rx_slave(struct bonding *bond) 383static struct slave *rlb_next_rx_slave(struct bonding *bond)
384{ 384{
385 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 385 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
386 struct slave *rx_slave, *slave, *start_at; 386 struct slave *before = NULL, *rx_slave = NULL, *slave;
387 int i = 0; 387 struct list_head *iter;
388 388 bool found = false;
389 if (bond_info->next_rx_slave)
390 start_at = bond_info->next_rx_slave;
391 else
392 start_at = bond_first_slave(bond);
393
394 rx_slave = NULL;
395 389
396 bond_for_each_slave_from(bond, slave, i, start_at) { 390 bond_for_each_slave(bond, slave, iter) {
397 if (SLAVE_IS_OK(slave)) { 391 if (!SLAVE_IS_OK(slave))
398 if (!rx_slave) { 392 continue;
399 rx_slave = slave; 393 if (!found) {
400 } else if (slave->speed > rx_slave->speed) { 394 if (!before || before->speed < slave->speed)
395 before = slave;
396 } else {
397 if (!rx_slave || rx_slave->speed < slave->speed)
401 rx_slave = slave; 398 rx_slave = slave;
402 }
403 } 399 }
400 if (slave == bond_info->rx_slave)
401 found = true;
404 } 402 }
403 /* we didn't find anything after the current or we have something
404 * better before and up to the current slave
405 */
406 if (!rx_slave || (before && rx_slave->speed < before->speed))
407 rx_slave = before;
405 408
406 if (rx_slave) { 409 if (rx_slave)
407 slave = bond_next_slave(bond, rx_slave); 410 bond_info->rx_slave = rx_slave;
408 bond_info->next_rx_slave = slave;
409 }
410 411
411 return rx_slave; 412 return rx_slave;
412} 413}
@@ -1611,7 +1612,7 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
1611 tlb_clear_slave(bond, slave, 0); 1612 tlb_clear_slave(bond, slave, 0);
1612 1613
1613 if (bond->alb_info.rlb_enabled) { 1614 if (bond->alb_info.rlb_enabled) {
1614 bond->alb_info.next_rx_slave = NULL; 1615 bond->alb_info.rx_slave = NULL;
1615 rlb_clear_slave(bond, slave); 1616 rlb_clear_slave(bond, slave);
1616 } 1617 }
1617} 1618}
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index c5eff5dafdfe..4226044efd08 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -154,9 +154,7 @@ struct alb_bond_info {
154 u8 rx_ntt; /* flag - need to transmit 154 u8 rx_ntt; /* flag - need to transmit
155 * to all rx clients 155 * to all rx clients
156 */ 156 */
157 struct slave *next_rx_slave;/* next slave to be assigned 157 struct slave *rx_slave;/* last slave to xmit from */
158 * to a new rx client for
159 */
160 u8 primary_is_promisc; /* boolean */ 158 u8 primary_is_promisc; /* boolean */
161 u32 rlb_promisc_timeout_counter;/* counts primary 159 u32 rlb_promisc_timeout_counter;/* counts primary
162 * promiscuity time 160 * promiscuity time