aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c75
-rw-r--r--drivers/net/bonding/bond_sysfs.c116
-rw-r--r--drivers/net/bonding/bonding.h9
3 files changed, 195 insertions, 5 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f22f6bf43858..1b19276cff12 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -90,6 +90,7 @@
90#define BOND_LINK_ARP_INTERV 0 90#define BOND_LINK_ARP_INTERV 0
91 91
92static int max_bonds = BOND_DEFAULT_MAX_BONDS; 92static int max_bonds = BOND_DEFAULT_MAX_BONDS;
93static int tx_queues = BOND_DEFAULT_TX_QUEUES;
93static int num_grat_arp = 1; 94static int num_grat_arp = 1;
94static int num_unsol_na = 1; 95static int num_unsol_na = 1;
95static int miimon = BOND_LINK_MON_INTERV; 96static int miimon = BOND_LINK_MON_INTERV;
@@ -111,6 +112,8 @@ static struct bond_params bonding_defaults;
111 112
112module_param(max_bonds, int, 0); 113module_param(max_bonds, int, 0);
113MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); 114MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
115module_param(tx_queues, int, 0);
116MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)");
114module_param(num_grat_arp, int, 0644); 117module_param(num_grat_arp, int, 0644);
115MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event"); 118MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
116module_param(num_unsol_na, int, 0644); 119module_param(num_unsol_na, int, 0644);
@@ -1540,6 +1543,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1540 goto err_undo_flags; 1543 goto err_undo_flags;
1541 } 1544 }
1542 1545
1546 /*
1547 * Set the new_slave's queue_id to be zero. Queue ID mapping
1548 * is set via sysfs or module option if desired.
1549 */
1550 new_slave->queue_id = 0;
1551
1543 /* Save slave's original mtu and then set it to match the bond */ 1552 /* Save slave's original mtu and then set it to match the bond */
1544 new_slave->original_mtu = slave_dev->mtu; 1553 new_slave->original_mtu = slave_dev->mtu;
1545 res = dev_set_mtu(slave_dev, bond->dev->mtu); 1554 res = dev_set_mtu(slave_dev, bond->dev->mtu);
@@ -3285,6 +3294,7 @@ static void bond_info_show_slave(struct seq_file *seq,
3285 else 3294 else
3286 seq_puts(seq, "Aggregator ID: N/A\n"); 3295 seq_puts(seq, "Aggregator ID: N/A\n");
3287 } 3296 }
3297 seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
3288} 3298}
3289 3299
3290static int bond_info_seq_show(struct seq_file *seq, void *v) 3300static int bond_info_seq_show(struct seq_file *seq, void *v)
@@ -4421,9 +4431,59 @@ static void bond_set_xmit_hash_policy(struct bonding *bond)
4421 } 4431 }
4422} 4432}
4423 4433
4434/*
4435 * Lookup the slave that corresponds to a qid
4436 */
4437static inline int bond_slave_override(struct bonding *bond,
4438 struct sk_buff *skb)
4439{
4440 int i, res = 1;
4441 struct slave *slave = NULL;
4442 struct slave *check_slave;
4443
4444 read_lock(&bond->lock);
4445
4446 if (!BOND_IS_OK(bond) || !skb->queue_mapping)
4447 goto out;
4448
4449 /* Find out if any slaves have the same mapping as this skb. */
4450 bond_for_each_slave(bond, check_slave, i) {
4451 if (check_slave->queue_id == skb->queue_mapping) {
4452 slave = check_slave;
4453 break;
4454 }
4455 }
4456
4457 /* If the slave isn't UP, use default transmit policy. */
4458 if (slave && slave->queue_id && IS_UP(slave->dev) &&
4459 (slave->link == BOND_LINK_UP)) {
4460 res = bond_dev_queue_xmit(bond, skb, slave->dev);
4461 }
4462
4463out:
4464 read_unlock(&bond->lock);
4465 return res;
4466}
4467
4468static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
4469{
4470 /*
4471 * This helper function exists to help dev_pick_tx get the correct
4472 * destination queue. Using a helper function skips the a call to
4473 * skb_tx_hash and will put the skbs in the queue we expect on their
4474 * way down to the bonding driver.
4475 */
4476 return skb->queue_mapping;
4477}
4478
4424static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) 4479static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
4425{ 4480{
4426 const struct bonding *bond = netdev_priv(dev); 4481 struct bonding *bond = netdev_priv(dev);
4482
4483 if (TX_QUEUE_OVERRIDE(bond->params.mode)) {
4484 if (!bond_slave_override(bond, skb))
4485 return NETDEV_TX_OK;
4486 }
4427 4487
4428 switch (bond->params.mode) { 4488 switch (bond->params.mode) {
4429 case BOND_MODE_ROUNDROBIN: 4489 case BOND_MODE_ROUNDROBIN:
@@ -4508,6 +4568,7 @@ static const struct net_device_ops bond_netdev_ops = {
4508 .ndo_open = bond_open, 4568 .ndo_open = bond_open,
4509 .ndo_stop = bond_close, 4569 .ndo_stop = bond_close,
4510 .ndo_start_xmit = bond_start_xmit, 4570 .ndo_start_xmit = bond_start_xmit,
4571 .ndo_select_queue = bond_select_queue,
4511 .ndo_get_stats = bond_get_stats, 4572 .ndo_get_stats = bond_get_stats,
4512 .ndo_do_ioctl = bond_do_ioctl, 4573 .ndo_do_ioctl = bond_do_ioctl,
4513 .ndo_set_multicast_list = bond_set_multicast_list, 4574 .ndo_set_multicast_list = bond_set_multicast_list,
@@ -4776,6 +4837,13 @@ static int bond_check_params(struct bond_params *params)
4776 } 4837 }
4777 } 4838 }
4778 4839
4840 if (tx_queues < 1 || tx_queues > 255) {
4841 pr_warning("Warning: tx_queues (%d) should be between "
4842 "1 and 255, resetting to %d\n",
4843 tx_queues, BOND_DEFAULT_TX_QUEUES);
4844 tx_queues = BOND_DEFAULT_TX_QUEUES;
4845 }
4846
4779 if ((all_slaves_active != 0) && (all_slaves_active != 1)) { 4847 if ((all_slaves_active != 0) && (all_slaves_active != 1)) {
4780 pr_warning("Warning: all_slaves_active module parameter (%d), " 4848 pr_warning("Warning: all_slaves_active module parameter (%d), "
4781 "not of valid value (0/1), so it was set to " 4849 "not of valid value (0/1), so it was set to "
@@ -4953,6 +5021,7 @@ static int bond_check_params(struct bond_params *params)
4953 params->primary[0] = 0; 5021 params->primary[0] = 0;
4954 params->primary_reselect = primary_reselect_value; 5022 params->primary_reselect = primary_reselect_value;
4955 params->fail_over_mac = fail_over_mac_value; 5023 params->fail_over_mac = fail_over_mac_value;
5024 params->tx_queues = tx_queues;
4956 params->all_slaves_active = all_slaves_active; 5025 params->all_slaves_active = all_slaves_active;
4957 5026
4958 if (primary) { 5027 if (primary) {
@@ -5040,8 +5109,8 @@ int bond_create(struct net *net, const char *name)
5040 5109
5041 rtnl_lock(); 5110 rtnl_lock();
5042 5111
5043 bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", 5112 bond_dev = alloc_netdev_mq(sizeof(struct bonding), name ? name : "",
5044 bond_setup); 5113 bond_setup, tx_queues);
5045 if (!bond_dev) { 5114 if (!bond_dev) {
5046 pr_err("%s: eek! can't alloc netdev!\n", name); 5115 pr_err("%s: eek! can't alloc netdev!\n", name);
5047 rtnl_unlock(); 5116 rtnl_unlock();
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 066311a5e084..f9a034361a8e 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1412,6 +1412,121 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d,
1412static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); 1412static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
1413 1413
1414/* 1414/*
1415 * Show the queue_ids of the slaves in the current bond.
1416 */
1417static ssize_t bonding_show_queue_id(struct device *d,
1418 struct device_attribute *attr,
1419 char *buf)
1420{
1421 struct slave *slave;
1422 int i, res = 0;
1423 struct bonding *bond = to_bond(d);
1424
1425 if (!rtnl_trylock())
1426 return restart_syscall();
1427
1428 read_lock(&bond->lock);
1429 bond_for_each_slave(bond, slave, i) {
1430 if (res > (PAGE_SIZE - 6)) {
1431 /* not enough space for another interface name */
1432 if ((PAGE_SIZE - res) > 10)
1433 res = PAGE_SIZE - 10;
1434 res += sprintf(buf + res, "++more++ ");
1435 break;
1436 }
1437 res += sprintf(buf + res, "%s:%d ",
1438 slave->dev->name, slave->queue_id);
1439 }
1440 read_unlock(&bond->lock);
1441 if (res)
1442 buf[res-1] = '\n'; /* eat the leftover space */
1443 rtnl_unlock();
1444 return res;
1445}
1446
1447/*
1448 * Set the queue_ids of the slaves in the current bond. The bond
1449 * interface must be enslaved for this to work.
1450 */
1451static ssize_t bonding_store_queue_id(struct device *d,
1452 struct device_attribute *attr,
1453 const char *buffer, size_t count)
1454{
1455 struct slave *slave, *update_slave;
1456 struct bonding *bond = to_bond(d);
1457 u16 qid;
1458 int i, ret = count;
1459 char *delim;
1460 struct net_device *sdev = NULL;
1461
1462 if (!rtnl_trylock())
1463 return restart_syscall();
1464
1465 /* delim will point to queue id if successful */
1466 delim = strchr(buffer, ':');
1467 if (!delim)
1468 goto err_no_cmd;
1469
1470 /*
1471 * Terminate string that points to device name and bump it
1472 * up one, so we can read the queue id there.
1473 */
1474 *delim = '\0';
1475 if (sscanf(++delim, "%hd\n", &qid) != 1)
1476 goto err_no_cmd;
1477
1478 /* Check buffer length, valid ifname and queue id */
1479 if (strlen(buffer) > IFNAMSIZ ||
1480 !dev_valid_name(buffer) ||
1481 qid > bond->params.tx_queues)
1482 goto err_no_cmd;
1483
1484 /* Get the pointer to that interface if it exists */
1485 sdev = __dev_get_by_name(dev_net(bond->dev), buffer);
1486 if (!sdev)
1487 goto err_no_cmd;
1488
1489 read_lock(&bond->lock);
1490
1491 /* Search for thes slave and check for duplicate qids */
1492 update_slave = NULL;
1493 bond_for_each_slave(bond, slave, i) {
1494 if (sdev == slave->dev)
1495 /*
1496 * We don't need to check the matching
1497 * slave for dups, since we're overwriting it
1498 */
1499 update_slave = slave;
1500 else if (qid && qid == slave->queue_id) {
1501 goto err_no_cmd_unlock;
1502 }
1503 }
1504
1505 if (!update_slave)
1506 goto err_no_cmd_unlock;
1507
1508 /* Actually set the qids for the slave */
1509 update_slave->queue_id = qid;
1510
1511 read_unlock(&bond->lock);
1512out:
1513 rtnl_unlock();
1514 return ret;
1515
1516err_no_cmd_unlock:
1517 read_unlock(&bond->lock);
1518err_no_cmd:
1519 pr_info("invalid input for queue_id set for %s.\n",
1520 bond->dev->name);
1521 ret = -EPERM;
1522 goto out;
1523}
1524
1525static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id,
1526 bonding_store_queue_id);
1527
1528
1529/*
1415 * Show and set the all_slaves_active flag. 1530 * Show and set the all_slaves_active flag.
1416 */ 1531 */
1417static ssize_t bonding_show_slaves_active(struct device *d, 1532static ssize_t bonding_show_slaves_active(struct device *d,
@@ -1489,6 +1604,7 @@ static struct attribute *per_bond_attrs[] = {
1489 &dev_attr_ad_actor_key.attr, 1604 &dev_attr_ad_actor_key.attr,
1490 &dev_attr_ad_partner_key.attr, 1605 &dev_attr_ad_partner_key.attr,
1491 &dev_attr_ad_partner_mac.attr, 1606 &dev_attr_ad_partner_mac.attr,
1607 &dev_attr_queue_id.attr,
1492 &dev_attr_all_slaves_active.attr, 1608 &dev_attr_all_slaves_active.attr,
1493 NULL, 1609 NULL,
1494}; 1610};
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index cecdea2a629f..c6fdd851579a 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -23,8 +23,8 @@
23#include "bond_3ad.h" 23#include "bond_3ad.h"
24#include "bond_alb.h" 24#include "bond_alb.h"
25 25
26#define DRV_VERSION "3.6.0" 26#define DRV_VERSION "3.7.0"
27#define DRV_RELDATE "September 26, 2009" 27#define DRV_RELDATE "June 2, 2010"
28#define DRV_NAME "bonding" 28#define DRV_NAME "bonding"
29#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 29#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
30 30
@@ -60,6 +60,9 @@
60 ((mode) == BOND_MODE_TLB) || \ 60 ((mode) == BOND_MODE_TLB) || \
61 ((mode) == BOND_MODE_ALB)) 61 ((mode) == BOND_MODE_ALB))
62 62
63#define TX_QUEUE_OVERRIDE(mode) \
64 (((mode) == BOND_MODE_ACTIVEBACKUP) || \
65 ((mode) == BOND_MODE_ROUNDROBIN))
63/* 66/*
64 * Less bad way to call ioctl from within the kernel; this needs to be 67 * Less bad way to call ioctl from within the kernel; this needs to be
65 * done some other way to get the call out of interrupt context. 68 * done some other way to get the call out of interrupt context.
@@ -131,6 +134,7 @@ struct bond_params {
131 char primary[IFNAMSIZ]; 134 char primary[IFNAMSIZ];
132 int primary_reselect; 135 int primary_reselect;
133 __be32 arp_targets[BOND_MAX_ARP_TARGETS]; 136 __be32 arp_targets[BOND_MAX_ARP_TARGETS];
137 int tx_queues;
134 int all_slaves_active; 138 int all_slaves_active;
135}; 139};
136 140
@@ -165,6 +169,7 @@ struct slave {
165 u8 perm_hwaddr[ETH_ALEN]; 169 u8 perm_hwaddr[ETH_ALEN];
166 u16 speed; 170 u16 speed;
167 u8 duplex; 171 u8 duplex;
172 u16 queue_id;
168 struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ 173 struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
169 struct tlb_slave_info tlb_info; 174 struct tlb_slave_info tlb_info;
170}; 175};