diff mbox

[tip/core/urgent] rcu: Stop rcu_do_batch() from multiplexing the "count" variable

Message ID 20120622153738.GA6800@linux.vnet.ibm.com
State Accepted
Commit b41772abebc27c61dd578b76da99aa5240b4c99a
Headers show

Commit Message

Paul E. McKenney June 22, 2012, 3:37 p.m. UTC
Commit b1420f1c (Make rcu_barrier() less disruptive) rearranged the
code in rcu_do_batch(), moving the ->qlen manipulation to follow
the requeueing of the callbacks.  Unfortunately, this rearrangement
clobbered the value of the "count" local variable before the value
of rdp->qlen was adjusted, resulting in the value of rdp->qlen being
inaccurate.  This commit therefore introduces an index variable "i",
avoiding the inadvertent multiplexing.

Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

Comments

Josh Triplett June 22, 2012, 7:52 p.m. UTC | #1
On Fri, Jun 22, 2012 at 08:37:38AM -0700, Paul E. McKenney wrote:
> Commit b1420f1c (Make rcu_barrier() less disruptive) rearranged the
> code in rcu_do_batch(), moving the ->qlen manipulation to follow
> the requeueing of the callbacks.  Unfortunately, this rearrangement
> clobbered the value of the "count" local variable before the value
> of rdp->qlen was adjusted, resulting in the value of rdp->qlen being
> inaccurate.  This commit therefore introduces an index variable "i",
> avoiding the inadvertent multiplexing.
> 
> Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

Reviewed-by: Josh Triplett <josh@joshtriplett.org>

> diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> index 2f34d02..2001d38 100644
> --- a/kernel/rcutree.c
> +++ b/kernel/rcutree.c
> @@ -1593,7 +1593,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
>  {
>  	unsigned long flags;
>  	struct rcu_head *next, *list, **tail;
> -	int bl, count, count_lazy;
> +	int bl, count, count_lazy, i;
>  
>  	/* If no callbacks are ready, just return.*/
>  	if (!cpu_has_callbacks_ready_to_invoke(rdp)) {
> @@ -1616,9 +1616,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
>  	rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
>  	*rdp->nxttail[RCU_DONE_TAIL] = NULL;
>  	tail = rdp->nxttail[RCU_DONE_TAIL];
> -	for (count = RCU_NEXT_SIZE - 1; count >= 0; count--)
> -		if (rdp->nxttail[count] == rdp->nxttail[RCU_DONE_TAIL])
> -			rdp->nxttail[count] = &rdp->nxtlist;
> +	for (i = RCU_NEXT_SIZE - 1; i >= 0; i--)
> +		if (rdp->nxttail[i] == rdp->nxttail[RCU_DONE_TAIL])
> +			rdp->nxttail[i] = &rdp->nxtlist;
>  	local_irq_restore(flags);
>  
>  	/* Invoke callbacks. */
> @@ -1646,9 +1646,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
>  	if (list != NULL) {
>  		*tail = rdp->nxtlist;
>  		rdp->nxtlist = list;
> -		for (count = 0; count < RCU_NEXT_SIZE; count++)
> -			if (&rdp->nxtlist == rdp->nxttail[count])
> -				rdp->nxttail[count] = tail;
> +		for (i = 0; i < RCU_NEXT_SIZE; i++)
> +			if (&rdp->nxtlist == rdp->nxttail[i])
> +				rdp->nxttail[i] = tail;
>  			else
>  				break;
>  	}
>
diff mbox

Patch

diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 2f34d02..2001d38 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1593,7 +1593,7 @@  static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 {
 	unsigned long flags;
 	struct rcu_head *next, *list, **tail;
-	int bl, count, count_lazy;
+	int bl, count, count_lazy, i;
 
 	/* If no callbacks are ready, just return.*/
 	if (!cpu_has_callbacks_ready_to_invoke(rdp)) {
@@ -1616,9 +1616,9 @@  static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 	rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
 	*rdp->nxttail[RCU_DONE_TAIL] = NULL;
 	tail = rdp->nxttail[RCU_DONE_TAIL];
-	for (count = RCU_NEXT_SIZE - 1; count >= 0; count--)
-		if (rdp->nxttail[count] == rdp->nxttail[RCU_DONE_TAIL])
-			rdp->nxttail[count] = &rdp->nxtlist;
+	for (i = RCU_NEXT_SIZE - 1; i >= 0; i--)
+		if (rdp->nxttail[i] == rdp->nxttail[RCU_DONE_TAIL])
+			rdp->nxttail[i] = &rdp->nxtlist;
 	local_irq_restore(flags);
 
 	/* Invoke callbacks. */
@@ -1646,9 +1646,9 @@  static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 	if (list != NULL) {
 		*tail = rdp->nxtlist;
 		rdp->nxtlist = list;
-		for (count = 0; count < RCU_NEXT_SIZE; count++)
-			if (&rdp->nxtlist == rdp->nxttail[count])
-				rdp->nxttail[count] = tail;
+		for (i = 0; i < RCU_NEXT_SIZE; i++)
+			if (&rdp->nxtlist == rdp->nxttail[i])
+				rdp->nxttail[i] = tail;
 			else
 				break;
 	}