aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c106
1 files changed, 56 insertions, 50 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2039f7838f2d..0942d82f7cbf 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1464,10 +1464,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1464 dev_set_allmulti(slave_dev, 1); 1464 dev_set_allmulti(slave_dev, 1);
1465 } 1465 }
1466 1466
1467 netif_tx_lock_bh(bond_dev);
1467 /* upload master's mc_list to new slave */ 1468 /* upload master's mc_list to new slave */
1468 for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { 1469 for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
1469 dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); 1470 dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
1470 } 1471 }
1472 netif_tx_unlock_bh(bond_dev);
1471 } 1473 }
1472 1474
1473 if (bond->params.mode == BOND_MODE_8023AD) { 1475 if (bond->params.mode == BOND_MODE_8023AD) {
@@ -1821,7 +1823,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1821 } 1823 }
1822 1824
1823 /* flush master's mc_list from slave */ 1825 /* flush master's mc_list from slave */
1826 netif_tx_lock_bh(bond_dev);
1824 bond_mc_list_flush(bond_dev, slave_dev); 1827 bond_mc_list_flush(bond_dev, slave_dev);
1828 netif_tx_unlock_bh(bond_dev);
1825 } 1829 }
1826 1830
1827 netdev_set_master(slave_dev, NULL); 1831 netdev_set_master(slave_dev, NULL);
@@ -1942,7 +1946,9 @@ static int bond_release_all(struct net_device *bond_dev)
1942 } 1946 }
1943 1947
1944 /* flush master's mc_list from slave */ 1948 /* flush master's mc_list from slave */
1949 netif_tx_lock_bh(bond_dev);
1945 bond_mc_list_flush(bond_dev, slave_dev); 1950 bond_mc_list_flush(bond_dev, slave_dev);
1951 netif_tx_unlock_bh(bond_dev);
1946 } 1952 }
1947 1953
1948 netdev_set_master(slave_dev, NULL); 1954 netdev_set_master(slave_dev, NULL);
@@ -2795,14 +2801,11 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
2795 } 2801 }
2796 2802
2797 if (do_failover) { 2803 if (do_failover) {
2798 rtnl_lock();
2799 write_lock_bh(&bond->curr_slave_lock); 2804 write_lock_bh(&bond->curr_slave_lock);
2800 2805
2801 bond_select_active_slave(bond); 2806 bond_select_active_slave(bond);
2802 2807
2803 write_unlock_bh(&bond->curr_slave_lock); 2808 write_unlock_bh(&bond->curr_slave_lock);
2804 rtnl_unlock();
2805
2806 } 2809 }
2807 2810
2808re_arm: 2811re_arm:
@@ -2859,8 +2862,6 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2859 2862
2860 slave->link = BOND_LINK_UP; 2863 slave->link = BOND_LINK_UP;
2861 2864
2862 rtnl_lock();
2863
2864 write_lock_bh(&bond->curr_slave_lock); 2865 write_lock_bh(&bond->curr_slave_lock);
2865 2866
2866 if ((!bond->curr_active_slave) && 2867 if ((!bond->curr_active_slave) &&
@@ -2896,7 +2897,6 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2896 } 2897 }
2897 2898
2898 write_unlock_bh(&bond->curr_slave_lock); 2899 write_unlock_bh(&bond->curr_slave_lock);
2899 rtnl_unlock();
2900 } 2900 }
2901 } else { 2901 } else {
2902 read_lock(&bond->curr_slave_lock); 2902 read_lock(&bond->curr_slave_lock);
@@ -2966,7 +2966,6 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2966 bond->dev->name, 2966 bond->dev->name,
2967 slave->dev->name); 2967 slave->dev->name);
2968 2968
2969 rtnl_lock();
2970 write_lock_bh(&bond->curr_slave_lock); 2969 write_lock_bh(&bond->curr_slave_lock);
2971 2970
2972 bond_select_active_slave(bond); 2971 bond_select_active_slave(bond);
@@ -2974,8 +2973,6 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2974 2973
2975 write_unlock_bh(&bond->curr_slave_lock); 2974 write_unlock_bh(&bond->curr_slave_lock);
2976 2975
2977 rtnl_unlock();
2978
2979 bond->current_arp_slave = slave; 2976 bond->current_arp_slave = slave;
2980 2977
2981 if (slave) { 2978 if (slave) {
@@ -2993,13 +2990,10 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2993 bond->primary_slave->dev->name); 2990 bond->primary_slave->dev->name);
2994 2991
2995 /* primary is up so switch to it */ 2992 /* primary is up so switch to it */
2996 rtnl_lock();
2997 write_lock_bh(&bond->curr_slave_lock); 2993 write_lock_bh(&bond->curr_slave_lock);
2998 bond_change_active_slave(bond, bond->primary_slave); 2994 bond_change_active_slave(bond, bond->primary_slave);
2999 write_unlock_bh(&bond->curr_slave_lock); 2995 write_unlock_bh(&bond->curr_slave_lock);
3000 2996
3001 rtnl_unlock();
3002
3003 slave = bond->primary_slave; 2997 slave = bond->primary_slave;
3004 slave->jiffies = jiffies; 2998 slave->jiffies = jiffies;
3005 } else { 2999 } else {
@@ -3769,42 +3763,45 @@ static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
3769{ 3763{
3770 struct bonding *bond = bond_dev->priv; 3764 struct bonding *bond = bond_dev->priv;
3771 struct net_device_stats *stats = &(bond->stats), *sstats; 3765 struct net_device_stats *stats = &(bond->stats), *sstats;
3766 struct net_device_stats local_stats;
3772 struct slave *slave; 3767 struct slave *slave;
3773 int i; 3768 int i;
3774 3769
3775 memset(stats, 0, sizeof(struct net_device_stats)); 3770 memset(&local_stats, 0, sizeof(struct net_device_stats));
3776 3771
3777 read_lock_bh(&bond->lock); 3772 read_lock_bh(&bond->lock);
3778 3773
3779 bond_for_each_slave(bond, slave, i) { 3774 bond_for_each_slave(bond, slave, i) {
3780 sstats = slave->dev->get_stats(slave->dev); 3775 sstats = slave->dev->get_stats(slave->dev);
3781 stats->rx_packets += sstats->rx_packets; 3776 local_stats.rx_packets += sstats->rx_packets;
3782 stats->rx_bytes += sstats->rx_bytes; 3777 local_stats.rx_bytes += sstats->rx_bytes;
3783 stats->rx_errors += sstats->rx_errors; 3778 local_stats.rx_errors += sstats->rx_errors;
3784 stats->rx_dropped += sstats->rx_dropped; 3779 local_stats.rx_dropped += sstats->rx_dropped;
3785 3780
3786 stats->tx_packets += sstats->tx_packets; 3781 local_stats.tx_packets += sstats->tx_packets;
3787 stats->tx_bytes += sstats->tx_bytes; 3782 local_stats.tx_bytes += sstats->tx_bytes;
3788 stats->tx_errors += sstats->tx_errors; 3783 local_stats.tx_errors += sstats->tx_errors;
3789 stats->tx_dropped += sstats->tx_dropped; 3784 local_stats.tx_dropped += sstats->tx_dropped;
3790 3785
3791 stats->multicast += sstats->multicast; 3786 local_stats.multicast += sstats->multicast;
3792 stats->collisions += sstats->collisions; 3787 local_stats.collisions += sstats->collisions;
3793 3788
3794 stats->rx_length_errors += sstats->rx_length_errors; 3789 local_stats.rx_length_errors += sstats->rx_length_errors;
3795 stats->rx_over_errors += sstats->rx_over_errors; 3790 local_stats.rx_over_errors += sstats->rx_over_errors;
3796 stats->rx_crc_errors += sstats->rx_crc_errors; 3791 local_stats.rx_crc_errors += sstats->rx_crc_errors;
3797 stats->rx_frame_errors += sstats->rx_frame_errors; 3792 local_stats.rx_frame_errors += sstats->rx_frame_errors;
3798 stats->rx_fifo_errors += sstats->rx_fifo_errors; 3793 local_stats.rx_fifo_errors += sstats->rx_fifo_errors;
3799 stats->rx_missed_errors += sstats->rx_missed_errors; 3794 local_stats.rx_missed_errors += sstats->rx_missed_errors;
3800 3795
3801 stats->tx_aborted_errors += sstats->tx_aborted_errors; 3796 local_stats.tx_aborted_errors += sstats->tx_aborted_errors;
3802 stats->tx_carrier_errors += sstats->tx_carrier_errors; 3797 local_stats.tx_carrier_errors += sstats->tx_carrier_errors;
3803 stats->tx_fifo_errors += sstats->tx_fifo_errors; 3798 local_stats.tx_fifo_errors += sstats->tx_fifo_errors;
3804 stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors; 3799 local_stats.tx_heartbeat_errors += sstats->tx_heartbeat_errors;
3805 stats->tx_window_errors += sstats->tx_window_errors; 3800 local_stats.tx_window_errors += sstats->tx_window_errors;
3806 } 3801 }
3807 3802
3803 memcpy(stats, &local_stats, sizeof(struct net_device_stats));
3804
3808 read_unlock_bh(&bond->lock); 3805 read_unlock_bh(&bond->lock);
3809 3806
3810 return stats; 3807 return stats;
@@ -3937,8 +3934,6 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
3937 struct bonding *bond = bond_dev->priv; 3934 struct bonding *bond = bond_dev->priv;
3938 struct dev_mc_list *dmi; 3935 struct dev_mc_list *dmi;
3939 3936
3940 write_lock_bh(&bond->lock);
3941
3942 /* 3937 /*
3943 * Do promisc before checking multicast_mode 3938 * Do promisc before checking multicast_mode
3944 */ 3939 */
@@ -3959,6 +3954,8 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
3959 bond_set_allmulti(bond, -1); 3954 bond_set_allmulti(bond, -1);
3960 } 3955 }
3961 3956
3957 read_lock(&bond->lock);
3958
3962 bond->flags = bond_dev->flags; 3959 bond->flags = bond_dev->flags;
3963 3960
3964 /* looking for addresses to add to slaves' mc list */ 3961 /* looking for addresses to add to slaves' mc list */
@@ -3979,7 +3976,7 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
3979 bond_mc_list_destroy(bond); 3976 bond_mc_list_destroy(bond);
3980 bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC); 3977 bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC);
3981 3978
3982 write_unlock_bh(&bond->lock); 3979 read_unlock(&bond->lock);
3983} 3980}
3984 3981
3985/* 3982/*
@@ -4526,7 +4523,9 @@ static void bond_free_all(void)
4526 struct net_device *bond_dev = bond->dev; 4523 struct net_device *bond_dev = bond->dev;
4527 4524
4528 bond_work_cancel_all(bond); 4525 bond_work_cancel_all(bond);
4526 netif_tx_lock_bh(bond_dev);
4529 bond_mc_list_destroy(bond); 4527 bond_mc_list_destroy(bond);
4528 netif_tx_unlock_bh(bond_dev);
4530 /* Release the bonded slaves */ 4529 /* Release the bonded slaves */
4531 bond_release_all(bond_dev); 4530 bond_release_all(bond_dev);
4532 bond_deinit(bond_dev); 4531 bond_deinit(bond_dev);
@@ -4549,14 +4548,19 @@ static void bond_free_all(void)
4549int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl) 4548int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
4550{ 4549{
4551 int mode = -1, i, rv; 4550 int mode = -1, i, rv;
4552 char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, }; 4551 char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
4553 4552
4554 rv = sscanf(buf, "%d", &mode); 4553 for (p = (char *)buf; *p; p++)
4555 if (!rv) { 4554 if (!(isdigit(*p) || isspace(*p)))
4555 break;
4556
4557 if (*p)
4556 rv = sscanf(buf, "%20s", modestr); 4558 rv = sscanf(buf, "%20s", modestr);
4557 if (!rv) 4559 else
4558 return -1; 4560 rv = sscanf(buf, "%d", &mode);
4559 } 4561
4562 if (!rv)
4563 return -1;
4560 4564
4561 for (i = 0; tbl[i].modename; i++) { 4565 for (i = 0; tbl[i].modename; i++) {
4562 if (mode == tbl[i].mode) 4566 if (mode == tbl[i].mode)
@@ -4883,14 +4887,16 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
4883 down_write(&bonding_rwsem); 4887 down_write(&bonding_rwsem);
4884 4888
4885 /* Check to see if the bond already exists. */ 4889 /* Check to see if the bond already exists. */
4886 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) 4890 if (name) {
4887 if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { 4891 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
4888 printk(KERN_ERR DRV_NAME 4892 if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
4893 printk(KERN_ERR DRV_NAME
4889 ": cannot add bond %s; it already exists\n", 4894 ": cannot add bond %s; it already exists\n",
4890 name); 4895 name);
4891 res = -EPERM; 4896 res = -EPERM;
4892 goto out_rtnl; 4897 goto out_rtnl;
4893 } 4898 }
4899 }
4894 4900
4895 bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", 4901 bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
4896 ether_setup); 4902 ether_setup);