diff options
| author | Veaceslav Falico <vfalico@redhat.com> | 2014-01-10 05:59:44 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-01-14 01:22:27 -0500 |
| commit | 768b954922e69a92a363bd4041cb93040ae4e9cf (patch) | |
| tree | a6de632160b5525aaebc9e462a7790c1b41d932f | |
| parent | c1bc9644ecd1f663f918d42b33b41a508683b0ee (diff) | |
bonding: fix __get_first_agg RCU usage
Currently, the RCU read lock usage is just wrong - it gets the slave struct
under RCU and continues to use it when RCU lock is released.
However, it's still safe to do this cause we didn't need the
rcu_read_lock() initially - all of the __get_first_agg() callers are either
holding RCU read lock or the RTNL lock, so that we can't sync while in it.
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.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index da0d7c54d352..b49f421346a7 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
| @@ -143,11 +143,13 @@ static inline struct bonding *__get_bond_by_port(struct port *port) | |||
| 143 | * | 143 | * |
| 144 | * Return the aggregator of the first slave in @bond, or %NULL if it can't be | 144 | * Return the aggregator of the first slave in @bond, or %NULL if it can't be |
| 145 | * found. | 145 | * found. |
| 146 | * The caller must hold RCU or RTNL lock. | ||
| 146 | */ | 147 | */ |
| 147 | static inline struct aggregator *__get_first_agg(struct port *port) | 148 | static inline struct aggregator *__get_first_agg(struct port *port) |
| 148 | { | 149 | { |
| 149 | struct bonding *bond = __get_bond_by_port(port); | 150 | struct bonding *bond = __get_bond_by_port(port); |
| 150 | struct slave *first_slave; | 151 | struct slave *first_slave; |
| 152 | struct aggregator *agg; | ||
| 151 | 153 | ||
| 152 | /* If there's no bond for this port, or bond has no slaves */ | 154 | /* If there's no bond for this port, or bond has no slaves */ |
| 153 | if (bond == NULL) | 155 | if (bond == NULL) |
| @@ -155,9 +157,10 @@ static inline struct aggregator *__get_first_agg(struct port *port) | |||
| 155 | 157 | ||
| 156 | rcu_read_lock(); | 158 | rcu_read_lock(); |
| 157 | first_slave = bond_first_slave_rcu(bond); | 159 | first_slave = bond_first_slave_rcu(bond); |
| 160 | agg = first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL; | ||
| 158 | rcu_read_unlock(); | 161 | rcu_read_unlock(); |
| 159 | 162 | ||
| 160 | return first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL; | 163 | return agg; |
| 161 | } | 164 | } |
| 162 | 165 | ||
| 163 | /** | 166 | /** |
