diff options
| author | David S. Miller <davem@davemloft.net> | 2015-01-27 20:09:09 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-01-27 20:09:09 -0500 |
| commit | 5094c6f8755407e2d97bfbb4c76fefca3274d3c7 (patch) | |
| tree | 585a12ea9325e14b1b27fd73497873ddbc18d288 | |
| parent | 999028cc1ccd1cd3a1c0104c6423553d3f573197 (diff) | |
| parent | 303691042d2fc996125f479cf01bd5ead8b90a16 (diff) | |
Merge branch 'bonding-next'
Jonathan Toppins says:
====================
bonding: various 802.3ad fixes
This patch series is a forward porting of patches we (Cumulus) are shipping
in our 3.2 series kernels. These fixes attempt to make 802.3ad bonding mode
more predictable in certian state machine transtions in addition to fixing
802.3ad bond carrier determination when bonding min_links option is changed.
Specific notes are contained within each patch.
For this patch series there are no userspace facing changes, a diff between
the modinfo output showed no difference. However, there are behavioral
facing changes, primarily in the bond carrier state. Please make sure to
review carefully.
v2:
* fixed some style issues
* dropped a portion of patch 1 in favor of more testing on my side
====================
Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/bonding/bond_3ad.c | 55 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 6 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_options.c | 1 | ||||
| -rw-r--r-- | include/net/bond_3ad.h | 1 | ||||
| -rw-r--r-- | include/net/bonding.h | 1 |
5 files changed, 47 insertions, 17 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 8baa87df1738..cfc4a9c1000a 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
| @@ -467,11 +467,14 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) | |||
| 467 | /* set the partner sync. to on if the partner is sync, | 467 | /* set the partner sync. to on if the partner is sync, |
| 468 | * and the port is matched | 468 | * and the port is matched |
| 469 | */ | 469 | */ |
| 470 | if ((port->sm_vars & AD_PORT_MATCHED) | 470 | if ((port->sm_vars & AD_PORT_MATCHED) && |
| 471 | && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) | 471 | (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) { |
| 472 | partner->port_state |= AD_STATE_SYNCHRONIZATION; | 472 | partner->port_state |= AD_STATE_SYNCHRONIZATION; |
| 473 | else | 473 | pr_debug("%s partner sync=1\n", port->slave->dev->name); |
| 474 | } else { | ||
| 474 | partner->port_state &= ~AD_STATE_SYNCHRONIZATION; | 475 | partner->port_state &= ~AD_STATE_SYNCHRONIZATION; |
| 476 | pr_debug("%s partner sync=0\n", port->slave->dev->name); | ||
| 477 | } | ||
| 475 | } | 478 | } |
| 476 | } | 479 | } |
| 477 | 480 | ||
| @@ -726,6 +729,8 @@ static inline void __update_lacpdu_from_port(struct port *port) | |||
| 726 | lacpdu->actor_port_priority = htons(port->actor_port_priority); | 729 | lacpdu->actor_port_priority = htons(port->actor_port_priority); |
| 727 | lacpdu->actor_port = htons(port->actor_port_number); | 730 | lacpdu->actor_port = htons(port->actor_port_number); |
| 728 | lacpdu->actor_state = port->actor_oper_port_state; | 731 | lacpdu->actor_state = port->actor_oper_port_state; |
| 732 | pr_debug("update lacpdu: %s, actor port state %x\n", | ||
| 733 | port->slave->dev->name, port->actor_oper_port_state); | ||
| 729 | 734 | ||
| 730 | /* lacpdu->reserved_3_1 initialized | 735 | /* lacpdu->reserved_3_1 initialized |
| 731 | * lacpdu->tlv_type_partner_info initialized | 736 | * lacpdu->tlv_type_partner_info initialized |
| @@ -898,7 +903,9 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) | |||
| 898 | if ((port->sm_vars & AD_PORT_SELECTED) && | 903 | if ((port->sm_vars & AD_PORT_SELECTED) && |
| 899 | (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) && | 904 | (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) && |
| 900 | !__check_agg_selection_timer(port)) { | 905 | !__check_agg_selection_timer(port)) { |
| 901 | port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING; | 906 | if (port->aggregator->is_active) |
| 907 | port->sm_mux_state = | ||
| 908 | AD_MUX_COLLECTING_DISTRIBUTING; | ||
| 902 | } else if (!(port->sm_vars & AD_PORT_SELECTED) || | 909 | } else if (!(port->sm_vars & AD_PORT_SELECTED) || |
| 903 | (port->sm_vars & AD_PORT_STANDBY)) { | 910 | (port->sm_vars & AD_PORT_STANDBY)) { |
| 904 | /* if UNSELECTED or STANDBY */ | 911 | /* if UNSELECTED or STANDBY */ |
| @@ -910,12 +917,16 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) | |||
| 910 | */ | 917 | */ |
| 911 | __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); | 918 | __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); |
| 912 | port->sm_mux_state = AD_MUX_DETACHED; | 919 | port->sm_mux_state = AD_MUX_DETACHED; |
| 920 | } else if (port->aggregator->is_active) { | ||
| 921 | port->actor_oper_port_state |= | ||
| 922 | AD_STATE_SYNCHRONIZATION; | ||
| 913 | } | 923 | } |
| 914 | break; | 924 | break; |
| 915 | case AD_MUX_COLLECTING_DISTRIBUTING: | 925 | case AD_MUX_COLLECTING_DISTRIBUTING: |
| 916 | if (!(port->sm_vars & AD_PORT_SELECTED) || | 926 | if (!(port->sm_vars & AD_PORT_SELECTED) || |
| 917 | (port->sm_vars & AD_PORT_STANDBY) || | 927 | (port->sm_vars & AD_PORT_STANDBY) || |
| 918 | !(port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION)) { | 928 | !(port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) || |
| 929 | !(port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) { | ||
| 919 | port->sm_mux_state = AD_MUX_ATTACHED; | 930 | port->sm_mux_state = AD_MUX_ATTACHED; |
| 920 | } else { | 931 | } else { |
| 921 | /* if port state hasn't changed make | 932 | /* if port state hasn't changed make |
| @@ -937,8 +948,10 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) | |||
| 937 | 948 | ||
| 938 | /* check if the state machine was changed */ | 949 | /* check if the state machine was changed */ |
| 939 | if (port->sm_mux_state != last_state) { | 950 | if (port->sm_mux_state != last_state) { |
| 940 | pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", | 951 | pr_debug("Mux Machine: Port=%d (%s), Last State=%d, Curr State=%d\n", |
| 941 | port->actor_port_number, last_state, | 952 | port->actor_port_number, |
| 953 | port->slave->dev->name, | ||
| 954 | last_state, | ||
| 942 | port->sm_mux_state); | 955 | port->sm_mux_state); |
| 943 | switch (port->sm_mux_state) { | 956 | switch (port->sm_mux_state) { |
| 944 | case AD_MUX_DETACHED: | 957 | case AD_MUX_DETACHED: |
| @@ -953,7 +966,12 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) | |||
| 953 | port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0); | 966 | port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0); |
| 954 | break; | 967 | break; |
| 955 | case AD_MUX_ATTACHED: | 968 | case AD_MUX_ATTACHED: |
| 956 | port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION; | 969 | if (port->aggregator->is_active) |
| 970 | port->actor_oper_port_state |= | ||
| 971 | AD_STATE_SYNCHRONIZATION; | ||
| 972 | else | ||
| 973 | port->actor_oper_port_state &= | ||
| 974 | ~AD_STATE_SYNCHRONIZATION; | ||
| 957 | port->actor_oper_port_state &= ~AD_STATE_COLLECTING; | 975 | port->actor_oper_port_state &= ~AD_STATE_COLLECTING; |
| 958 | port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING; | 976 | port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING; |
| 959 | ad_disable_collecting_distributing(port, | 977 | ad_disable_collecting_distributing(port, |
| @@ -963,6 +981,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) | |||
| 963 | case AD_MUX_COLLECTING_DISTRIBUTING: | 981 | case AD_MUX_COLLECTING_DISTRIBUTING: |
| 964 | port->actor_oper_port_state |= AD_STATE_COLLECTING; | 982 | port->actor_oper_port_state |= AD_STATE_COLLECTING; |
| 965 | port->actor_oper_port_state |= AD_STATE_DISTRIBUTING; | 983 | port->actor_oper_port_state |= AD_STATE_DISTRIBUTING; |
| 984 | port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION; | ||
| 966 | ad_enable_collecting_distributing(port, | 985 | ad_enable_collecting_distributing(port, |
| 967 | update_slave_arr); | 986 | update_slave_arr); |
| 968 | port->ntt = true; | 987 | port->ntt = true; |
| @@ -1044,8 +1063,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
| 1044 | 1063 | ||
| 1045 | /* check if the State machine was changed or new lacpdu arrived */ | 1064 | /* check if the State machine was changed or new lacpdu arrived */ |
| 1046 | if ((port->sm_rx_state != last_state) || (lacpdu)) { | 1065 | if ((port->sm_rx_state != last_state) || (lacpdu)) { |
| 1047 | pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", | 1066 | pr_debug("Rx Machine: Port=%d (%s), Last State=%d, Curr State=%d\n", |
| 1048 | port->actor_port_number, last_state, | 1067 | port->actor_port_number, |
| 1068 | port->slave->dev->name, | ||
| 1069 | last_state, | ||
| 1049 | port->sm_rx_state); | 1070 | port->sm_rx_state); |
| 1050 | switch (port->sm_rx_state) { | 1071 | switch (port->sm_rx_state) { |
| 1051 | case AD_RX_INITIALIZE: | 1072 | case AD_RX_INITIALIZE: |
| @@ -1394,6 +1415,9 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr) | |||
| 1394 | 1415 | ||
| 1395 | aggregator = __get_first_agg(port); | 1416 | aggregator = __get_first_agg(port); |
| 1396 | ad_agg_selection_logic(aggregator, update_slave_arr); | 1417 | ad_agg_selection_logic(aggregator, update_slave_arr); |
| 1418 | |||
| 1419 | if (!port->aggregator->is_active) | ||
| 1420 | port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; | ||
| 1397 | } | 1421 | } |
| 1398 | 1422 | ||
| 1399 | /* Decide if "agg" is a better choice for the new active aggregator that | 1423 | /* Decide if "agg" is a better choice for the new active aggregator that |
| @@ -2195,8 +2219,10 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, | |||
| 2195 | switch (lacpdu->subtype) { | 2219 | switch (lacpdu->subtype) { |
| 2196 | case AD_TYPE_LACPDU: | 2220 | case AD_TYPE_LACPDU: |
| 2197 | ret = RX_HANDLER_CONSUMED; | 2221 | ret = RX_HANDLER_CONSUMED; |
| 2198 | netdev_dbg(slave->bond->dev, "Received LACPDU on port %d\n", | 2222 | netdev_dbg(slave->bond->dev, |
| 2199 | port->actor_port_number); | 2223 | "Received LACPDU on port %d slave %s\n", |
| 2224 | port->actor_port_number, | ||
| 2225 | slave->dev->name); | ||
| 2200 | /* Protect against concurrent state machines */ | 2226 | /* Protect against concurrent state machines */ |
| 2201 | spin_lock(&slave->bond->mode_lock); | 2227 | spin_lock(&slave->bond->mode_lock); |
| 2202 | ad_rx_machine(lacpdu, port); | 2228 | ad_rx_machine(lacpdu, port); |
| @@ -2288,7 +2314,10 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) | |||
| 2288 | port->actor_admin_port_key &= ~AD_DUPLEX_KEY_MASKS; | 2314 | port->actor_admin_port_key &= ~AD_DUPLEX_KEY_MASKS; |
| 2289 | port->actor_oper_port_key = port->actor_admin_port_key |= | 2315 | port->actor_oper_port_key = port->actor_admin_port_key |= |
| 2290 | __get_duplex(port); | 2316 | __get_duplex(port); |
| 2291 | netdev_dbg(slave->bond->dev, "Port %d changed duplex\n", port->actor_port_number); | 2317 | netdev_dbg(slave->bond->dev, "Port %d slave %s changed duplex\n", |
| 2318 | port->actor_port_number, slave->dev->name); | ||
| 2319 | if (port->actor_oper_port_key & AD_DUPLEX_KEY_MASKS) | ||
