|
@@ -1025,9 +1025,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
|
|
|
{
|
|
|
rx_states_t last_state;
|
|
|
|
|
|
- // Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback)
|
|
|
- __get_rx_machine_lock(port);
|
|
|
-
|
|
|
// keep current State Machine state to compare later if it was changed
|
|
|
last_state = port->sm_rx_state;
|
|
|
|
|
@@ -1133,7 +1130,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
|
|
|
pr_err("%s: An illegal loopback occurred on adapter (%s).\n"
|
|
|
"Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
|
|
|
port->slave->dev->master->name, port->slave->dev->name);
|
|
|
- __release_rx_machine_lock(port);
|
|
|
return;
|
|
|
}
|
|
|
__update_selected(lacpdu, port);
|
|
@@ -1153,7 +1149,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- __release_rx_machine_lock(port);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -2155,6 +2150,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
|
|
|
goto re_arm;
|
|
|
}
|
|
|
|
|
|
+ /* Lock around state machines to protect data accessed
|
|
|
+ * by all (e.g., port->sm_vars). ad_rx_machine may run
|
|
|
+ * concurrently due to incoming LACPDU.
|
|
|
+ */
|
|
|
+ __get_rx_machine_lock(port);
|
|
|
+
|
|
|
ad_rx_machine(NULL, port);
|
|
|
ad_periodic_machine(port);
|
|
|
ad_port_selection_logic(port);
|
|
@@ -2164,6 +2165,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
|
|
|
// turn off the BEGIN bit, since we already handled it
|
|
|
if (port->sm_vars & AD_PORT_BEGIN)
|
|
|
port->sm_vars &= ~AD_PORT_BEGIN;
|
|
|
+
|
|
|
+ __release_rx_machine_lock(port);
|
|
|
}
|
|
|
|
|
|
re_arm:
|
|
@@ -2200,7 +2203,10 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
|
|
|
case AD_TYPE_LACPDU:
|
|
|
pr_debug("Received LACPDU on port %d\n",
|
|
|
port->actor_port_number);
|
|
|
+ /* Protect against concurrent state machines */
|
|
|
+ __get_rx_machine_lock(port);
|
|
|
ad_rx_machine(lacpdu, port);
|
|
|
+ __release_rx_machine_lock(port);
|
|
|
break;
|
|
|
|
|
|
case AD_TYPE_MARKER:
|