diff options
author | dingtianhong <dingtianhong@huawei.com> | 2013-12-12 21:19:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-14 01:58:01 -0500 |
commit | 2e52f4fe3655c7a2311070c6713f7feabc75486c (patch) | |
tree | c24f81f012e80b79b60f00653e162692f236fa83 | |
parent | 733ab63935beab905b03a329cdc544e8c171b6b9 (diff) |
bonding: rebuild the lock use for bond_loadbalance_arp_mon()
The bond_loadbalance_arp_mon() use the bond lock to protect the
bond slave list, it is no effect, so I could use RTNL or RCU to
replace it, considering the performance impact, the RCU is more
better here, so the bond lock replace with the RCU.
The bond_select_active_slave() need RTNL and curr_slave_lock
together, but there is no RTNL lock here, so add a rtnl_rtylock.
Suggested-by: Jay Vosburgh <fubar@us.ibm.com>
Suggested-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/bonding/bond_main.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b34634a96710..1781ea620d76 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2411,12 +2411,12 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2411 | struct list_head *iter; | 2411 | struct list_head *iter; |
2412 | int do_failover = 0; | 2412 | int do_failover = 0; |
2413 | 2413 | ||
2414 | read_lock(&bond->lock); | ||
2415 | |||
2416 | if (!bond_has_slaves(bond)) | 2414 | if (!bond_has_slaves(bond)) |
2417 | goto re_arm; | 2415 | goto re_arm; |
2418 | 2416 | ||
2419 | oldcurrent = bond->curr_active_slave; | 2417 | rcu_read_lock(); |
2418 | |||
2419 | oldcurrent = ACCESS_ONCE(bond->curr_active_slave); | ||
2420 | /* see if any of the previous devices are up now (i.e. they have | 2420 | /* see if any of the previous devices are up now (i.e. they have |
2421 | * xmt and rcv traffic). the curr_active_slave does not come into | 2421 | * xmt and rcv traffic). the curr_active_slave does not come into |
2422 | * the picture unless it is null. also, slave->jiffies is not needed | 2422 | * the picture unless it is null. also, slave->jiffies is not needed |
@@ -2425,7 +2425,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2425 | * TODO: what about up/down delay in arp mode? it wasn't here before | 2425 | * TODO: what about up/down delay in arp mode? it wasn't here before |
2426 | * so it can wait | 2426 | * so it can wait |
2427 | */ | 2427 | */ |
2428 | bond_for_each_slave(bond, slave, iter) { | 2428 | bond_for_each_slave_rcu(bond, slave, iter) { |
2429 | unsigned long trans_start = dev_trans_start(slave->dev); | 2429 | unsigned long trans_start = dev_trans_start(slave->dev); |
2430 | 2430 | ||
2431 | if (slave->link != BOND_LINK_UP) { | 2431 | if (slave->link != BOND_LINK_UP) { |
@@ -2487,7 +2487,14 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2487 | bond_arp_send_all(bond, slave); | 2487 | bond_arp_send_all(bond, slave); |
2488 | } | 2488 | } |
2489 | 2489 | ||
2490 | rcu_read_unlock(); | ||
2491 | |||
2490 | if (do_failover) { | 2492 | if (do_failover) { |
2493 | /* the bond_select_active_slave must hold RTNL | ||
2494 | * and curr_slave_lock for write. | ||
2495 | */ | ||
2496 | if (!rtnl_trylock()) | ||
2497 | goto re_arm; | ||
2491 | block_netpoll_tx(); | 2498 | block_netpoll_tx(); |
2492 | write_lock_bh(&bond->curr_slave_lock); | 2499 | write_lock_bh(&bond->curr_slave_lock); |
2493 | 2500 | ||
@@ -2495,14 +2502,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2495 | 2502 | ||
2496 | write_unlock_bh(&bond->curr_slave_lock); | 2503 | write_unlock_bh(&bond->curr_slave_lock); |
2497 | unblock_netpoll_tx(); | 2504 | unblock_netpoll_tx(); |
2505 | rtnl_unlock(); | ||
2498 | } | 2506 | } |
2499 | 2507 | ||
2500 | re_arm: | 2508 | re_arm: |
2501 | if (bond->params.arp_interval) | 2509 | if (bond->params.arp_interval) |
2502 | queue_delayed_work(bond->wq, &bond->arp_work, | 2510 | queue_delayed_work(bond->wq, &bond->arp_work, |
2503 | msecs_to_jiffies(bond->params.arp_interval)); | 2511 | msecs_to_jiffies(bond->params.arp_interval)); |
2504 | |||
2505 | read_unlock(&bond->lock); | ||
2506 | } | 2512 | } |
2507 | 2513 | ||
2508 | /* | 2514 | /* |