nfsd4: eliminate struct nfs4_cb_recall
[safe/jmp/linux-2.6] / kernel / rcutree.c
index a342b03..d2a372f 100644 (file)
@@ -78,8 +78,31 @@ DEFINE_PER_CPU(struct rcu_data, rcu_data);
 struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
 DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
 
+/*
+ * Increment the quiescent state counter.
+ * The counter is a bit degenerated: We do not need to know
+ * how many quiescent states passed, just if there was at least
+ * one since the start of the grace period. Thus just a flag.
+ */
+void rcu_qsctr_inc(int cpu)
+{
+       struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
+       rdp->passed_quiesc = 1;
+       rdp->passed_quiesc_completed = rdp->completed;
+}
+
+void rcu_bh_qsctr_inc(int cpu)
+{
+       struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
+       rdp->passed_quiesc = 1;
+       rdp->passed_quiesc_completed = rdp->completed;
+}
+
 #ifdef CONFIG_NO_HZ
-DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks);
+DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
+       .dynticks_nesting = 1,
+       .dynticks = 1,
+};
 #endif /* #ifdef CONFIG_NO_HZ */
 
 static int blimit = 10;                /* Maximum callbacks per softirq. */
@@ -507,8 +530,6 @@ static void note_new_gpnum(struct rcu_state *rsp, struct rcu_data *rdp)
        rdp->qs_pending = 1;
        rdp->passed_quiesc = 0;
        rdp->gpnum = rsp->gpnum;
-       rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending +
-                                     RCU_JIFFIES_TILL_FORCE_QS;
 }
 
 /*
@@ -555,8 +576,6 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
        rsp->gpnum++;
        rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */
        rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
-       rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending +
-                                     RCU_JIFFIES_TILL_FORCE_QS;
        record_gp_stall_check_time(rsp);
        dyntick_record_completed(rsp, rsp->completed - 1);
        note_new_gpnum(rsp, rdp);
@@ -572,6 +591,7 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
        /* Special-case the common single-level case. */
        if (NUM_RCU_NODES == 1) {
                rnp->qsmask = rnp->qsmaskinit;
+               rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state OK. */
                spin_unlock_irqrestore(&rnp->lock, flags);
                return;
        }
@@ -944,8 +964,8 @@ static void rcu_do_batch(struct rcu_data *rdp)
 void rcu_check_callbacks(int cpu, int user)
 {
        if (user ||
-           (idle_cpu(cpu) && !in_softirq() &&
-                               hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
+           (idle_cpu(cpu) && rcu_scheduler_active &&
+            !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
 
                /*
                 * Get here if this CPU took its interrupt from user
@@ -1031,7 +1051,6 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
 {
        unsigned long flags;
        long lastcomp;
-       struct rcu_data *rdp = rsp->rda[smp_processor_id()];
        struct rcu_node *rnp = rcu_get_root(rsp);
        u8 signaled;
 
@@ -1042,16 +1061,13 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
                return; /* Someone else is already on the job. */
        }
        if (relaxed &&
-           (long)(rsp->jiffies_force_qs - jiffies) >= 0 &&
-           (rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) >= 0)
+           (long)(rsp->jiffies_force_qs - jiffies) >= 0)
                goto unlock_ret; /* no emergency and done recently. */
        rsp->n_force_qs++;
        spin_lock(&rnp->lock);
        lastcomp = rsp->completed;
        signaled = rsp->signaled;
        rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
-       rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending +
-                                     RCU_JIFFIES_TILL_FORCE_QS;
        if (lastcomp == rsp->gpnum) {
                rsp->n_force_qs_ngp++;
                spin_unlock(&rnp->lock);
@@ -1120,8 +1136,7 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
         * If an RCU GP has gone long enough, go check for dyntick
         * idle CPUs and, if needed, send resched IPIs.
         */
-       if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 ||
-           (rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0)
+       if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)
                force_quiescent_state(rsp, 1);
 
        /*
@@ -1206,8 +1221,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
        if (unlikely(++rdp->qlen > qhimark)) {
                rdp->blimit = LONG_MAX;
                force_quiescent_state(rsp, 0);
-       } else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 ||
-                  (rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0)
+       } else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)
                force_quiescent_state(rsp, 1);
        local_irq_restore(flags);
 }
@@ -1266,8 +1280,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
 
        /* Has an RCU GP gone long enough to send resched IPIs &c? */
        if (ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum) &&
-           ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 ||
-            (rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0))
+           ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0))
                return 1;
 
        /* nothing to do */
@@ -1310,7 +1323,7 @@ int rcu_needs_cpu(int cpu)
  * access due to the fact that this CPU cannot possibly have any RCU
  * callbacks in flight yet.
  */
-static void
+static void __cpuinit
 rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
 {
        unsigned long flags;
@@ -1379,13 +1392,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
 
 static void __cpuinit rcu_online_cpu(int cpu)
 {
-#ifdef CONFIG_NO_HZ
-       struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
-
-       rdtp->dynticks_nesting = 1;
-       rdtp->dynticks |= 1;    /* need consecutive #s even for hotplug. */
-       rdtp->dynticks_nmi = (rdtp->dynticks_nmi + 1) & ~0x1;
-#endif /* #ifdef CONFIG_NO_HZ */
        rcu_init_percpu_data(cpu, &rcu_state);
        rcu_init_percpu_data(cpu, &rcu_bh_state);
        open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);