aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authordingtianhong <dingtianhong@huawei.com>2013-12-13 04:29:19 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-18 16:52:25 -0500
commit71a06c59d19a57c8dd2972ebee88030f5b0c700e (patch)
treecd55e18def09e35b41e63dd8429beab6dc945dc3 /drivers/net/bonding
parent35eecf052250f663f07a4cded7d3503fd1b50729 (diff)
bonding: protect port for bond_3ad_adapter_speed_changed()
Jay Vosburgh said that the bond_3ad_adapter_speed_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 comment 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>
Diffstat (limited to 'drivers/net/bonding')
-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 187b1b7772ef..6405ce397baf 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2201,20 +2201,25 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
2201 2201
2202 port = &(SLAVE_AD_INFO(slave).port); 2202 port = &(SLAVE_AD_INFO(slave).port);
2203 2203
2204 // if slave is null, the whole port is not initialized 2204 /* if slave is null, the whole port is not initialized */
2205 if (!port->slave) { 2205 if (!port->slave) {
2206 pr_warning("Warning: %s: speed changed for uninitialized port on %s\n", 2206 pr_warning("Warning: %s: speed changed for uninitialized port on %s\n",
2207 slave->bond->dev->name, slave->dev->name); 2207 slave->bond->dev->name, slave->dev->name);
2208 return; 2208 return;
2209 } 2209 }
2210 2210
2211 __get_state_machine_lock(port);
2212
2211 port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; 2213 port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
2212 port->actor_oper_port_key = port->actor_admin_port_key |= 2214 port->actor_oper_port_key = port->actor_admin_port_key |=
2213 (__get_link_speed(port) << 1); 2215 (__get_link_speed(port) << 1);
2214 pr_debug("Port %d changed speed\n", port->actor_port_number); 2216 pr_debug("Port %d changed speed\n", port->actor_port_number);
2215 // there is no need to reselect a new aggregator, just signal the 2217 /* there is no need to reselect a new aggregator, just signal the
2216 // state machines to reinitialize 2218 * state machines to reinitialize
2219 */
2217 port->sm_vars |= AD_PORT_BEGIN; 2220 port->sm_vars |= AD_PORT_BEGIN;
2221
2222 __release_state_machine_lock(port);
2218} 2223}
2219 2224
2220/** 2225/**