diff options
-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 | /* |