diff options
| author | Nikolay Aleksandrov <nikolay@redhat.com> | 2014-09-15 11:19:33 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-09-15 17:19:49 -0400 |
| commit | 56924c3811ae843527f7a1090ead73a0acf704a4 (patch) | |
| tree | f161e1d1f9b6d941e4040d7cb3bed59ee93b5439 /drivers/net/bonding | |
| parent | 437024067ac1fbda7bb3a795e75922f9034672fb (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.c | 38 |
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 | ||
| 337 | static struct slave *rlb_next_rx_slave(struct bonding *bond) | 337 | /* Caller must hold rcu_read_lock() */ |
| 338 | static 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 */ |
| 370 | static struct slave *__rlb_next_rx_slave(struct bonding *bond) | 371 | static 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 | } |
