aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@redhat.com>2013-11-05 07:51:41 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-07 15:10:21 -0500
commit73958329ea1fe0dc149b51e5d8703015f65a03e0 (patch)
tree149b655cfa917f9239f68dfe0ad3bb55d7ad8a90 /drivers
parent6fb392b1a63ae36c31f62bc3fc8630b49d602b62 (diff)
bonding: extend round-robin mode with packets_per_slave
This patch aims to extend round-robin mode with a new option called packets_per_slave which can have the following values and effects: 0 - choose a random slave 1 (default) - standard round-robin, 1 packet per slave >1 - round-robin when >1 packets have been transmitted per slave The allowed values are between 0 and 65535. This patch also fixes the comment style in bond_xmit_roundrobin(). Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com> Acked-by: Veaceslav Falico <vfalico@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bonding/bond_main.c55
-rw-r--r--drivers/net/bonding/bond_sysfs.c49
-rw-r--r--drivers/net/bonding/bonding.h3
3 files changed, 101 insertions, 6 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a141f406cb98..4dd5ee2a34cc 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -79,6 +79,7 @@
79#include <net/pkt_sched.h> 79#include <net/pkt_sched.h>
80#include <linux/rculist.h> 80#include <linux/rculist.h>
81#include <net/flow_keys.h> 81#include <net/flow_keys.h>
82#include <linux/reciprocal_div.h>
82#include "bonding.h" 83#include "bonding.h"
83#include "bond_3ad.h" 84#include "bond_3ad.h"
84#include "bond_alb.h" 85#include "bond_alb.h"
@@ -111,6 +112,7 @@ static char *fail_over_mac;
111static int all_slaves_active; 112static int all_slaves_active;
112static struct bond_params bonding_defaults; 113static struct bond_params bonding_defaults;
113static int resend_igmp = BOND_DEFAULT_RESEND_IGMP; 114static int resend_igmp = BOND_DEFAULT_RESEND_IGMP;
115static int packets_per_slave = 1;
114 116
115module_param(max_bonds, int, 0); 117module_param(max_bonds, int, 0);
116MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); 118MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -183,6 +185,10 @@ MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface"
183module_param(resend_igmp, int, 0); 185module_param(resend_igmp, int, 0);
184MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on " 186MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on "
185 "link failure"); 187 "link failure");
188module_param(packets_per_slave, int, 0);
189MODULE_PARM_DESC(packets_per_slave, "Packets to send per slave in balance-rr "
190 "mode; 0 for a random slave, 1 packet per "
191 "slave (default), >1 packets per slave.");
186 192
187/*----------------------------- Global variables ----------------------------*/ 193/*----------------------------- Global variables ----------------------------*/
188 194
@@ -3574,14 +3580,44 @@ void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id)
3574 kfree_skb(skb); 3580 kfree_skb(skb);
3575} 3581}
3576 3582
3583/**
3584 * bond_rr_gen_slave_id - generate slave id based on packets_per_slave
3585 * @bond: bonding device to use
3586 *
3587 * Based on the value of the bonding device's packets_per_slave parameter
3588 * this function generates a slave id, which is usually used as the next
3589 * slave to transmit through.
3590 */
3591static u32 bond_rr_gen_slave_id(struct bonding *bond)
3592{
3593 int packets_per_slave = bond->params.packets_per_slave;
3594 u32 slave_id;
3595
3596 switch (packets_per_slave) {
3597 case 0:
3598 slave_id = prandom_u32();
3599 break;
3600 case 1:
3601 slave_id = bond->rr_tx_counter;
3602 break;
3603 default:
3604 slave_id = reciprocal_divide(bond->rr_tx_counter,
3605 packets_per_slave);
3606 break;
3607 }
3608 bond->rr_tx_counter++;
3609
3610 return slave_id;
3611}
3612
3577static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev) 3613static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
3578{ 3614{
3579 struct bonding *bond = netdev_priv(bond_dev); 3615 struct bonding *bond = netdev_priv(bond_dev);
3580 struct iphdr *iph = ip_hdr(skb); 3616 struct iphdr *iph = ip_hdr(skb);
3581 struct slave *slave; 3617 struct slave *slave;
3618 u32 slave_id;
3582 3619
3583 /* 3620 /* Start with the curr_active_slave that joined the bond as the
3584 * Start with the curr_active_slave that joined the bond as the
3585 * default for sending IGMP traffic. For failover purposes one 3621 * default for sending IGMP traffic. For failover purposes one
3586 * needs to maintain some consistency for the interface that will 3622 * needs to maintain some consistency for the interface that will
3587 * send the join/membership reports. The curr_active_slave found 3623 * send the join/membership reports. The curr_active_slave found
@@ -3594,8 +3630,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
3594 else 3630 else
3595 bond_xmit_slave_id(bond, skb, 0); 3631 bond_xmit_slave_id(bond, skb, 0);
3596 } else { 3632 } else {
3597 bond_xmit_slave_id(bond, skb, 3633 slave_id = bond_rr_gen_slave_id(bond);
3598 bond->rr_tx_counter++ % bond->slave_cnt); 3634 bond_xmit_slave_id(bond, skb, slave_id % bond->slave_cnt);
3599 } 3635 }
3600 3636
3601 return NETDEV_TX_OK; 3637 return NETDEV_TX_OK;
@@ -4099,6 +4135,12 @@ static int bond_check_params(struct bond_params *params)
4099 resend_igmp = BOND_DEFAULT_RESEND_IGMP; 4135 resend_igmp = BOND_DEFAULT_RESEND_IGMP;
4100 } 4136 }
4101 4137
4138 if (packets_per_slave < 0 || packets_per_slave > USHRT_MAX) {
4139 pr_warn("Warning: packets_per_slave (%d) should be between 0 and %u resetting to 1\n",
4140 packets_per_slave, USHRT_MAX);
4141 packets_per_slave = 1;
4142 }
4143
4102 /* reset values for TLB/ALB */ 4144 /* reset values for TLB/ALB */
4103 if ((bond_mode == BOND_MODE_TLB) || 4145 if ((bond_mode == BOND_MODE_TLB) ||
4104 (bond_mode == BOND_MODE_ALB)) { 4146 (bond_mode == BOND_MODE_ALB)) {
@@ -4288,7 +4330,10 @@ static int bond_check_params(struct bond_params *params)
4288 params->resend_igmp = resend_igmp; 4330 params->resend_igmp = resend_igmp;
4289 params->min_links = min_links; 4331 params->min_links = min_links;
4290 params->lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL; 4332 params->lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
4291 4333 if (packets_per_slave > 1)
4334 params->packets_per_slave = reciprocal_value(packets_per_slave);
4335 else
4336 params->packets_per_slave = packets_per_slave;
4292 if (primary) { 4337 if (primary) {
4293 strncpy(params->primary, primary, IFNAMSIZ); 4338 strncpy(params->primary, primary, IFNAMSIZ);
4294 params->primary[IFNAMSIZ - 1] = 0; 4339 params->primary[IFNAMSIZ - 1] = 0;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 47749c970a01..75dc4d0efb34 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -40,6 +40,7 @@
40#include <net/net_namespace.h> 40#include <net/net_namespace.h>
41#include <net/netns/generic.h> 41#include <net/netns/generic.h>
42#include <linux/nsproxy.h> 42#include <linux/nsproxy.h>
43#include <linux/reciprocal_div.h>
43 44
44#include "bonding.h" 45#include "bonding.h"
45 46
@@ -1640,6 +1641,53 @@ out:
1640static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR, 1641static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
1641 bonding_show_lp_interval, bonding_store_lp_interval); 1642 bonding_show_lp_interval, bonding_store_lp_interval);
1642 1643
1644static ssize_t bonding_show_packets_per_slave(struct device *d,
1645 struct device_attribute *attr,
1646 char *buf)
1647{
1648 struct bonding *bond = to_bond(d);
1649 int packets_per_slave = bond->params.packets_per_slave;
1650
1651 if (packets_per_slave > 1)
1652 packets_per_slave = reciprocal_value(packets_per_slave);
1653
1654 return sprintf(buf, "%d\n", packets_per_slave);
1655}
1656
1657static ssize_t bonding_store_packets_per_slave(struct device *d,
1658 struct device_attribute *attr,
1659 const char *buf, size_t count)
1660{
1661 struct bonding *bond = to_bond(d);
1662 int new_value, ret = count;
1663
1664 if (sscanf(buf, "%d", &new_value) != 1) {
1665 pr_err("%s: no packets_per_slave value specified.\n",
1666 bond->dev->name);
1667 ret = -EINVAL;
1668 goto out;
1669 }
1670 if (new_value < 0 || new_value > USHRT_MAX) {
1671 pr_err("%s: packets_per_slave must be between 0 and %u\n",
1672 bond->dev->name, USHRT_MAX);
1673 ret = -EINVAL;
1674 goto out;
1675 }
1676 if (bond->params.mode != BOND_MODE_ROUNDROBIN)
1677 pr_warn("%s: Warning: packets_per_slave has effect only in balance-rr mode\n",
1678 bond->dev->name);
1679 if (new_value > 1)
1680 bond->params.packets_per_slave = reciprocal_value(new_value);
1681 else
1682 bond->params.packets_per_slave = new_value;
1683out:
1684 return ret;
1685}
1686
1687static DEVICE_ATTR(packets_per_slave, S_IRUGO | S_IWUSR,
1688 bonding_show_packets_per_slave,
1689 bonding_store_packets_per_slave);
1690
1643static struct attribute *per_bond_attrs[] = { 1691static struct attribute *per_bond_attrs[] = {
1644 &dev_attr_slaves.attr, 1692 &dev_attr_slaves.attr,
1645 &dev_attr_mode.attr, 1693 &dev_attr_mode.attr,
@@ -1671,6 +1719,7 @@ static struct attribute *per_bond_attrs[] = {
1671 &dev_attr_resend_igmp.attr, 1719 &dev_attr_resend_igmp.attr,
1672 &dev_attr_min_links.attr, 1720 &dev_attr_min_links.attr,
1673 &dev_attr_lp_interval.attr, 1721 &dev_attr_lp_interval.attr,
1722 &dev_attr_packets_per_slave.attr,
1674 NULL, 1723 NULL,
1675}; 1724};
1676 1725
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 046a60535e04..77a07a12e77f 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -156,6 +156,7 @@ struct bond_params {
156 int all_slaves_active; 156 int all_slaves_active;
157 int resend_igmp; 157 int resend_igmp;
158 int lp_interval; 158 int lp_interval;
159 int packets_per_slave;
159}; 160};
160 161
161struct bond_parm_tbl { 162struct bond_parm_tbl {
@@ -222,7 +223,7 @@ struct bonding {
222 char proc_file_name[IFNAMSIZ]; 223 char proc_file_name[IFNAMSIZ];
223#endif /* CONFIG_PROC_FS */ 224#endif /* CONFIG_PROC_FS */
224 struct list_head bond_list; 225 struct list_head bond_list;
225 u16 rr_tx_counter; 226 u32 rr_tx_counter;
226 struct ad_bond_info ad_info; 227 struct ad_bond_info ad_info;
227 struct alb_bond_info alb_info; 228 struct alb_bond_info alb_info;
228 struct bond_params params; 229 struct bond_params params;