diff options
-rw-r--r-- | drivers/net/bonding/bond_main.c | 88 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 34 |
2 files changed, 36 insertions, 86 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5f5b69f37d2e..1445c7ddb26c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -3459,6 +3459,28 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) | |||
3459 | 3459 | ||
3460 | /*-------------------------- Device entry points ----------------------------*/ | 3460 | /*-------------------------- Device entry points ----------------------------*/ |
3461 | 3461 | ||
3462 | static void bond_work_init_all(struct bonding *bond) | ||
3463 | { | ||
3464 | INIT_DELAYED_WORK(&bond->mcast_work, | ||
3465 | bond_resend_igmp_join_requests_delayed); | ||
3466 | INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | ||
3467 | INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | ||
3468 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
3469 | INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon); | ||
3470 | else | ||
3471 | INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon); | ||
3472 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | ||
3473 | } | ||
3474 | |||
3475 | static void bond_work_cancel_all(struct bonding *bond) | ||
3476 | { | ||
3477 | cancel_delayed_work_sync(&bond->mii_work); | ||
3478 | cancel_delayed_work_sync(&bond->arp_work); | ||
3479 | cancel_delayed_work_sync(&bond->alb_work); | ||
3480 | cancel_delayed_work_sync(&bond->ad_work); | ||
3481 | cancel_delayed_work_sync(&bond->mcast_work); | ||
3482 | } | ||
3483 | |||
3462 | static int bond_open(struct net_device *bond_dev) | 3484 | static int bond_open(struct net_device *bond_dev) |
3463 | { | 3485 | { |
3464 | struct bonding *bond = netdev_priv(bond_dev); | 3486 | struct bonding *bond = netdev_priv(bond_dev); |
@@ -3481,41 +3503,27 @@ static int bond_open(struct net_device *bond_dev) | |||
3481 | } | 3503 | } |
3482 | read_unlock(&bond->lock); | 3504 | read_unlock(&bond->lock); |
3483 | 3505 | ||
3484 | INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); | 3506 | bond_work_init_all(bond); |
3485 | 3507 | ||
3486 | if (bond_is_lb(bond)) { | 3508 | if (bond_is_lb(bond)) { |
3487 | /* bond_alb_initialize must be called before the timer | 3509 | /* bond_alb_initialize must be called before the timer |
3488 | * is started. | 3510 | * is started. |
3489 | */ | 3511 | */ |
3490 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) { | 3512 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) |
3491 | /* something went wrong - fail the open operation */ | ||
3492 | return -ENOMEM; | 3513 | return -ENOMEM; |
3493 | } | ||
3494 | |||
3495 | INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | ||
3496 | queue_delayed_work(bond->wq, &bond->alb_work, 0); | 3514 | queue_delayed_work(bond->wq, &bond->alb_work, 0); |
3497 | } | 3515 | } |
3498 | 3516 | ||
3499 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3517 | if (bond->params.miimon) /* link check interval, in milliseconds. */ |
3500 | INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | ||
3501 | queue_delayed_work(bond->wq, &bond->mii_work, 0); | 3518 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
3502 | } | ||
3503 | 3519 | ||
3504 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | 3520 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
3505 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
3506 | INIT_DELAYED_WORK(&bond->arp_work, | ||
3507 | bond_activebackup_arp_mon); | ||
3508 | else | ||
3509 | INIT_DELAYED_WORK(&bond->arp_work, | ||
3510 | bond_loadbalance_arp_mon); | ||
3511 | |||
3512 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | 3521 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
3513 | if (bond->params.arp_validate) | 3522 | if (bond->params.arp_validate) |
3514 | bond->recv_probe = bond_arp_rcv; | 3523 | bond->recv_probe = bond_arp_rcv; |
3515 | } | 3524 | } |
3516 | 3525 | ||
3517 | if (bond->params.mode == BOND_MODE_8023AD) { | 3526 | if (bond->params.mode == BOND_MODE_8023AD) { |
3518 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | ||
3519 | queue_delayed_work(bond->wq, &bond->ad_work, 0); | 3527 | queue_delayed_work(bond->wq, &bond->ad_work, 0); |
3520 | /* register to receive LACPDUs */ | 3528 | /* register to receive LACPDUs */ |
3521 | bond->recv_probe = bond_3ad_lacpdu_recv; | 3529 | bond->recv_probe = bond_3ad_lacpdu_recv; |
@@ -3530,34 +3538,10 @@ static int bond_close(struct net_device *bond_dev) | |||
3530 | struct bonding *bond = netdev_priv(bond_dev); | 3538 | struct bonding *bond = netdev_priv(bond_dev); |
3531 | 3539 | ||
3532 | write_lock_bh(&bond->lock); | 3540 | write_lock_bh(&bond->lock); |
3533 | |||
3534 | bond->send_peer_notif = 0; | 3541 | bond->send_peer_notif = 0; |
3535 | |||
3536 | write_unlock_bh(&bond->lock); | 3542 | write_unlock_bh(&bond->lock); |
3537 | 3543 | ||
3538 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3544 | bond_work_cancel_all(bond); |
3539 | cancel_delayed_work_sync(&bond->mii_work); | ||
3540 | } | ||
3541 | |||
3542 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | ||
3543 | cancel_delayed_work_sync(&bond->arp_work); | ||
3544 | } | ||
3545 | |||
3546 | switch (bond->params.mode) { | ||
3547 | case BOND_MODE_8023AD: | ||
3548 | cancel_delayed_work_sync(&bond->ad_work); | ||
3549 | break; | ||
3550 | case BOND_MODE_TLB: | ||
3551 | case BOND_MODE_ALB: | ||
3552 | cancel_delayed_work_sync(&bond->alb_work); | ||
3553 | break; | ||
3554 | default: | ||
3555 | break; | ||
3556 | } | ||
3557 | |||
3558 | if (delayed_work_pending(&bond->mcast_work)) | ||
3559 | cancel_delayed_work_sync(&bond->mcast_work); | ||
3560 | |||
3561 | if (bond_is_lb(bond)) { | 3545 | if (bond_is_lb(bond)) { |
3562 | /* Must be called only after all | 3546 | /* Must be called only after all |
3563 | * slaves have been released | 3547 | * slaves have been released |
@@ -4436,26 +4420,6 @@ static void bond_setup(struct net_device *bond_dev) | |||
4436 | bond_dev->features |= bond_dev->hw_features; | 4420 | bond_dev->features |= bond_dev->hw_features; |
4437 | } | 4421 | } |
4438 | 4422 | ||
4439 | static void bond_work_cancel_all(struct bonding *bond) | ||
4440 | { | ||
4441 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | ||
4442 | cancel_delayed_work_sync(&bond->mii_work); | ||
4443 | |||
4444 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | ||
4445 | cancel_delayed_work_sync(&bond->arp_work); | ||
4446 | |||
4447 | if (bond->params.mode == BOND_MODE_ALB && | ||
4448 | delayed_work_pending(&bond->alb_work)) | ||
4449 | cancel_delayed_work_sync(&bond->alb_work); | ||
4450 | |||
4451 | if (bond->params.mode == BOND_MODE_8023AD && | ||
4452 | delayed_work_pending(&bond->ad_work)) | ||
4453 | cancel_delayed_work_sync(&bond->ad_work); | ||
4454 | |||
4455 | if (delayed_work_pending(&bond->mcast_work)) | ||
4456 | cancel_delayed_work_sync(&bond->mcast_work); | ||
4457 | } | ||
4458 | |||
4459 | /* | 4423 | /* |
4460 | * Destroy a bonding device. | 4424 | * Destroy a bonding device. |
4461 | * Must be under rtnl_lock when this function is called. | 4425 | * Must be under rtnl_lock when this function is called. |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index ef8d2a080d17..3327a072e224 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -513,6 +513,8 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
513 | int new_value, ret = count; | 513 | int new_value, ret = count; |
514 | struct bonding *bond = to_bond(d); | 514 | struct bonding *bond = to_bond(d); |
515 | 515 | ||
516 | if (!rtnl_trylock()) | ||
517 | return restart_syscall(); | ||
516 | if (sscanf(buf, "%d", &new_value) != 1) { | 518 | if (sscanf(buf, "%d", &new_value) != 1) { |
517 | pr_err("%s: no arp_interval value specified.\n", | 519 | pr_err("%s: no arp_interval value specified.\n", |
518 | bond->dev->name); | 520 | bond->dev->name); |
@@ -539,10 +541,6 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
539 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", | 541 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", |
540 | bond->dev->name, bond->dev->name); | 542 | bond->dev->name, bond->dev->name); |
541 | bond->params.miimon = 0; | 543 | bond->params.miimon = 0; |
542 | if (delayed_work_pending(&bond->mii_work)) { | ||
543 | cancel_delayed_work(&bond->mii_work); | ||
544 | flush_workqueue(bond->wq); | ||
545 | } | ||
546 | } | 544 | } |
547 | if (!bond->params.arp_targets[0]) { | 545 | if (!bond->params.arp_targets[0]) { |
548 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", | 546 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", |
@@ -554,19 +552,12 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
554 | * timer will get fired off when the open function | 552 | * timer will get fired off when the open function |
555 | * is called. | 553 | * is called. |
556 | */ | 554 | */ |
557 | if (!delayed_work_pending(&bond->arp_work)) { | 555 | cancel_delayed_work_sync(&bond->mii_work); |
558 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | 556 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
559 | INIT_DELAYED_WORK(&bond->arp_work, | ||
560 | bond_activebackup_arp_mon); | ||
561 | else | ||
562 | INIT_DELAYED_WORK(&bond->arp_work, | ||
563 | bond_loadbalance_arp_mon); | ||
564 | |||
565 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | ||
566 | } | ||
567 | } | 557 | } |
568 | 558 | ||
569 | out: | 559 | out: |
560 | rtnl_unlock(); | ||
570 | return ret; | 561 | return ret; |
571 | } | 562 | } |
572 | static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, | 563 | static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, |
@@ -962,6 +953,8 @@ static ssize_t bonding_store_miimon(struct device *d, | |||
962 | int new_value, ret = count; | 953 | int new_value, ret = count; |
963 | struct bonding *bond = to_bond(d); | 954 | struct bonding *bond = to_bond(d); |
964 | 955 | ||
956 | if (!rtnl_trylock()) | ||
957 | return restart_syscall(); | ||
965 | if (sscanf(buf, "%d", &new_value) != 1) { | 958 | if (sscanf(buf, "%d", &new_value) != 1) { |
966 | pr_err("%s: no miimon value specified.\n", | 959 | pr_err("%s: no miimon value specified.\n", |
967 | bond->dev->name); | 960 | bond->dev->name); |
@@ -993,10 +986,6 @@ static ssize_t bonding_store_miimon(struct device *d, | |||
993 | bond->params.arp_validate = | 986 | bond->params.arp_validate = |
994 | BOND_ARP_VALIDATE_NONE; | 987 | BOND_ARP_VALIDATE_NONE; |
995 | } | 988 | } |
996 | if (delayed_work_pending(&bond->arp_work)) { | ||
997 | cancel_delayed_work(&bond->arp_work); | ||
998 | flush_workqueue(bond->wq); | ||
999 | } | ||
1000 | } | 989 | } |
1001 | 990 | ||
1002 | if (bond->dev->flags & IFF_UP) { | 991 | if (bond->dev->flags & IFF_UP) { |
@@ -1005,15 +994,12 @@ static ssize_t bonding_store_miimon(struct device *d, | |||
1005 | * timer will get fired off when the open function | 994 | * timer will get fired off when the open function |
1006 | * is called. | 995 | * is called. |
1007 | */ | 996 | */ |
1008 | if (!delayed_work_pending(&bond->mii_work)) { | 997 | cancel_delayed_work_sync(&bond->arp_work); |
1009 | INIT_DELAYED_WORK(&bond->mii_work, | 998 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
1010 | bond_mii_monitor); | ||
1011 | queue_delayed_work(bond->wq, | ||
1012 | &bond->mii_work, 0); | ||
1013 | } | ||
1014 | } | 999 | } |
1015 | } | 1000 | } |
1016 | out: | 1001 | out: |
1002 | rtnl_unlock(); | ||
1017 | return ret; | 1003 | return ret; |
1018 | } | 1004 | } |
1019 | static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, | 1005 | static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, |