diff options
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 8 | ||||
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 16 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 96 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 1 |
4 files changed, 61 insertions, 60 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index b33c099d65a4..0ae0d7c54ccf 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -2110,9 +2110,6 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2110 | 2110 | ||
2111 | read_lock(&bond->lock); | 2111 | read_lock(&bond->lock); |
2112 | 2112 | ||
2113 | if (bond->kill_timers) | ||
2114 | goto out; | ||
2115 | |||
2116 | //check if there are any slaves | 2113 | //check if there are any slaves |
2117 | if (bond->slave_cnt == 0) | 2114 | if (bond->slave_cnt == 0) |
2118 | goto re_arm; | 2115 | goto re_arm; |
@@ -2161,9 +2158,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2161 | } | 2158 | } |
2162 | 2159 | ||
2163 | re_arm: | 2160 | re_arm: |
2164 | if (!bond->kill_timers) | 2161 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); |
2165 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); | 2162 | |
2166 | out: | ||
2167 | read_unlock(&bond->lock); | 2163 | read_unlock(&bond->lock); |
2168 | } | 2164 | } |
2169 | 2165 | ||
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index d4fbd2e62616..106b88a04738 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -1343,10 +1343,6 @@ void bond_alb_monitor(struct work_struct *work) | |||
1343 | 1343 | ||
1344 | read_lock(&bond->lock); | 1344 | read_lock(&bond->lock); |
1345 | 1345 | ||
1346 | if (bond->kill_timers) { | ||
1347 | goto out; | ||
1348 | } | ||
1349 | |||
1350 | if (bond->slave_cnt == 0) { | 1346 | if (bond->slave_cnt == 0) { |
1351 | bond_info->tx_rebalance_counter = 0; | 1347 | bond_info->tx_rebalance_counter = 0; |
1352 | bond_info->lp_counter = 0; | 1348 | bond_info->lp_counter = 0; |
@@ -1401,10 +1397,13 @@ void bond_alb_monitor(struct work_struct *work) | |||
1401 | 1397 | ||
1402 | /* | 1398 | /* |
1403 | * dev_set_promiscuity requires rtnl and | 1399 | * dev_set_promiscuity requires rtnl and |
1404 | * nothing else. | 1400 | * nothing else. Avoid race with bond_close. |
1405 | */ | 1401 | */ |
1406 | read_unlock(&bond->lock); | 1402 | read_unlock(&bond->lock); |
1407 | rtnl_lock(); | 1403 | if (!rtnl_trylock()) { |
1404 | read_lock(&bond->lock); | ||
1405 | goto re_arm; | ||
1406 | } | ||
1408 | 1407 | ||
1409 | bond_info->rlb_promisc_timeout_counter = 0; | 1408 | bond_info->rlb_promisc_timeout_counter = 0; |
1410 | 1409 | ||
@@ -1440,9 +1439,8 @@ void bond_alb_monitor(struct work_struct *work) | |||
1440 | } | 1439 | } |
1441 | 1440 | ||
1442 | re_arm: | 1441 | re_arm: |
1443 | if (!bond->kill_timers) | 1442 | queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks); |
1444 | queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks); | 1443 | |
1445 | out: | ||
1446 | read_unlock(&bond->lock); | 1444 | read_unlock(&bond->lock); |
1447 | } | 1445 | } |
1448 | 1446 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c5944f1a4f9d..c34cc1e7c6f6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -773,9 +773,6 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) | |||
773 | 773 | ||
774 | read_lock(&bond->lock); | 774 | read_lock(&bond->lock); |
775 | 775 | ||
776 | if (bond->kill_timers) | ||
777 | goto out; | ||
778 | |||
779 | /* rejoin all groups on bond device */ | 776 | /* rejoin all groups on bond device */ |
780 | __bond_resend_igmp_join_requests(bond->dev); | 777 | __bond_resend_igmp_join_requests(bond->dev); |
781 | 778 | ||
@@ -789,9 +786,9 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) | |||
789 | __bond_resend_igmp_join_requests(vlan_dev); | 786 | __bond_resend_igmp_join_requests(vlan_dev); |
790 | } | 787 | } |
791 | 788 | ||
792 | if ((--bond->igmp_retrans > 0) && !bond->kill_timers) | 789 | if (--bond->igmp_retrans > 0) |
793 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); | 790 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); |
794 | out: | 791 | |
795 | read_unlock(&bond->lock); | 792 | read_unlock(&bond->lock); |
796 | } | 793 | } |
797 | 794 | ||
@@ -2517,10 +2514,11 @@ void bond_mii_monitor(struct work_struct *work) | |||
2517 | struct bonding *bond = container_of(work, struct bonding, | 2514 | struct bonding *bond = container_of(work, struct bonding, |
2518 | mii_work.work); | 2515 | mii_work.work); |
2519 | bool should_notify_peers = false; | 2516 | bool should_notify_peers = false; |
2517 | unsigned long delay; | ||
2520 | 2518 | ||
2521 | read_lock(&bond->lock); | 2519 | read_lock(&bond->lock); |
2522 | if (bond->kill_timers) | 2520 | |
2523 | goto out; | 2521 | delay = msecs_to_jiffies(bond->params.miimon); |
2524 | 2522 | ||
2525 | if (bond->slave_cnt == 0) | 2523 | if (bond->slave_cnt == 0) |
2526 | goto re_arm; | 2524 | goto re_arm; |
@@ -2529,7 +2527,15 @@ void bond_mii_monitor(struct work_struct *work) | |||
2529 | 2527 | ||
2530 | if (bond_miimon_inspect(bond)) { | 2528 | if (bond_miimon_inspect(bond)) { |
2531 | read_unlock(&bond->lock); | 2529 | read_unlock(&bond->lock); |
2532 | rtnl_lock(); | 2530 | |
2531 | /* Race avoidance with bond_close cancel of workqueue */ | ||
2532 | if (!rtnl_trylock()) { | ||
2533 | read_lock(&bond->lock); | ||
2534 | delay = 1; | ||
2535 | should_notify_peers = false; | ||
2536 | goto re_arm; | ||
2537 | } | ||
2538 | |||
2533 | read_lock(&bond->lock); | 2539 | read_lock(&bond->lock); |
2534 | 2540 | ||
2535 | bond_miimon_commit(bond); | 2541 | bond_miimon_commit(bond); |
@@ -2540,14 +2546,18 @@ void bond_mii_monitor(struct work_struct *work) | |||
2540 | } | 2546 | } |
2541 | 2547 | ||
2542 | re_arm: | 2548 | re_arm: |
2543 | if (bond->params.miimon && !bond->kill_timers) | 2549 | if (bond->params.miimon) |
2544 | queue_delayed_work(bond->wq, &bond->mii_work, | 2550 | queue_delayed_work(bond->wq, &bond->mii_work, delay); |
2545 | msecs_to_jiffies(bond->params.miimon)); | 2551 | |
2546 | out: | ||
2547 | read_unlock(&bond->lock); | 2552 | read_unlock(&bond->lock); |
2548 | 2553 | ||
2549 | if (should_notify_peers) { | 2554 | if (should_notify_peers) { |
2550 | rtnl_lock(); | 2555 | if (!rtnl_trylock()) { |
2556 | read_lock(&bond->lock); | ||
2557 | bond->send_peer_notif++; | ||
2558 | read_unlock(&bond->lock); | ||
2559 | return; | ||
2560 | } | ||
2551 | netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS); | 2561 | netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS); |
2552 | rtnl_unlock(); | 2562 | rtnl_unlock(); |
2553 | } | 2563 | } |
@@ -2789,9 +2799,6 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2789 | 2799 | ||
2790 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); | 2800 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); |
2791 | 2801 | ||
2792 | if (bond->kill_timers) | ||
2793 | goto out; | ||
2794 | |||
2795 | if (bond->slave_cnt == 0) | 2802 | if (bond->slave_cnt == 0) |
2796 | goto re_arm; | 2803 | goto re_arm; |
2797 | 2804 | ||
@@ -2888,9 +2895,9 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2888 | } | 2895 | } |
2889 | 2896 | ||
2890 | re_arm: | 2897 | re_arm: |
2891 | if (bond->params.arp_interval && !bond->kill_timers) | 2898 | if (bond->params.arp_interval) |
2892 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); | 2899 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
2893 | out: | 2900 | |
2894 | read_unlock(&bond->lock); | 2901 | read_unlock(&bond->lock); |
2895 | } | 2902 | } |
2896 | 2903 | ||
@@ -3131,9 +3138,6 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
3131 | 3138 | ||
3132 | read_lock(&bond->lock); | 3139 | read_lock(&bond->lock); |
3133 | 3140 | ||
3134 | if (bond->kill_timers) | ||
3135 | goto out; | ||
3136 | |||
3137 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); | 3141 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); |
3138 | 3142 | ||
3139 | if (bond->slave_cnt == 0) | 3143 | if (bond->slave_cnt == 0) |
@@ -3143,7 +3147,15 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
3143 | 3147 | ||
3144 | if (bond_ab_arp_inspect(bond, delta_in_ticks)) { | 3148 | if (bond_ab_arp_inspect(bond, delta_in_ticks)) { |
3145 | read_unlock(&bond->lock); | 3149 | read_unlock(&bond->lock); |
3146 | rtnl_lock(); | 3150 | |
3151 | /* Race avoidance with bond_close flush of workqueue */ | ||
3152 | if (!rtnl_trylock()) { | ||
3153 | read_lock(&bond->lock); | ||
3154 | delta_in_ticks = 1; | ||
3155 | should_notify_peers = false; | ||
3156 | goto re_arm; | ||
3157 | } | ||
3158 | |||
3147 | read_lock(&bond->lock); | 3159 | read_lock(&bond->lock); |
3148 | 3160 | ||
3149 | bond_ab_arp_commit(bond, delta_in_ticks); | 3161 | bond_ab_arp_commit(bond, delta_in_ticks); |
@@ -3156,13 +3168,18 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
3156 | bond_ab_arp_probe(bond); | 3168 | bond_ab_arp_probe(bond); |
3157 | 3169 | ||
3158 | re_arm: | 3170 | re_arm: |
3159 | if (bond->params.arp_interval && !bond->kill_timers) | 3171 | if (bond->params.arp_interval) |
3160 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); | 3172 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
3161 | out: | 3173 | |
3162 | read_unlock(&bond->lock); | 3174 | read_unlock(&bond->lock); |
3163 | 3175 | ||
3164 | if (should_notify_peers) { | 3176 | if (should_notify_peers) { |
3165 | rtnl_lock(); | 3177 | if (!rtnl_trylock()) { |
3178 | read_lock(&bond->lock); | ||
3179 | bond->send_peer_notif++; | ||
3180 | read_unlock(&bond->lock); | ||
3181 | return; | ||
3182 | } | ||
3166 | netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS); | 3183 | netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS); |
3167 | rtnl_unlock(); | 3184 | rtnl_unlock(); |
3168 | } | 3185 | } |
@@ -3424,8 +3441,6 @@ static int bond_open(struct net_device *bond_dev) | |||
3424 | struct slave *slave; | 3441 | struct slave *slave; |
3425 | int i; | 3442 | int i; |
3426 | 3443 | ||
3427 | bond->kill_timers = 0; | ||
3428 | |||
3429 | /* reset slave->backup and slave->inactive */ | 3444 | /* reset slave->backup and slave->inactive */ |
3430 | read_lock(&bond->lock); | 3445 | read_lock(&bond->lock); |
3431 | if (bond->slave_cnt > 0) { | 3446 | if (bond->slave_cnt > 0) { |
@@ -3494,33 +3509,30 @@ static int bond_close(struct net_device *bond_dev) | |||
3494 | 3509 | ||
3495 | bond->send_peer_notif = 0; | 3510 | bond->send_peer_notif = 0; |
3496 | 3511 | ||
3497 | /* signal timers not to re-arm */ | ||
3498 | bond->kill_timers = 1; | ||
3499 | |||
3500 | write_unlock_bh(&bond->lock); | 3512 | write_unlock_bh(&bond->lock); |
3501 | 3513 | ||
3502 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3514 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ |
3503 | cancel_delayed_work(&bond->mii_work); | 3515 | cancel_delayed_work_sync(&bond->mii_work); |
3504 | } | 3516 | } |
3505 | 3517 | ||
3506 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | 3518 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
3507 | cancel_delayed_work(&bond->arp_work); | 3519 | cancel_delayed_work_sync(&bond->arp_work); |
3508 | } | 3520 | } |
3509 | 3521 | ||
3510 | switch (bond->params.mode) { | 3522 | switch (bond->params.mode) { |
3511 | case BOND_MODE_8023AD: | 3523 | case BOND_MODE_8023AD: |
3512 | cancel_delayed_work(&bond->ad_work); | 3524 | cancel_delayed_work_sync(&bond->ad_work); |
3513 | break; | 3525 | break; |
3514 | case BOND_MODE_TLB: | 3526 | case BOND_MODE_TLB: |
3515 | case BOND_MODE_ALB: | 3527 | case BOND_MODE_ALB: |
3516 | cancel_delayed_work(&bond->alb_work); | 3528 | cancel_delayed_work_sync(&bond->alb_work); |
3517 | break; | 3529 | break; |
3518 | default: | 3530 | default: |
3519 | break; | 3531 | break; |
3520 | } | 3532 | } |
3521 | 3533 | ||
3522 | if (delayed_work_pending(&bond->mcast_work)) | 3534 | if (delayed_work_pending(&bond->mcast_work)) |
3523 | cancel_delayed_work(&bond->mcast_work); | 3535 | cancel_delayed_work_sync(&bond->mcast_work); |
3524 | 3536 | ||
3525 | if (bond_is_lb(bond)) { | 3537 | if (bond_is_lb(bond)) { |
3526 | /* Must be called only after all | 3538 | /* Must be called only after all |
@@ -4367,26 +4379,22 @@ static void bond_setup(struct net_device *bond_dev) | |||
4367 | 4379 | ||
4368 | static void bond_work_cancel_all(struct bonding *bond) | 4380 | static void bond_work_cancel_all(struct bonding *bond) |
4369 | { | 4381 | { |
4370 | write_lock_bh(&bond->lock); | ||
4371 | bond->kill_timers = 1; | ||
4372 | write_unlock_bh(&bond->lock); | ||
4373 | |||
4374 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | 4382 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) |
4375 | cancel_delayed_work(&bond->mii_work); | 4383 | cancel_delayed_work_sync(&bond->mii_work); |
4376 | 4384 | ||
4377 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | 4385 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) |
4378 | cancel_delayed_work(&bond->arp_work); | 4386 | cancel_delayed_work_sync(&bond->arp_work); |
4379 | 4387 | ||
4380 | if (bond->params.mode == BOND_MODE_ALB && | 4388 | if (bond->params.mode == BOND_MODE_ALB && |
4381 | delayed_work_pending(&bond->alb_work)) | 4389 | delayed_work_pending(&bond->alb_work)) |
4382 | cancel_delayed_work(&bond->alb_work); | 4390 | cancel_delayed_work_sync(&bond->alb_work); |
4383 | 4391 | ||
4384 | if (bond->params.mode == BOND_MODE_8023AD && | 4392 | if (bond->params.mode == BOND_MODE_8023AD && |
4385 | delayed_work_pending(&bond->ad_work)) | 4393 | delayed_work_pending(&bond->ad_work)) |
4386 | cancel_delayed_work(&bond->ad_work); | 4394 | cancel_delayed_work_sync(&bond->ad_work); |
4387 | 4395 | ||
4388 | if (delayed_work_pending(&bond->mcast_work)) | 4396 | if (delayed_work_pending(&bond->mcast_work)) |
4389 | cancel_delayed_work(&bond->mcast_work); | 4397 | cancel_delayed_work_sync(&bond->mcast_work); |
4390 | } | 4398 | } |
4391 | 4399 | ||
4392 | /* | 4400 | /* |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 82fec5fc75d7..1aecc37e5b4d 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -222,7 +222,6 @@ struct bonding { | |||
222 | struct slave *); | 222 | struct slave *); |
223 | rwlock_t lock; | 223 | rwlock_t lock; |
224 | rwlock_t curr_slave_lock; | 224 | rwlock_t curr_slave_lock; |
225 | s8 kill_timers; | ||
226 | u8 send_peer_notif; | 225 | u8 send_peer_notif; |
227 | s8 setup_by_slave; | 226 | s8 setup_by_slave; |
228 | s8 igmp_retrans; | 227 | s8 igmp_retrans; |