aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVeaceslav Falico <vfalico@redhat.com>2014-01-10 05:59:45 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-14 01:22:27 -0500
commit49b7624eda6867d2803bcc5bbf6f25936184304a (patch)
tree8cf62ce9ae669d5587bbc7b9dc8ee504eecaed56
parent768b954922e69a92a363bd4041cb93040ae4e9cf (diff)
bonding: fix __get_active_agg() RCU logic
Currently, the implementation is meaningless - once again, we take the slave structure and use it after we've exited RCU critical section. Fix this by removing the rcu_read_lock() from __get_active_agg(), and ensuring that all its callers are holding RCU. Fixes: be79bd048 ("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.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index b49f421346a7..cce1f1bf90b4 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -678,6 +678,8 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
678/** 678/**
679 * __get_active_agg - get the current active aggregator 679 * __get_active_agg - get the current active aggregator
680 * @aggregator: the aggregator we're looking at 680 * @aggregator: the aggregator we're looking at
681 *
682 * Caller must hold RCU lock.
681 */ 683 */
682static struct aggregator *__get_active_agg(struct aggregator *aggregator) 684static struct aggregator *__get_active_agg(struct aggregator *aggregator)
683{ 685{
@@ -685,13 +687,9 @@ static struct aggregator *__get_active_agg(struct aggregator *aggregator)
685 struct list_head *iter; 687 struct list_head *iter;
686 struct slave *slave; 688 struct slave *slave;
687 689
688 rcu_read_lock();
689 bond_for_each_slave_rcu(bond, slave, iter) 690 bond_for_each_slave_rcu(bond, slave, iter)
690 if (SLAVE_AD_INFO(slave).aggregator.is_active) { 691 if (SLAVE_AD_INFO(slave).aggregator.is_active)
691 rcu_read_unlock();
692 return &(SLAVE_AD_INFO(slave).aggregator); 692 return &(SLAVE_AD_INFO(slave).aggregator);
693 }
694 rcu_read_unlock();
695 693
696 return NULL; 694 return NULL;
697} 695}
@@ -1499,11 +1497,11 @@ static void ad_agg_selection_logic(struct aggregator *agg)
1499 struct slave *slave; 1497 struct slave *slave;
1500 struct port *port; 1498 struct port *port;
1501 1499
1500 rcu_read_lock();
1502 origin = agg; 1501 origin = agg;
1503 active = __get_active_agg(agg); 1502 active = __get_active_agg(agg);
1504 best = (active && agg_device_up(active)) ? active : NULL; 1503 best = (active && agg_device_up(active)) ? active : NULL;
1505 1504
1506 rcu_read_lock();
1507 bond_for_each_slave_rcu(bond, slave, iter) { 1505 bond_for_each_slave_rcu(bond, slave, iter) {
1508 agg = &(SLAVE_AD_INFO(slave).aggregator); 1506 agg = &(SLAVE_AD_INFO(slave).aggregator);
1509 1507