rcu: fine-tune grace-period begin/end checks
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Fri, 10 Dec 2010 23:02:47 +0000 (15:02 -0800)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Fri, 17 Dec 2010 20:34:20 +0000 (12:34 -0800)
Use the CPU's bit in rnp->qsmask to determine whether or not the CPU
should try to report a quiescent state.  Handle overflow in the check
for rdp->gpnum having fallen behind.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
kernel/rcutree.c

index 8105271..c39ec5b 100644 (file)
@@ -617,9 +617,17 @@ static void __init check_cpu_stall_init(void)
 static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
 {
        if (rdp->gpnum != rnp->gpnum) {
-               rdp->qs_pending = 1;
-               rdp->passed_quiesc = 0;
+               /*
+                * If the current grace period is waiting for this CPU,
+                * set up to detect a quiescent state, otherwise don't
+                * go looking for one.
+                */
                rdp->gpnum = rnp->gpnum;
+               if (rnp->qsmask & rdp->grpmask) {
+                       rdp->qs_pending = 1;
+                       rdp->passed_quiesc = 0;
+               } else
+                       rdp->qs_pending = 0;
        }
 }
 
@@ -681,19 +689,20 @@ __rcu_process_gp_end(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_dat
 
                /*
                 * If we were in an extended quiescent state, we may have
-                * missed some grace periods that others CPUs took care on
+                * missed some grace periods that others CPUs handled on
                 * our behalf. Catch up with this state to avoid noting
-                * spurious new grace periods.
+                * spurious new grace periods.  If another grace period
+                * has started, then rnp->gpnum will have advanced, so
+                * we will detect this later on.
                 */
-               if (rdp->completed > rdp->gpnum)
+               if (ULONG_CMP_LT(rdp->gpnum, rdp->completed))
                        rdp->gpnum = rdp->completed;
 
                /*
-                * If another CPU handled our extended quiescent states and
-                * we have no more grace period to complete yet, then stop
-                * chasing quiescent states.
+                * If RCU does not need a quiescent state from this CPU,
+                * then make sure that this CPU doesn't go looking for one.
                 */
-               if (rdp->completed == rnp->gpnum)
+               if ((rnp->qsmask & rdp->grpmask) == 0)
                        rdp->qs_pending = 0;
        }
 }