diff options
author | Veaceslav Falico <vfalico@redhat.com> | 2014-01-10 05:59:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-14 01:22:27 -0500 |
commit | c1bc9644ecd1f663f918d42b33b41a508683b0ee (patch) | |
tree | d020bd6c841fbd0f368618a3e88db5417d46e3bf | |
parent | 853dc21bfe15f545347b5c82aad02735d552110d (diff) |
bonding: fix bond_3ad_set_carrier() RCU usage
Currently, its usage is just plainly wrong. It first gets a slave under
RCU, and, after releasing the RCU lock, continues to use it - whilst it can
be freed.
Fix this by ensuring that bond_3ad_set_carrier() holds RCU till it uses its
slave (or its agg).
Fixes: be79bd048ab ("bonding: add RCU for bond_3ad_state_machine_handler()")
CC: dingtianhong@huawei.com
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 29db1caee764..da0d7c54d352 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -2327,32 +2327,32 @@ int bond_3ad_set_carrier(struct bonding *bond) | |||
2327 | { | 2327 | { |
2328 | struct aggregator *active; | 2328 | struct aggregator *active; |
2329 | struct slave *first_slave; | 2329 | struct slave *first_slave; |
2330 | int ret = 1; | ||
2330 | 2331 | ||
2331 | rcu_read_lock(); | 2332 | rcu_read_lock(); |
2332 | first_slave = bond_first_slave_rcu(bond); | 2333 | first_slave = bond_first_slave_rcu(bond); |
2333 | rcu_read_unlock(); | 2334 | if (!first_slave) { |
2334 | if (!first_slave) | 2335 | ret = 0; |
2335 | return 0; | 2336 | goto out; |
2337 | } | ||
2336 | active = __get_active_agg(&(SLAVE_AD_INFO(first_slave).aggregator)); | 2338 | active = __get_active_agg(&(SLAVE_AD_INFO(first_slave).aggregator)); |
2337 | if (active) { | 2339 | if (active) { |
2338 | /* are enough slaves available to consider link up? */ | 2340 | /* are enough slaves available to consider link up? */ |
2339 | if (active->num_of_ports < bond->params.min_links) { | 2341 | if (active->num_of_ports < bond->params.min_links) { |
2340 | if (netif_carrier_ok(bond->dev)) { | 2342 | if (netif_carrier_ok(bond->dev)) { |
2341 | netif_carrier_off(bond->dev); | 2343 | netif_carrier_off(bond->dev); |
2342 | return 1; | 2344 | goto out; |
2343 | } | 2345 | } |
2344 | } else if (!netif_carrier_ok(bond->dev)) { | 2346 | } else if (!netif_carrier_ok(bond->dev)) { |
2345 | netif_carrier_on(bond->dev); | 2347 | netif_carrier_on(bond->dev); |
2346 | return 1; | 2348 | goto out; |
2347 | } | 2349 | } |
2348 | return 0; | 2350 | } else if (netif_carrier_ok(bond->dev)) { |
2349 | } | ||
2350 | |||
2351 | if (netif_carrier_ok(bond->dev)) { | ||
2352 | netif_carrier_off(bond->dev); | 2351 | netif_carrier_off(bond->dev); |
2353 | return 1; | ||
2354 | } | 2352 | } |
2355 | return 0; | 2353 | out: |
2354 | rcu_read_unlock(); | ||
2355 | return ret; | ||
2356 | } | 2356 | } |
2357 | 2357 | ||
2358 | /** | 2358 | /** |