Neil Horman 38d9b67
commit 7eacd03810960823393521063734fc8188446bca
Neil Horman 38d9b67
Author: Neil Horman <nhorman@tuxdriver.com>
Neil Horman 38d9b67
Date:   Fri Sep 13 11:05:33 2013 -0400
Neil Horman 38d9b67
Neil Horman 38d9b67
    bonding: Make alb learning packet interval configurable
Neil Horman 38d9b67
    
Neil Horman 38d9b67
    running bonding in ALB mode requires that learning packets be sent periodically,
Neil Horman 38d9b67
    so that the switch knows where to send responding traffic.  However, depending
Neil Horman 38d9b67
    on switch configuration, there may not be any need to send traffic at the
Neil Horman 38d9b67
    default rate of 3 packets per second, which represents little more than wasted
Neil Horman 38d9b67
    data.  Allow the ALB learning packet interval to be made configurable via sysfs
Neil Horman 38d9b67
    
Neil Horman 38d9b67
    Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Neil Horman 38d9b67
    Acked-by: Acked-by: Veaceslav Falico <vfalico@redhat.com>
Neil Horman 38d9b67
    CC: Jay Vosburgh <fubar@us.ibm.com>
Neil Horman 38d9b67
    CC: Andy Gospodarek <andy@greyhouse.net>
Neil Horman 38d9b67
    CC: "David S. Miller" <davem@davemloft.net>
Neil Horman 38d9b67
    Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Neil Horman 38d9b67
    Signed-off-by: David S. Miller <davem@davemloft.net>
Neil Horman 38d9b67
Neil Horman 38d9b67
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
Neil Horman 38d9b67
index 87bbcfe..9b28e71 100644
Neil Horman 38d9b67
--- a/Documentation/networking/bonding.txt
Neil Horman 38d9b67
+++ b/Documentation/networking/bonding.txt
Neil Horman 38d9b67
@@ -1362,6 +1362,12 @@ To add ARP targets:
Neil Horman 38d9b67
 To remove an ARP target:
Neil Horman 38d9b67
 # echo -192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target
Neil Horman 38d9b67
 
Neil Horman 38d9b67
+To configure the interval between learning packet transmits:
Neil Horman 38d9b67
+# echo 12 > /sys/class/net/bond0/bonding/lp_interval
Neil Horman 38d9b67
+	NOTE: the lp_inteval is the number of seconds between instances where
Neil Horman 38d9b67
+the bonding driver sends learning packets to each slaves peer switch.  The
Neil Horman 38d9b67
+default interval is 1 second.
Neil Horman 38d9b67
+
Neil Horman 38d9b67
 Example Configuration
Neil Horman 38d9b67
 ---------------------
Neil Horman 38d9b67
 	We begin with the same example that is shown in section 3.3,
Neil Horman 38d9b67
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
Neil Horman 38d9b67
index 91f179d..f428ef57 100644
Neil Horman 38d9b67
--- a/drivers/net/bonding/bond_alb.c
Neil Horman 38d9b67
+++ b/drivers/net/bonding/bond_alb.c
Neil Horman 38d9b67
@@ -1472,7 +1472,7 @@ void bond_alb_monitor(struct work_struct *work)
Neil Horman 38d9b67
 	bond_info->lp_counter++;
Neil Horman 38d9b67
 
Neil Horman 38d9b67
 	/* send learning packets */
Neil Horman 38d9b67
-	if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) {
Neil Horman 38d9b67
+	if (bond_info->lp_counter >= BOND_ALB_LP_TICKS(bond)) {
Neil Horman 38d9b67
 		/* change of curr_active_slave involves swapping of mac addresses.
Neil Horman 38d9b67
 		 * in order to avoid this swapping from happening while
Neil Horman 38d9b67
 		 * sending the learning packets, the curr_slave_lock must be held for
Neil Horman 38d9b67
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
Neil Horman 38d9b67
index 28d8e4c..c5eff5d 100644
Neil Horman 38d9b67
--- a/drivers/net/bonding/bond_alb.h
Neil Horman 38d9b67
+++ b/drivers/net/bonding/bond_alb.h
Neil Horman 38d9b67
@@ -36,14 +36,15 @@ struct slave;
Neil Horman 38d9b67
 					 * Used for division - never set
Neil Horman 38d9b67
 					 * to zero !!!
Neil Horman 38d9b67
 					 */
Neil Horman 38d9b67
-#define BOND_ALB_LP_INTERVAL	    1	/* In seconds, periodic send of
Neil Horman 38d9b67
-					 * learning packets to the switch
Neil Horman 38d9b67
-					 */
Neil Horman 38d9b67
+#define BOND_ALB_DEFAULT_LP_INTERVAL 1
Neil Horman 38d9b67
+#define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval)	/* In seconds, periodic send of
Neil Horman 38d9b67
+								 * learning packets to the switch
Neil Horman 38d9b67
+								 */
Neil Horman 38d9b67
 
Neil Horman 38d9b67
 #define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
Neil Horman 38d9b67
 				  * ALB_TIMER_TICKS_PER_SEC)
Neil Horman 38d9b67
 
Neil Horman 38d9b67
-#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
Neil Horman 38d9b67
+#define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \
Neil Horman 38d9b67
 			   * ALB_TIMER_TICKS_PER_SEC)
Neil Horman 38d9b67
 
Neil Horman 38d9b67
 #define TLB_HASH_TABLE_SIZE 256	/* The size of the clients hash table.
Neil Horman 38d9b67
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
Neil Horman 38d9b67
index 72df399..55bbb8b 100644
Neil Horman 38d9b67
--- a/drivers/net/bonding/bond_main.c
Neil Horman 38d9b67
+++ b/drivers/net/bonding/bond_main.c
Neil Horman 38d9b67
@@ -4416,6 +4416,7 @@ static int bond_check_params(struct bond_params *params)
Neil Horman 38d9b67
 	params->all_slaves_active = all_slaves_active;
Neil Horman 38d9b67
 	params->resend_igmp = resend_igmp;
Neil Horman 38d9b67
 	params->min_links = min_links;
Neil Horman 38d9b67
+	params->lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
Neil Horman 38d9b67
 
Neil Horman 38d9b67
 	if (primary) {
Neil Horman 38d9b67
 		strncpy(params->primary, primary, IFNAMSIZ);
Neil Horman 38d9b67
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
Neil Horman 38d9b67
index eeab40b..c29b836 100644
Neil Horman 38d9b67
--- a/drivers/net/bonding/bond_sysfs.c
Neil Horman 38d9b67
+++ b/drivers/net/bonding/bond_sysfs.c
Neil Horman 38d9b67
@@ -1699,6 +1699,44 @@ out:
Neil Horman 38d9b67
 static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
Neil Horman 38d9b67
 		   bonding_show_resend_igmp, bonding_store_resend_igmp);
Neil Horman 38d9b67
 
Neil Horman 38d9b67
+
Neil Horman 38d9b67
+static ssize_t bonding_show_lp_interval(struct device *d,
Neil Horman 38d9b67
+					struct device_attribute *attr,
Neil Horman 38d9b67
+					char *buf)
Neil Horman 38d9b67
+{
Neil Horman 38d9b67
+	struct bonding *bond = to_bond(d);
Neil Horman 38d9b67
+	return sprintf(buf, "%d\n", bond->params.lp_interval);
Neil Horman 38d9b67
+}
Neil Horman 38d9b67
+
Neil Horman 38d9b67
+static ssize_t bonding_store_lp_interval(struct device *d,
Neil Horman 38d9b67
+					 struct device_attribute *attr,
Neil Horman 38d9b67
+					 const char *buf, size_t count)
Neil Horman 38d9b67
+{
Neil Horman 38d9b67
+	struct bonding *bond = to_bond(d);
Neil Horman 38d9b67
+	int new_value, ret = count;
Neil Horman 38d9b67
+
Neil Horman 38d9b67
+	if (sscanf(buf, "%d", &new_value) != 1) {
Neil Horman 38d9b67
+		pr_err("%s: no lp interval value specified.\n",
Neil Horman 38d9b67
+			bond->dev->name);
Neil Horman 38d9b67
+		ret = -EINVAL;
Neil Horman 38d9b67
+		goto out;
Neil Horman 38d9b67
+	}
Neil Horman 38d9b67
+
Neil Horman 38d9b67
+	if (new_value <= 0) {
Neil Horman 38d9b67
+		pr_err ("%s: lp_interval must be between 1 and %d\n",
Neil Horman 38d9b67
+			bond->dev->name, INT_MAX);
Neil Horman 38d9b67
+		ret = -EINVAL;
Neil Horman 38d9b67
+		goto out;
Neil Horman 38d9b67
+	}
Neil Horman 38d9b67
+
Neil Horman 38d9b67
+	bond->params.lp_interval = new_value;
Neil Horman 38d9b67
+out:
Neil Horman 38d9b67
+	return ret;
Neil Horman 38d9b67
+}
Neil Horman 38d9b67
+
Neil Horman 38d9b67
+static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
Neil Horman 38d9b67
+		   bonding_show_lp_interval, bonding_store_lp_interval);
Neil Horman 38d9b67
+
Neil Horman 38d9b67
 static struct attribute *per_bond_attrs[] = {
Neil Horman 38d9b67
 	&dev_attr_slaves.attr,
Neil Horman 38d9b67
 	&dev_attr_mode.attr,
Neil Horman 38d9b67
@@ -1729,6 +1767,7 @@ static struct attribute *per_bond_attrs[] = {
Neil Horman 38d9b67
 	&dev_attr_all_slaves_active.attr,
Neil Horman 38d9b67
 	&dev_attr_resend_igmp.attr,
Neil Horman 38d9b67
 	&dev_attr_min_links.attr,
Neil Horman 38d9b67
+	&dev_attr_lp_interval.attr,
Neil Horman 38d9b67
 	NULL,
Neil Horman 38d9b67
 };
Neil Horman 38d9b67
 
Neil Horman 38d9b67
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
Neil Horman 38d9b67
index 7ad8bd5..03cf3fd 100644
Neil Horman 38d9b67
--- a/drivers/net/bonding/bonding.h
Neil Horman 38d9b67
+++ b/drivers/net/bonding/bonding.h
Neil Horman 38d9b67
@@ -176,6 +176,7 @@ struct bond_params {
Neil Horman 38d9b67
 	int tx_queues;
Neil Horman 38d9b67
 	int all_slaves_active;
Neil Horman 38d9b67
 	int resend_igmp;
Neil Horman 38d9b67
+	int lp_interval;
Neil Horman 38d9b67
 };
Neil Horman 38d9b67
 
Neil Horman 38d9b67
 struct bond_parm_tbl {