aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@redhat.com>2014-09-15 11:19:33 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-15 17:19:49 -0400
commit56924c3811ae843527f7a1090ead73a0acf704a4 (patch)
treef161e1d1f9b6d941e4040d7cb3bed59ee93b5439 /drivers/net/bonding
parent437024067ac1fbda7bb3a795e75922f9034672fb (diff)
bonding: consolidate the two rlb_next_rx_slave functions into one
__rlb_next_rx_slave() is a copy of rlb_next_rx_slave() with the difference that it uses rcu primitives to walk the slave list. We don't need the two functions and can make rlb_next_rx_slave() a wrapper for callers which hold RTNL. So add a comment and ASSERT_RTNL() to make sure what is intended. Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_alb.c38
1 files changed, 10 insertions, 28 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 85af961f1317..4efdeb67ab7c 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -334,14 +334,15 @@ out:
334 return RX_HANDLER_ANOTHER; 334 return RX_HANDLER_ANOTHER;
335} 335}
336 336
337static struct slave *rlb_next_rx_slave(struct bonding *bond) 337/* Caller must hold rcu_read_lock() */
338static struct slave *__rlb_next_rx_slave(struct bonding *bond)
338{ 339{
339 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 340 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
340 struct slave *before = NULL, *rx_slave = NULL, *slave; 341 struct slave *before = NULL, *rx_slave = NULL, *slave;
341 struct list_head *iter; 342 struct list_head *iter;
342 bool found = false; 343 bool found = false;
343 344
344 bond_for_each_slave(bond, slave, iter) { 345 bond_for_each_slave_rcu(bond, slave, iter) {
345 if (!bond_slave_can_tx(slave)) 346 if (!bond_slave_can_tx(slave))
346 continue; 347 continue;
347 if (!found) { 348 if (!found) {
@@ -366,35 +367,16 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond)
366 return rx_slave; 367 return rx_slave;
367} 368}
368 369
369/* Caller must hold rcu_read_lock() */ 370/* Caller must hold RTNL, rcu_read_lock is obtained only to silence checkers */
370static struct slave *__rlb_next_rx_slave(struct bonding *bond) 371static struct slave *rlb_next_rx_slave(struct bonding *bond)
371{ 372{
372 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 373 struct slave *rx_slave;
373 struct slave *before = NULL, *rx_slave = NULL, *slave;
374 struct list_head *iter;
375 bool found = false;
376 374
377 bond_for_each_slave_rcu(bond, slave, iter) { 375 ASSERT_RTNL();
378 if (!bond_slave_can_tx(slave))
379 continue;
380 if (!found) {
381 if (!before || before->speed < slave->speed)
382 before = slave;
383 } else {
384 if (!rx_slave || rx_slave->speed < slave->speed)
385 rx_slave = slave;
386 }
387 if (slave == bond_info->rx_slave)
388 found = true;
389 }
390 /* we didn't find anything after the current or we have something
391 * better before and up to the current slave
392 */
393 if (!rx_slave || (before && rx_slave->speed < before->speed))
394 rx_slave = before;
395 376
396 if (rx_slave) 377 rcu_read_lock();
397 bond_info->rx_slave = rx_slave; 378 rx_slave = __rlb_next_rx_slave(bond);
379 rcu_read_unlock();
398 380
399 return rx_slave; 381 return rx_slave;
400} 382}