All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pranith Kumar <bobby.prani@gmail.com>
To: paulmck@linux.vnet.ibm.com
Cc: linux-kernel@vger.kernel.org, Josh Triplett <josh@joshtriplett.org>
Subject: Re: [RFC PATCH 1/5] kernel/rcu/tree.c:1272 fix a sparse warning
Date: Fri, 13 Jun 2014 01:52:07 -0400	[thread overview]
Message-ID: <539A9187.9080507@gmail.com> (raw)
In-Reply-To: <539A83F3.2060407@gmail.com>

On 06/13/2014 12:54 AM, Pranith Kumar wrote:
> On 06/12/2014 07:16 PM, Paul E. McKenney wrote:
>> On Wed, Jun 11, 2014 at 04:39:39PM -0400, Pranith Kumar wrote:
>>> kernel/rcu/tree.c:1272:9: warning: context imbalance in 'rcu_start_future_gp' - different lock contexts for basic block
>>>
>>> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
>>> index f1ba773..9ab84d3 100644
>>> --- a/kernel/rcu/tree.c
>>> +++ b/kernel/rcu/tree.c
>>> @@ -1234,49 +1234,54 @@ rcu_start_future_gp(struct rcu_node *rnp, struct rcu_data *rdp,
>>>  	}
>>>
>>>  	/*
>>> -	 * There might be no grace period in progress.  If we don't already
>>> +	 * There is be no grace period in progress.  If we don't already
>>
>> We actually don't know at this point, unless rnp==rnp_root.  Otherwise,
>> the grace period might have started, but initialization might not yet
>> have reached rnp.
> 
> I should have mentioned that I wrote this on top of the previous patch where we
> were checking the root node for presence of a grace period 
> 	ACCESS_ONCE(rnp_root->gpnum) != ACCESS_ONCE(rnp_root->completed)
> 
> But, I realize that even this does not guarantee that a grace period is in
> progress as we do not yet have the lock for the root.
> 
>>
>>>  	 * hold it, acquire the root rcu_node structure's lock in order to
>>> -	 * start one (if needed).
>>> +	 * start one.
>>>  	 */
>>>  	if (rnp != rnp_root) {
>>>  		raw_spin_lock(&rnp_root->lock);
>>>  		smp_mb__after_unlock_lock();
>>
>> I am not convinced that this transformation is correct, especially in
>> the rnp==rnp_root case.  For one thing, I don't see the need for a
>> future grace period being recorded in that case.
>>
>> And I believe that if this transformation is fixed, there will be some
>> duplicate code, which scares me more than sparse false positives.  So I
>> am not willing to take this sort of transformation.  Or am I missing
>> something?
>>
>  
> You are right. I knew I missed something! Even though this started as an
> exercise to remove the sparse warning, I thought I could simplify the function
> since I could see that we are doing some things twice.
> 
> Please find v2 below which takes care of the issues you mentioned. RFC please!
> 

Please find v3 which removes an unnecessary function I introduced.

simplify the function. fix sparse warning as an added bonus :)

Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
---
 kernel/rcu/tree.c | 65 +++++++++++++++++++++++--------------------------------
 1 file changed, 27 insertions(+), 38 deletions(-)

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index f1ba773..639d7a0 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1198,6 +1198,9 @@ static void trace_rcu_future_gp(struct rcu_node *rnp, struct rcu_data *rdp,
  * is reason to awaken the grace-period kthread.
  *
  * The caller must hold the specified rcu_node structure's ->lock.
+ *
+ * This is called recursively at-most twice, once with a rcu_node and a root
+ * rcu_node.
  */
 static bool __maybe_unused
 rcu_start_future_gp(struct rcu_node *rnp, struct rcu_data *rdp,
@@ -1207,29 +1210,31 @@ rcu_start_future_gp(struct rcu_node *rnp, struct rcu_data *rdp,
 	int i;
 	bool ret = false;
 	struct rcu_node *rnp_root = rcu_get_root(rdp->rsp);
+	bool is_root = (rnp_root == rnp);
 
 	/*
 	 * Pick up grace-period number for new callbacks.  If this
 	 * grace period is already marked as needed, return to the caller.
 	 */
 	c = rcu_cbs_completed(rdp->rsp, rnp);
-	trace_rcu_future_gp(rnp, rdp, c, TPS("Startleaf"));
+	trace_rcu_future_gp(rnp, rdp, c, 
+			is_root ? TPS("Startedroot") : TPS("Startleaf"));
 	if (rnp->need_future_gp[c & 0x1]) {
-		trace_rcu_future_gp(rnp, rdp, c, TPS("Prestartleaf"));
+		trace_rcu_future_gp(rnp, rdp, c, 
+				is_root ? TPS("Prestartroot") :	TPS("Prestartleaf"));
 		goto out;
 	}
 
 	/*
-	 * If either this rcu_node structure or the root rcu_node structure
-	 * believe that a grace period is in progress, then we must wait
-	 * for the one following, which is in "c".  Because our request
-	 * will be noticed at the end of the current grace period, we don't
-	 * need to explicitly start one.
+	 * If this rcu_node structure believes that a grace period is in progress,
+	 * then we must wait for the one following, which is in "c".  
+	 * Because our request will be noticed at the end of the current grace
+	 * period, we don't need to explicitly start one.
 	 */
-	if (rnp->gpnum != rnp->completed ||
-	    ACCESS_ONCE(rnp->gpnum) != ACCESS_ONCE(rnp->completed)) {
+	if (rnp->gpnum != rnp->completed) {
 		rnp->need_future_gp[c & 0x1]++;
-		trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleaf"));
+		trace_rcu_future_gp(rnp, rdp, c, 
+			is_root ? TPS("Startedleafroot") : TPS("Startleaf"));
 		goto out;
 	}
 
@@ -1241,41 +1246,25 @@ rcu_start_future_gp(struct rcu_node *rnp, struct rcu_data *rdp,
 	if (rnp != rnp_root) {
 		raw_spin_lock(&rnp_root->lock);
 		smp_mb__after_unlock_lock();
+
+		/*
+		 * Start a new grace period with the root node
+		 */
+		ret = rcu_start_future_gp(rnp_root, rdp, &c);
+		raw_spin_unlock(&rnp_root->lock);
+		goto out;
 	}
 
 	/*
-	 * Get a new grace-period number.  If there really is no grace
-	 * period in progress, it will be smaller than the one we obtained
-	 * earlier.  Adjust callbacks as needed.  Note that even no-CBs
-	 * CPUs have a ->nxtcompleted[] array, so no no-CBs checks needed.
+	 * Adjust callbacks as needed.  Note that even no-CBs CPUs
+	 * have a ->nxtcompleted[] array, so no no-CBs checks needed.
 	 */
-	c = rcu_cbs_completed(rdp->rsp, rnp_root);
 	for (i = RCU_DONE_TAIL; i < RCU_NEXT_TAIL; i++)
 		if (ULONG_CMP_LT(c, rdp->nxtcompleted[i]))
 			rdp->nxtcompleted[i] = c;
-
-	/*
-	 * If the needed for the required grace period is already
-	 * recorded, trace and leave.
-	 */
-	if (rnp_root->need_future_gp[c & 0x1]) {
-		trace_rcu_future_gp(rnp, rdp, c, TPS("Prestartedroot"));
-		goto unlock_out;
-	}
-
-	/* Record the need for the future grace period. */
-	rnp_root->need_future_gp[c & 0x1]++;
-
-	/* If a grace period is not already in progress, start one. */
-	if (rnp_root->gpnum != rnp_root->completed) {
-		trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleafroot"));
-	} else {
-		trace_rcu_future_gp(rnp, rdp, c, TPS("Startedroot"));
-		ret = rcu_start_gp_advanced(rdp->rsp, rnp_root, rdp);
-	}
-unlock_out:
-	if (rnp != rnp_root)
-		raw_spin_unlock(&rnp_root->lock);
+	/* rnp == rnp_root, we already hold the lock */
+	trace_rcu_future_gp(rnp, rdp, c, TPS("Startedroot"));
+	ret = rcu_start_gp_advanced(rdp->rsp, rnp, rdp);
 out:
 	if (c_out != NULL)
 		*c_out = c;
-- 
1.9.1



  reply	other threads:[~2014-06-13  5:52 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-11 20:39 [RFC PATCH 0/5] rcu: fix sparse warnings Pranith Kumar
2014-06-11 20:39 ` [RFC PATCH 1/5] kernel/rcu/tree.c:1272 fix a sparse warning Pranith Kumar
2014-06-12 23:16   ` Paul E. McKenney
2014-06-13  4:54     ` Pranith Kumar
2014-06-13  5:52       ` Pranith Kumar [this message]
2014-06-11 20:39 ` [RFC PATCH 2/5] kernel/rcu/tree_plugin.h:1494 " Pranith Kumar
2014-06-26 19:39   ` Paul E. McKenney
2014-06-11 20:39 ` [RFC PATCH 3/5] kernel/rcu/tree_plugin.h:990 " Pranith Kumar
2014-06-26 19:39   ` Paul E. McKenney
2014-06-11 20:39 ` [RFC PATCH 4/5] kernel/rcu/tree.c:3435 " Pranith Kumar
2014-06-11 21:25   ` josh
2014-06-12  1:37     ` Pranith Kumar
2014-06-11 20:39 ` [RFC PATCH 5/5] kernel/rcu/rcutorture.c:185 " Pranith Kumar
2014-06-11 21:47   ` josh
2014-07-08 22:35     ` Paul E. McKenney
2014-07-08 22:46       ` Pranith Kumar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=539A9187.9080507@gmail.com \
    --to=bobby.prani@gmail.com \
    --cc=josh@joshtriplett.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulmck@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.