diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 106 |
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) dev_set_allmulti(slave_dev, 1); } + netif_tx_lock_bh(bond_dev); /* upload master's mc_list to new slave */ for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); } + netif_tx_unlock_bh(bond_dev); } if (bond->params.mode == BOND_MODE_8023AD) { @@ -1821,7 +1823,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) } /* flush master's mc_list from slave */ + netif_tx_lock_bh(bond_dev); bond_mc_list_flush(bond_dev, slave_dev); + netif_tx_unlock_bh(bond_dev); } netdev_set_master(slave_dev, NULL); @@ -1942,7 +1946,9 @@ static int bond_release_all(struct net_device *bond_dev) } /* flush master's mc_list from slave */ + netif_tx_lock_bh(bond_dev); bond_mc_list_flush(bond_dev, slave_dev); + netif_tx_unlock_bh(bond_dev); } netdev_set_master(slave_dev, NULL); @@ -2795,14 +2801,11 @@ void bond_loadbalance_arp_mon(struct work_struct *work) } if (do_failover) { - rtnl_lock(); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); - rtnl_unlock(); - } re_arm: @@ -2859,8 +2862,6 @@ void bond_activebackup_arp_mon(struct work_struct *work) slave->link = BOND_LINK_UP; - rtnl_lock(); - write_lock_bh(&bond->curr_slave_lock); if ((!bond->curr_active_slave) && @@ -2896,7 +2897,6 @@ void bond_activebackup_arp_mon(struct work_struct *work) } write_unlock_bh(&bond->curr_slave_lock); - rtnl_unlock(); } } else { read_lock(&bond->curr_slave_lock); @@ -2966,7 +2966,6 @@ void bond_activebackup_arp_mon(struct work_struct *work) bond->dev->name, slave->dev->name); - rtnl_lock(); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); @@ -2974,8 +2973,6 @@ void bond_activebackup_arp_mon(struct work_struct *work) write_unlock_bh(&bond->curr_slave_lock); - rtnl_unlock(); - bond->current_arp_slave = slave; if (slave) { @@ -2993,13 +2990,10 @@ void bond_activebackup_arp_mon(struct work_struct *work) bond->primary_slave->dev->name); /* primary is up so switch to it */ - rtnl_lock(); write_lock_bh(&bond->curr_slave_lock); bond_change_active_slave(bond, bond->primary_slave); write_unlock_bh(&bond->curr_slave_lock); - rtnl_unlock(); - slave = bond->primary_slave; slave->jiffies = jiffies; } else { @@ -3769,42 +3763,45 @@ static struct net_device_stats *bond_get_stats(struct net_device *bond_dev) { struct bonding *bond = bond_dev->priv; struct net_device_stats *stats = &(bond->stats), *sstats; + struct net_device_stats local_stats; struct slave *slave; int i; - memset(stats, 0, sizeof(struct net_device_stats)); + memset(&local_stats, 0, sizeof(struct net_device_stats)); read_lock_bh(&bond->lock); bond_for_each_slave(bond, slave, i) { sstats = slave->dev->get_stats(slave->dev); - stats->rx_packets += sstats->rx_packets; - stats->rx_bytes += sstats->rx_bytes; - stats->rx_errors += sstats->rx_errors; - stats->rx_dropped += sstats->rx_dropped; + local_stats.rx_packets += sstats->rx_packets; + local_stats.rx_bytes += sstats->rx_bytes; + local_stats.rx_errors += sstats->rx_errors; + local_stats.rx_dropped += sstats->rx_dropped; - stats->tx_packets += sstats->tx_packets; - stats->tx_bytes += sstats->tx_bytes; - stats->tx_errors += sstats->tx_errors; - stats->tx_dropped += sstats->tx_dropped; + local_stats.tx_packets += sstats->tx_packets; + local_stats.tx_bytes += sstats->tx_bytes; + local_stats.tx_errors += sstats->tx_errors; + local_stats.tx_dropped += sstats->tx_dropped; - stats->multicast += sstats->multicast; - stats->collisions += sstats->collisions; + local_stats.multicast += sstats->multicast; + local_stats.collisions += sstats->collisions; - stats->rx_length_errors += sstats->rx_length_errors; - stats->rx_over_errors += sstats->rx_over_errors; - stats->rx_crc_errors += sstats->rx_crc_errors; - stats->rx_frame_errors += sstats->rx_frame_errors; - stats->rx_fifo_errors += sstats->rx_fifo_errors; - stats->rx_missed_errors += sstats->rx_missed_errors; + local_stats.rx_length_errors += sstats->rx_length_errors; + local_stats.rx_over_errors += sstats->rx_over_errors; + local_stats.rx_crc_errors += sstats->rx_crc_errors; + local_stats.rx_frame_errors += sstats->rx_frame_errors; + local_stats.rx_fifo_errors += sstats->rx_fifo_errors; + local_stats.rx_missed_errors += sstats->rx_missed_errors; - stats->tx_aborted_errors += sstats->tx_aborted_errors; - stats->tx_carrier_errors += sstats->tx_carrier_errors; - stats->tx_fifo_errors += sstats->tx_fifo_errors; - stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors; - stats->tx_window_errors += sstats->tx_window_errors; + local_stats.tx_aborted_errors += sstats->tx_aborted_errors; + local_stats.tx_carrier_errors += sstats->tx_carrier_errors; + local_stats.tx_fifo_errors += sstats->tx_fifo_errors; + local_stats.tx_heartbeat_errors += sstats->tx_heartbeat_errors; + local_stats.tx_window_errors += sstats->tx_window_errors; } + memcpy(stats, &local_stats, sizeof(struct net_device_stats)); + read_unlock_bh(&bond->lock); return stats; @@ -3937,8 +3934,6 @@ static void bond_set_multicast_list(struct net_device *bond_dev) struct bonding *bond = bond_dev->priv; struct dev_mc_list *dmi; - write_lock_bh(&bond->lock); - /* * Do promisc before checking multicast_mode */ @@ -3959,6 +3954,8 @@ static void bond_set_multicast_list(struct net_device *bond_dev) bond_set_allmulti(bond, -1); } + read_lock(&bond->lock); + bond->flags = bond_dev->flags; /* looking for addresses to add to slaves' mc list */ @@ -3979,7 +3976,7 @@ static void bond_set_multicast_list(struct net_device *bond_dev) bond_mc_list_destroy(bond); bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC); - write_unlock_bh(&bond->lock); + read_unlock(&bond->lock); } /* @@ -4526,7 +4523,9 @@ static void bond_free_all(void) struct net_device *bond_dev = bond->dev; bond_work_cancel_all(bond); + netif_tx_lock_bh(bond_dev); bond_mc_list_destroy(bond); + netif_tx_unlock_bh(bond_dev); /* Release the bonded slaves */ bond_release_all(bond_dev); bond_deinit(bond_dev); @@ -4549,14 +4548,19 @@ static void bond_free_all(void) int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl) { int mode = -1, i, rv; - char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, }; + char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, }; - rv = sscanf(buf, "%d", &mode); - if (!rv) { + for (p = (char *)buf; *p; p++) + if (!(isdigit(*p) || isspace(*p))) + break; + + if (*p) rv = sscanf(buf, "%20s", modestr); - if (!rv) - return -1; - } + else + rv = sscanf(buf, "%d", &mode); + + if (!rv) + return -1; for (i = 0; tbl[i].modename; i++) { if (mode == tbl[i].mode) @@ -4883,14 +4887,16 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond down_write(&bonding_rwsem); /* Check to see if the bond already exists. */ - list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) - if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { - printk(KERN_ERR DRV_NAME + if (name) { + list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) + if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { + printk(KERN_ERR DRV_NAME ": cannot add bond %s; it already exists\n", - name); - res = -EPERM; - goto out_rtnl; - } + name); + res = -EPERM; + goto out_rtnl; + } + } bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", ether_setup); |