Commit bca44a73 authored by dingtianhong's avatar dingtianhong Committed by David S. Miller

bonding: protect port for bond_3ad_adapter_duplex_changed()

Jay Vosburgh said that the bond_3ad_adapter_duplex_changed is
called with RTNL only, and the function will modify the port's
information with no further locking, it will not mutex against
bond state machine and incoming LACPDU which do not hold RTNL,
So I add __get_state_machine_lock to protect the port.

But it is not a critical bug, it exist since day one, and till
now it has never been hit and reported, because changes to
speed is very rare, and will not occur critical problem.

The comments in the function is very old, cleanup it.
Suggested-by: default avatarJay Vosburgh <fubar@us.ibm.com>
Signed-off-by: default avatarDing Tianhong <dingtianhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 71a06c59
...@@ -2234,20 +2234,25 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) ...@@ -2234,20 +2234,25 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
port = &(SLAVE_AD_INFO(slave).port); port = &(SLAVE_AD_INFO(slave).port);
// if slave is null, the whole port is not initialized /* if slave is null, the whole port is not initialized */
if (!port->slave) { if (!port->slave) {
pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n", pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n",
slave->bond->dev->name, slave->dev->name); slave->bond->dev->name, slave->dev->name);
return; return;
} }
__get_state_machine_lock(port);
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
port->actor_oper_port_key = port->actor_admin_port_key |= port->actor_oper_port_key = port->actor_admin_port_key |=
__get_duplex(port); __get_duplex(port);
pr_debug("Port %d changed duplex\n", port->actor_port_number); pr_debug("Port %d changed duplex\n", port->actor_port_number);
// there is no need to reselect a new aggregator, just signal the /* there is no need to reselect a new aggregator, just signal the
// state machines to reinitialize * state machines to reinitialize
*/
port->sm_vars |= AD_PORT_BEGIN; port->sm_vars |= AD_PORT_BEGIN;
__release_state_machine_lock(port);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment