All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage
@ 2014-01-09 10:48 Veaceslav Falico
  2014-01-09 10:48 ` [PATCH net-next 1/3] bonding: fix bond_3ad_set_carrier() " Veaceslav Falico
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Veaceslav Falico @ 2014-01-09 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico

While digging through bond_3ad.c I've found that the RCU usage there is
just wrong - it's used as a kind of mutex/spinlock instead of RCU.

This patchset is on top of bond_3ad.c cleanup:
http://www.spinics.net/lists/netdev/msg265447.html

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: netdev@vger.kernel.org
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net-next 1/3] bonding: fix bond_3ad_set_carrier() RCU usage
  2014-01-09 10:48 [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage Veaceslav Falico
@ 2014-01-09 10:48 ` Veaceslav Falico
  2014-01-09 10:48 ` [PATCH net-next 2/3] bonding: fix __get_first_agg " Veaceslav Falico
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Veaceslav Falico @ 2014-01-09 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Veaceslav Falico, dingtianhong, Jay Vosburgh, Andy Gospodarek

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() is either under RCU read
lock or under the RTNL lock (bond_set_carrier() always holds it).

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>
---
 drivers/net/bonding/bond_3ad.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 29db1ca..6330beb 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1597,9 +1597,9 @@ static void ad_agg_selection_logic(struct aggregator *agg)
 		}
 	}
 
-	rcu_read_unlock();
-
 	bond_3ad_set_carrier(bond);
+
+	rcu_read_unlock();
 }
 
 /**
@@ -2322,15 +2322,14 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
  *
  * Called by bond_set_carrier(). Return zero if carrier state does not
  * change, nonzero if it does.
+ * The caller must hold RCU read lock.
  */
 int bond_3ad_set_carrier(struct bonding *bond)
 {
 	struct aggregator *active;
 	struct slave *first_slave;
 
-	rcu_read_lock();
 	first_slave = bond_first_slave_rcu(bond);
-	rcu_read_unlock();
 	if (!first_slave)
 		return 0;
 	active = __get_active_agg(&(SLAVE_AD_INFO(first_slave).aggregator));
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net-next 2/3] bonding: fix __get_first_agg RCU usage
  2014-01-09 10:48 [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage Veaceslav Falico
  2014-01-09 10:48 ` [PATCH net-next 1/3] bonding: fix bond_3ad_set_carrier() " Veaceslav Falico
@ 2014-01-09 10:48 ` Veaceslav Falico
  2014-01-09 10:48 ` [PATCH net-next 3/3] bonding: fix __get_active_agg() RCU logic Veaceslav Falico
  2014-01-09 10:56 ` [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage Veaceslav Falico
  3 siblings, 0 replies; 5+ messages in thread
From: Veaceslav Falico @ 2014-01-09 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Veaceslav Falico, dingtianhong, Jay Vosburgh, Andy Gospodarek

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.

So, remove the useless rcu locking and add a comment.

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>
---
 drivers/net/bonding/bond_3ad.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 6330beb..70e72d7 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -143,6 +143,7 @@ static inline struct bonding *__get_bond_by_port(struct port *port)
  *
  * Return the aggregator of the first slave in @bond, or %NULL if it can't be
  * found.
+ * The caller must either hold RCU or RTNL lock.
  */
 static inline struct aggregator *__get_first_agg(struct port *port)
 {
@@ -153,9 +154,7 @@ static inline struct aggregator *__get_first_agg(struct port *port)
 	if (bond == NULL)
 		return NULL;
 
-	rcu_read_lock();
 	first_slave = bond_first_slave_rcu(bond);
-	rcu_read_unlock();
 
 	return first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL;
 }
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net-next 3/3] bonding: fix __get_active_agg() RCU logic
  2014-01-09 10:48 [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage Veaceslav Falico
  2014-01-09 10:48 ` [PATCH net-next 1/3] bonding: fix bond_3ad_set_carrier() " Veaceslav Falico
  2014-01-09 10:48 ` [PATCH net-next 2/3] bonding: fix __get_first_agg " Veaceslav Falico
@ 2014-01-09 10:48 ` Veaceslav Falico
  2014-01-09 10:56 ` [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage Veaceslav Falico
  3 siblings, 0 replies; 5+ messages in thread
From: Veaceslav Falico @ 2014-01-09 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Veaceslav Falico, dingtianhong, Jay Vosburgh, Andy Gospodarek

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 either RCU or RTNL lock.

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>
---
 drivers/net/bonding/bond_3ad.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 70e72d7..587fd7e 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -674,6 +674,8 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
 /**
  * __get_active_agg - get the current active aggregator
  * @aggregator: the aggregator we're looking at
+ *
+ * Caller must hold either RCU or RTNL lock.
  */
 static struct aggregator *__get_active_agg(struct aggregator *aggregator)
 {
@@ -681,13 +683,9 @@ static struct aggregator *__get_active_agg(struct aggregator *aggregator)
 	struct list_head *iter;
 	struct slave *slave;
 
-	rcu_read_lock();
 	bond_for_each_slave_rcu(bond, slave, iter)
-		if (SLAVE_AD_INFO(slave).aggregator.is_active) {
-			rcu_read_unlock();
+		if (SLAVE_AD_INFO(slave).aggregator.is_active)
 			return &(SLAVE_AD_INFO(slave).aggregator);
-		}
-	rcu_read_unlock();
 
 	return NULL;
 }
@@ -1495,11 +1493,11 @@ static void ad_agg_selection_logic(struct aggregator *agg)
 	struct slave *slave;
 	struct port *port;
 
+	rcu_read_lock();
 	origin = agg;
 	active = __get_active_agg(agg);
 	best = (active && agg_device_up(active)) ? active : NULL;
 
-	rcu_read_lock();
 	bond_for_each_slave_rcu(bond, slave, iter) {
 		agg = &(SLAVE_AD_INFO(slave).aggregator);
 
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage
  2014-01-09 10:48 [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage Veaceslav Falico
                   ` (2 preceding siblings ...)
  2014-01-09 10:48 ` [PATCH net-next 3/3] bonding: fix __get_active_agg() RCU logic Veaceslav Falico
@ 2014-01-09 10:56 ` Veaceslav Falico
  3 siblings, 0 replies; 5+ messages in thread
From: Veaceslav Falico @ 2014-01-09 10:56 UTC (permalink / raw)
  To: netdev; +Cc: Jay Vosburgh, Andy Gospodarek

On Thu, Jan 09, 2014 at 11:48:27AM +0100, Veaceslav Falico wrote:
>While digging through bond_3ad.c I've found that the RCU usage there is
>just wrong - it's used as a kind of mutex/spinlock instead of RCU.
>
>This patchset is on top of bond_3ad.c cleanup:
>http://www.spinics.net/lists/netdev/msg265447.html

Self-NAK, seems like I've missed some locks. Sorry for the noise/early
posting, will post v2 soon.

>
>CC: Jay Vosburgh <fubar@us.ibm.com>
>CC: Andy Gospodarek <andy@greyhouse.net>
>CC: netdev@vger.kernel.org
>Signed-off-by: Veaceslav Falico <vfalico@redhat.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-01-09 11:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-09 10:48 [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage Veaceslav Falico
2014-01-09 10:48 ` [PATCH net-next 1/3] bonding: fix bond_3ad_set_carrier() " Veaceslav Falico
2014-01-09 10:48 ` [PATCH net-next 2/3] bonding: fix __get_first_agg " Veaceslav Falico
2014-01-09 10:48 ` [PATCH net-next 3/3] bonding: fix __get_active_agg() RCU logic Veaceslav Falico
2014-01-09 10:56 ` [PATCH net-next 0/3] bonding: fix bond_3ad RCU usage Veaceslav Falico

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.