aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordingtianhong <dingtianhong@huawei.com>2013-12-13 04:29:24 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-18 16:52:26 -0500
commitbca44a7341924ec92ee7a1ba085c8f0745aeb74e (patch)
tree1435233da672d0cebd94b411023d61b012f57473
parent71a06c59d19a57c8dd2972ebee88030f5b0c700e (diff)
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: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_3ad.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 6405ce397baf..e851a67740f7 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2234,20 +2234,25 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
2234 2234
2235 port = &(SLAVE_AD_INFO(slave).port); 2235 port = &(SLAVE_AD_INFO(slave).port);
2236 2236
2237 // if slave is null, the whole port is not initialized 2237 /* if slave is null, the whole port is not initialized */
2238 if (!port->slave) { 2238 if (!port->slave) {
2239 pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n", 2239 pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n",
2240 slave->bond->dev->name, slave->dev->name); 2240 slave->bond->dev->name, slave->dev->name);
2241 return; 2241 return;
2242 } 2242 }
2243 2243
2244 __get_state_machine_lock(port);
2245
2244 port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; 2246 port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
2245 port->actor_oper_port_key = port->actor_admin_port_key |= 2247 port->actor_oper_port_key = port->actor_admin_port_key |=
2246 __get_duplex(port); 2248 __get_duplex(port);
2247 pr_debug("Port %d changed duplex\n", port->actor_port_number); 2249 pr_debug("Port %d changed duplex\n", port->actor_port_number);
2248 // there is no need to reselect a new aggregator, just signal the 2250 /* there is no need to reselect a new aggregator, just signal the
2249 // state machines to reinitialize 2251 * state machines to reinitialize
2252 */
2250 port->sm_vars |= AD_PORT_BEGIN; 2253 port->sm_vars |= AD_PORT_BEGIN;
2254
2255 __release_state_machine_lock(port);
2251} 2256}
2252 2257
2253/** 2258/**