diff options
author | Mahesh Bandewar <maheshb@google.com> | 2014-04-22 19:30:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-24 13:04:34 -0400 |
commit | e9f0fb88493570200b8dc1cc02d3e676412d25bc (patch) | |
tree | edd781d8c00772c53e0736a95cf26f0ef2e620dc | |
parent | f05b42eaa22cd7c6736d31316e6046c5127f8721 (diff) |
bonding: Add tlb_dynamic_lb parameter for tlb mode
The aggresive load balancing causes packet re-ordering as active
flows are moved from a slave to another within the group. Sometime
this aggresive lb is not necessary if the preference is for less
re-ordering. This parameter if used with value "0" disables
this dynamic flow shuffling minimizing packet re-ordering. Of course
the side effect is that it has to live with the static load balancing
that the hashing distribution provides. This impact is less severe if
the correct xmit-hashing-policy is used for the tlb setup.
The default value of the parameter is set to "1" mimicing the earlier
behavior.
Ran the netperf test with 200 stream for 1 min between two hosts with
4x1G trunk (xmit-lb mode with xmit-policy L3+4) before and after these
changes. Following was the command used for those 200 instances -
netperf -t TCP_RR -l 60 -s 5 -H <host> -- -r81920,81920
Transactions per second:
Before change: 1,367.11
After change: 1,470.65
Change-Id: Ie3f75c77282cf602e83a6e833c6eb164e72a0990
Signed-off-by: Mahesh Bandewar <maheshb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/networking/bonding.txt | 42 | ||||
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 19 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 4 | ||||
-rw-r--r-- | drivers/net/bonding/bond_options.c | 27 | ||||
-rw-r--r-- | drivers/net/bonding/bond_options.h | 1 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 29 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 1 |
7 files changed, 111 insertions, 12 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index a97c567f24e8..9c723ecd0025 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt | |||
@@ -585,13 +585,19 @@ mode | |||
585 | balance-tlb or 5 | 585 | balance-tlb or 5 |
586 | 586 | ||
587 | Adaptive transmit load balancing: channel bonding that | 587 | Adaptive transmit load balancing: channel bonding that |
588 | does not require any special switch support. The | 588 | does not require any special switch support. |
589 | outgoing traffic is distributed according to the | 589 | |
590 | current load (computed relative to the speed) on each | 590 | In tlb_dynamic_lb=1 mode; the outgoing traffic is |
591 | slave. Incoming traffic is received by the current | 591 | distributed according to the current load (computed |
592 | slave. If the receiving slave fails, another slave | 592 | relative to the speed) on each slave. |
593 | takes over the MAC address of the failed receiving | 593 | |
594 | slave. | 594 | In tlb_dynamic_lb=0 mode; the load balancing based on |
595 | current load is disabled and the load is distributed | ||
596 | only using the hash distribution. | ||
597 | |||
598 | Incoming traffic is received by the current slave. | ||
599 | If the receiving slave fails, another slave takes over | ||
600 | the MAC address of the failed receiving slave. | ||
595 | 601 | ||
596 | Prerequisite: | 602 | Prerequisite: |
597 | 603 | ||
@@ -736,6 +742,28 @@ primary_reselect | |||
736 | 742 | ||
737 | This option was added for bonding version 3.6.0. | 743 | This option was added for bonding version 3.6.0. |
738 | 744 | ||
745 | tlb_dynamic_lb | ||
746 | |||
747 | Specifies if dynamic shuffling of flows is enabled in tlb | ||
748 | mode. The value has no effect on any other modes. | ||
749 | |||
750 | The default behavior of tlb mode is to shuffle active flows across | ||
751 | slaves based on the load in that interval. This gives nice lb | ||
752 | characteristics but can cause packet reordering. If re-ordering is | ||
753 | a concern use this variable to disable flow shuffling and rely on | ||
754 | load balancing provided solely by the hash distribution. | ||
755 | xmit-hash-policy can be used to select the appropriate hashing for | ||
756 | the setup. | ||
757 | |||
758 | The sysfs entry can be used to change the setting per bond device | ||
759 | and the initial value is derived from the module parameter. The | ||
760 | sysfs entry is allowed to be changed only if the bond device is | ||
761 | down. | ||
762 | |||
763 | The default value is "1" that enables flow shuffling while value "0" | ||
764 | disables it. This option was added in bonding driver 3.7.1 | ||
765 | |||
766 | |||
739 | updelay | 767 | updelay |
740 | 768 | ||
741 | Specifies the time, in milliseconds, to wait before enabling a | 769 | Specifies the time, in milliseconds, to wait before enabling a |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 153232ed4b3f..70de039dad2e 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -1356,7 +1356,8 @@ static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond, | |||
1356 | if (!tx_slave) { | 1356 | if (!tx_slave) { |
1357 | /* unbalanced or unassigned, send through primary */ | 1357 | /* unbalanced or unassigned, send through primary */ |
1358 | tx_slave = rcu_dereference(bond->curr_active_slave); | 1358 | tx_slave = rcu_dereference(bond->curr_active_slave); |
1359 | bond_info->unbalanced_load += skb->len; | 1359 | if (bond->params.tlb_dynamic_lb) |
1360 | bond_info->unbalanced_load += skb->len; | ||
1360 | } | 1361 | } |
1361 | 1362 | ||
1362 | if (tx_slave && SLAVE_IS_OK(tx_slave)) { | 1363 | if (tx_slave && SLAVE_IS_OK(tx_slave)) { |
@@ -1369,7 +1370,7 @@ static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond, | |||
1369 | goto out; | 1370 | goto out; |
1370 | } | 1371 | } |
1371 | 1372 | ||
1372 | if (tx_slave) { | 1373 | if (tx_slave && bond->params.tlb_dynamic_lb) { |
1373 | _lock_tx_hashtbl(bond); | 1374 | _lock_tx_hashtbl(bond); |
1374 | __tlb_clear_slave(bond, tx_slave, 0); | 1375 | __tlb_clear_slave(bond, tx_slave, 0); |
1375 | _unlock_tx_hashtbl(bond); | 1376 | _unlock_tx_hashtbl(bond); |
@@ -1399,11 +1400,21 @@ int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1399 | /* In case of IPX, it will falback to L2 hash */ | 1400 | /* In case of IPX, it will falback to L2 hash */ |
1400 | case htons(ETH_P_IPV6): | 1401 | case htons(ETH_P_IPV6): |
1401 | hash_index = bond_xmit_hash(bond, skb); | 1402 | hash_index = bond_xmit_hash(bond, skb); |
1402 | tx_slave = tlb_choose_channel(bond, hash_index & 0xFF, skb->len); | 1403 | if (bond->params.tlb_dynamic_lb) { |
1404 | tx_slave = tlb_choose_channel(bond, | ||
1405 | hash_index & 0xFF, | ||
1406 | skb->len); | ||
1407 | } else { | ||
1408 | struct list_head *iter; | ||
1409 | int idx = hash_index % bond->slave_cnt; | ||
1410 | |||
1411 | bond_for_each_slave_rcu(bond, tx_slave, iter) | ||
1412 | if (--idx < 0) | ||
1413 | break; | ||
1414 | } | ||
1403 | break; | 1415 | break; |
1404 | } | 1416 | } |
1405 | } | 1417 | } |
1406 | |||
1407 | return bond_do_alb_xmit(skb, bond, tx_slave); | 1418 | return bond_do_alb_xmit(skb, bond, tx_slave); |
1408 | } | 1419 | } |
1409 | 1420 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 1fd32a16cbc5..9d08e007d853 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -3096,7 +3096,8 @@ static int bond_open(struct net_device *bond_dev) | |||
3096 | */ | 3096 | */ |
3097 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) | 3097 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) |
3098 | return -ENOMEM; | 3098 | return -ENOMEM; |
3099 | queue_delayed_work(bond->wq, &bond->alb_work, 0); | 3099 | if (bond->params.tlb_dynamic_lb) |
3100 | queue_delayed_work(bond->wq, &bond->alb_work, 0); | ||
3100 | } | 3101 | } |
3101 | 3102 | ||
3102 | if (bond->params.miimon) /* link check interval, in milliseconds. */ | 3103 | if (bond->params.miimon) /* link check interval, in milliseconds. */ |
@@ -4304,6 +4305,7 @@ static int bond_check_params(struct bond_params *params) | |||
4304 | params->min_links = min_links; | 4305 | params->min_links = min_links; |
4305 | params->lp_interval = lp_interval; | 4306 | params->lp_interval = lp_interval; |
4306 | params->packets_per_slave = packets_per_slave; | 4307 | params->packets_per_slave = packets_per_slave; |
4308 | params->tlb_dynamic_lb = 1; /* Default value */ | ||
4307 | if (packets_per_slave > 0) { | 4309 | if (packets_per_slave > 0) { |
4308 | params->reciprocal_packets_per_slave = | 4310 | params->reciprocal_packets_per_slave = |
4309 | reciprocal_value(packets_per_slave); | 4311 | reciprocal_value(packets_per_slave); |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index dc3893841752..9fba7a1e6d51 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
@@ -70,6 +70,8 @@ static int bond_option_mode_set(struct bonding *bond, | |||
70 | const struct bond_opt_value *newval); | 70 | const struct bond_opt_value *newval); |
71 | static int bond_option_slaves_set(struct bonding *bond, | 71 | static int bond_option_slaves_set(struct bonding *bond, |
72 | const struct bond_opt_value *newval); | 72 | const struct bond_opt_value *newval); |
73 | static int bond_option_tlb_dynamic_lb_set(struct bonding *bond, | ||
74 | const struct bond_opt_value *newval); | ||
73 | 75 | ||
74 | 76 | ||
75 | static const struct bond_opt_value bond_mode_tbl[] = { | 77 | static const struct bond_opt_value bond_mode_tbl[] = { |
@@ -179,6 +181,12 @@ static const struct bond_opt_value bond_lp_interval_tbl[] = { | |||
179 | { NULL, -1, 0}, | 181 | { NULL, -1, 0}, |
180 | }; | 182 | }; |
181 | 183 | ||
184 | static const struct bond_opt_value bond_tlb_dynamic_lb_tbl[] = { | ||
185 | { "off", 0, 0}, | ||
186 | { "on", 1, BOND_VALFLAG_DEFAULT}, | ||
187 | { NULL, -1, 0} | ||
188 | }; | ||
189 | |||
182 | static const struct bond_option bond_opts[] = { | 190 | static const struct bond_option bond_opts[] = { |
183 | [BOND_OPT_MODE] = { | 191 | [BOND_OPT_MODE] = { |
184 | .id = BOND_OPT_MODE, | 192 | .id = BOND_OPT_MODE, |
@@ -364,6 +372,15 @@ static const struct bond_option bond_opts[] = { | |||
364 | .flags = BOND_OPTFLAG_RAWVAL, | 372 | .flags = BOND_OPTFLAG_RAWVAL, |
365 | .set = bond_option_slaves_set | 373 | .set = bond_option_slaves_set |
366 | }, | 374 | }, |
375 | [BOND_OPT_TLB_DYNAMIC_LB] = { | ||
376 | .id = BOND_OPT_TLB_DYNAMIC_LB, | ||
377 | .name = "dynamic_lb", | ||
378 | .desc = "Enable dynamic flow shuffling", | ||
379 | .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_TLB)), | ||
380 | .values = bond_tlb_dynamic_lb_tbl, | ||
381 | .flags = BOND_OPTFLAG_IFDOWN, | ||
382 | .set = bond_option_tlb_dynamic_lb_set, | ||
383 | }, | ||
367 | { } | 384 | { } |
368 | }; | 385 | }; |
369 | 386 | ||
@@ -1337,3 +1354,13 @@ err_no_cmd: | |||
1337 | ret = -EPERM; | 1354 | ret = -EPERM; |
1338 | goto out; | 1355 | goto out; |
1339 | } | 1356 | } |
1357 | |||
1358 | static int bond_option_tlb_dynamic_lb_set(struct bonding *bond, | ||
1359 | const struct bond_opt_value *newval) | ||
1360 | { | ||
1361 | pr_info("%s: Setting dynamic-lb to %s (%llu)\n", | ||
1362 | bond->dev->name, newval->string, newval->value); | ||
1363 | bond->params.tlb_dynamic_lb = newval->value; | ||
1364 | |||
1365 | return 0; | ||
1366 | } | ||
diff --git a/drivers/net/bonding/bond_options.h b/drivers/net/bonding/bond_options.h index 12be9e1bfb0c..c1860f06145a 100644 --- a/drivers/net/bonding/bond_options.h +++ b/drivers/net/bonding/bond_options.h | |||
@@ -62,6 +62,7 @@ enum { | |||
62 | BOND_OPT_RESEND_IGMP, | 62 | BOND_OPT_RESEND_IGMP, |
63 | BOND_OPT_LP_INTERVAL, | 63 | BOND_OPT_LP_INTERVAL, |
64 | BOND_OPT_SLAVES, | 64 | BOND_OPT_SLAVES, |
65 | BOND_OPT_TLB_DYNAMIC_LB, | ||
65 | BOND_OPT_LAST | 66 | BOND_OPT_LAST |
66 | }; | 67 | }; |
67 | 68 | ||
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 0e8b268da0a0..431892f1a4ce 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -1039,6 +1039,34 @@ static ssize_t bonding_store_lp_interval(struct device *d, | |||
1039 | static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR, | 1039 | static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR, |
1040 | bonding_show_lp_interval, bonding_store_lp_interval); | 1040 | bonding_show_lp_interval, bonding_store_lp_interval); |
1041 | 1041 | ||
1042 | static ssize_t bonding_show_tlb_dynamic_lb(struct device *d, | ||
1043 | struct device_attribute *attr, | ||
1044 | char *buf) | ||
1045 | { | ||
1046 | struct bonding *bond = to_bond(d); | ||
1047 | return sprintf(buf, "%d\n", bond->params.tlb_dynamic_lb); | ||
1048 | } | ||
1049 | |||
1050 | static ssize_t bonding_store_tlb_dynamic_lb(struct device *d, | ||
1051 | struct device_attribute *attr, | ||
1052 | const char *buf, | ||
1053 | size_t count) | ||
1054 | { | ||
1055 | struct bonding *bond = to_bond(d); | ||
1056 | int ret; | ||
1057 | |||
1058 | ret = bond_opt_tryset_rtnl(bond, BOND_OPT_TLB_DYNAMIC_LB, | ||
1059 | (char *)buf); | ||
1060 | if (!ret) | ||
1061 | ret = count; | ||
1062 | |||
1063 | return ret; | ||
1064 | } | ||
1065 | |||
1066 | static DEVICE_ATTR(tlb_dynamic_lb, S_IRUGO | S_IWUSR, | ||
1067 | bonding_show_tlb_dynamic_lb, | ||
1068 | bonding_store_tlb_dynamic_lb); | ||
1069 | |||
1042 | static ssize_t bonding_show_packets_per_slave(struct device *d, | 1070 | static ssize_t bonding_show_packets_per_slave(struct device *d, |
1043 | struct device_attribute *attr, | 1071 | struct device_attribute *attr, |
1044 | char *buf) | 1072 | char *buf) |
@@ -1099,6 +1127,7 @@ static struct attribute *per_bond_attrs[] = { | |||
1099 | &dev_attr_min_links.attr, | 1127 | &dev_attr_min_links.attr, |
1100 | &dev_attr_lp_interval.attr, | 1128 | &dev_attr_lp_interval.attr, |
1101 | &dev_attr_packets_per_slave.attr, | 1129 | &dev_attr_packets_per_slave.attr, |
1130 | &dev_attr_tlb_dynamic_lb.attr, | ||
1102 | NULL, | 1131 | NULL, |
1103 | }; | 1132 | }; |
1104 | 1133 | ||
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index c0948ca26389..c1c7c2f12ac4 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -174,6 +174,7 @@ struct bond_params { | |||
174 | int resend_igmp; | 174 | int resend_igmp; |
175 | int lp_interval; | 175 | int lp_interval; |
176 | int packets_per_slave; | 176 | int packets_per_slave; |
177 | int tlb_dynamic_lb; | ||
177 | struct reciprocal_value reciprocal_packets_per_slave; | 178 | struct reciprocal_value reciprocal_packets_per_slave; |
178 | }; | 179 | }; |
179 | 180 | ||