rcu: Correctly unlock root node in rcu_check_gp_start_stall()
authorNeeraj Upadhyay <neeraju@codeaurora.org>
Fri, 29 Mar 2019 11:27:08 +0000 (16:57 +0530)
committerPaul E. McKenney <paulmck@linux.ibm.com>
Tue, 28 May 2019 16:02:57 +0000 (09:02 -0700)
On systems whose rcu_node tree has only one node, the
rcu_check_gp_start_stall() function's values of rnp and rnp_root will
be identical.  In this case, it clearly does not make sense to release
both rnp->lock and rnp_root->lock, but that is exactly what this function
does in the last early exit.  This commit therefore unlocks only rnp->lock
when rnp and rnp_root are equal.

Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org>
Reviewed-by: Mukesh Ojha <mojha@codeaurora.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.ibm.com>
kernel/rcu/tree_stall.h

index f65a73a973235f75268d1553465bdeb6c987da0e..065183391f75979e6bca59184f48e1126670eaad 100644 (file)
@@ -630,7 +630,9 @@ static void rcu_check_gp_start_stall(struct rcu_node *rnp, struct rcu_data *rdp,
            time_before(j, rcu_state.gp_req_activity + gpssdelay) ||
            time_before(j, rcu_state.gp_activity + gpssdelay) ||
            atomic_xchg(&warned, 1)) {
-               raw_spin_unlock_rcu_node(rnp_root); /* irqs remain disabled. */
+               if (rnp_root != rnp)
+                       /* irqs remain disabled. */
+                       raw_spin_unlock_rcu_node(rnp_root);
                raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                return;
        }