|
@@ -383,30 +383,31 @@ out:
|
|
|
static struct slave *rlb_next_rx_slave(struct bonding *bond)
|
|
|
{
|
|
|
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
|
|
|
- struct slave *rx_slave, *slave, *start_at;
|
|
|
- int i = 0;
|
|
|
-
|
|
|
- if (bond_info->next_rx_slave)
|
|
|
- start_at = bond_info->next_rx_slave;
|
|
|
- else
|
|
|
- start_at = bond_first_slave(bond);
|
|
|
-
|
|
|
- rx_slave = NULL;
|
|
|
+ struct slave *before = NULL, *rx_slave = NULL, *slave;
|
|
|
+ struct list_head *iter;
|
|
|
+ bool found = false;
|
|
|
|
|
|
- bond_for_each_slave_from(bond, slave, i, start_at) {
|
|
|
- if (SLAVE_IS_OK(slave)) {
|
|
|
- if (!rx_slave) {
|
|
|
- rx_slave = slave;
|
|
|
- } else if (slave->speed > rx_slave->speed) {
|
|
|
+ bond_for_each_slave(bond, slave, iter) {
|
|
|
+ if (!SLAVE_IS_OK(slave))
|
|
|
+ continue;
|
|
|
+ if (!found) {
|
|
|
+ if (!before || before->speed < slave->speed)
|
|
|
+ before = slave;
|
|
|
+ } else {
|
|
|
+ if (!rx_slave || rx_slave->speed < slave->speed)
|
|
|
rx_slave = slave;
|
|
|
- }
|
|
|
}
|
|
|
+ if (slave == bond_info->rx_slave)
|
|
|
+ found = true;
|
|
|
}
|
|
|
+ /* we didn't find anything after the current or we have something
|
|
|
+ * better before and up to the current slave
|
|
|
+ */
|
|
|
+ if (!rx_slave || (before && rx_slave->speed < before->speed))
|
|
|
+ rx_slave = before;
|
|
|
|
|
|
- if (rx_slave) {
|
|
|
- slave = bond_next_slave(bond, rx_slave);
|
|
|
- bond_info->next_rx_slave = slave;
|
|
|
- }
|
|
|
+ if (rx_slave)
|
|
|
+ bond_info->rx_slave = rx_slave;
|
|
|
|
|
|
return rx_slave;
|
|
|
}
|
|
@@ -1611,7 +1612,7 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
|
|
|
tlb_clear_slave(bond, slave, 0);
|
|
|
|
|
|
if (bond->alb_info.rlb_enabled) {
|
|
|
- bond->alb_info.next_rx_slave = NULL;
|
|
|
+ bond->alb_info.rx_slave = NULL;
|
|
|
rlb_clear_slave(bond, slave);
|
|
|
}
|
|
|
}
|