rcu: Print scheduling-clock information on RCU CPU stall-warning messages
[deliverable/linux.git] / kernel / rcutree.c
index 6c4a6722abfd2fc7297da3e93e6789b94edb6de0..dccd2f78db4e107fb5f22be624c1cb38ba3d0ffb 100644 (file)
@@ -208,8 +208,11 @@ module_param(blimit, int, 0);
 module_param(qhimark, int, 0);
 module_param(qlowmark, int, 0);
 
-int rcu_cpu_stall_suppress __read_mostly;
+int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */
+int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
+
 module_param(rcu_cpu_stall_suppress, int, 0644);
+module_param(rcu_cpu_stall_timeout, int, 0644);
 
 static void force_quiescent_state(struct rcu_state *rsp, int relaxed);
 static int rcu_pending(int cpu);
@@ -301,8 +304,6 @@ static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
        return &rsp->node[0];
 }
 
-#ifdef CONFIG_SMP
-
 /*
  * If the specified CPU is offline, tell the caller that it is in
  * a quiescent state.  Otherwise, whack it with a reschedule IPI.
@@ -339,8 +340,6 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
        return 0;
 }
 
-#endif /* #ifdef CONFIG_SMP */
-
 /*
  * rcu_idle_enter_common - inform RCU that current CPU is moving towards idle
  *
@@ -366,6 +365,17 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
        atomic_inc(&rdtp->dynticks);
        smp_mb__after_atomic_inc();  /* Force ordering with next sojourn. */
        WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
+
+       /*
+        * The idle task is not permitted to enter the idle loop while
+        * in an RCU read-side critical section.
+        */
+       rcu_lockdep_assert(!lock_is_held(&rcu_lock_map),
+                          "Illegal idle entry in RCU read-side critical section.");
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map),
+                          "Illegal idle entry in RCU-bh read-side critical section.");
+       rcu_lockdep_assert(!lock_is_held(&rcu_sched_lock_map),
+                          "Illegal idle entry in RCU-sched read-side critical section.");
 }
 
 /**
@@ -595,8 +605,6 @@ int rcu_is_cpu_rrupt_from_idle(void)
        return __get_cpu_var(rcu_dynticks).dynticks_nesting <= 1;
 }
 
-#ifdef CONFIG_SMP
-
 /*
  * Snapshot the specified CPU's dynticks counter so that we can later
  * credit them with an implicit quiescent state.  Return 1 if this CPU
@@ -640,12 +648,28 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
        return rcu_implicit_offline_qs(rdp);
 }
 
-#endif /* #ifdef CONFIG_SMP */
+static int jiffies_till_stall_check(void)
+{
+       int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout);
+
+       /*
+        * Limit check must be consistent with the Kconfig limits
+        * for CONFIG_RCU_CPU_STALL_TIMEOUT.
+        */
+       if (till_stall_check < 3) {
+               ACCESS_ONCE(rcu_cpu_stall_timeout) = 3;
+               till_stall_check = 3;
+       } else if (till_stall_check > 300) {
+               ACCESS_ONCE(rcu_cpu_stall_timeout) = 300;
+               till_stall_check = 300;
+       }
+       return till_stall_check * HZ + RCU_STALL_DELAY_DELTA;
+}
 
 static void record_gp_stall_check_time(struct rcu_state *rsp)
 {
        rsp->gp_start = jiffies;
-       rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_CHECK;
+       rsp->jiffies_stall = jiffies + jiffies_till_stall_check();
 }
 
 static void print_other_cpu_stall(struct rcu_state *rsp)
@@ -664,13 +688,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
                raw_spin_unlock_irqrestore(&rnp->lock, flags);
                return;
        }
-       rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_RECHECK;
-
-       /*
-        * Now rat on any tasks that got kicked up to the root rcu_node
-        * due to CPU offlining.
-        */
-       ndetected = rcu_print_task_stall(rnp);
+       rsp->jiffies_stall = jiffies + 3 * jiffies_till_stall_check() + 3;
        raw_spin_unlock_irqrestore(&rnp->lock, flags);
 
        /*
@@ -678,8 +696,9 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
         * See Documentation/RCU/stallwarn.txt for info on how to debug
         * RCU CPU stall warnings.
         */
-       printk(KERN_ERR "INFO: %s detected stalls on CPUs/tasks: {",
+       printk(KERN_ERR "INFO: %s detected stalls on CPUs/tasks:",
               rsp->name);
+       print_cpu_stall_info_begin();
        rcu_for_each_leaf_node(rsp, rnp) {
                raw_spin_lock_irqsave(&rnp->lock, flags);
                ndetected += rcu_print_task_stall(rnp);
@@ -688,11 +707,22 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
                        continue;
                for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
                        if (rnp->qsmask & (1UL << cpu)) {
-                               printk(" %d", rnp->grplo + cpu);
+                               print_cpu_stall_info(rsp, rnp->grplo + cpu);
                                ndetected++;
                        }
        }
-       printk("} (detected by %d, t=%ld jiffies)\n",
+
+       /*
+        * Now rat on any tasks that got kicked up to the root rcu_node
+        * due to CPU offlining.
+        */
+       rnp = rcu_get_root(rsp);
+       raw_spin_lock_irqsave(&rnp->lock, flags);
+       ndetected = rcu_print_task_stall(rnp);
+       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+
+       print_cpu_stall_info_end();
+       printk(KERN_CONT "(detected by %d, t=%ld jiffies)\n",
               smp_processor_id(), (long)(jiffies - rsp->gp_start));
        if (ndetected == 0)
                printk(KERN_ERR "INFO: Stall ended before state dump start\n");
@@ -716,15 +746,18 @@ static void print_cpu_stall(struct rcu_state *rsp)
         * See Documentation/RCU/stallwarn.txt for info on how to debug
         * RCU CPU stall warnings.
         */
-       printk(KERN_ERR "INFO: %s detected stall on CPU %d (t=%lu jiffies)\n",
-              rsp->name, smp_processor_id(), jiffies - rsp->gp_start);
+       printk(KERN_ERR "INFO: %s self-detected stall on CPU", rsp->name);
+       print_cpu_stall_info_begin();
+       print_cpu_stall_info(rsp, smp_processor_id());
+       print_cpu_stall_info_end();
+       printk(KERN_CONT " (t=%lu jiffies)\n", jiffies - rsp->gp_start);
        if (!trigger_all_cpu_backtrace())
                dump_stack();
 
        raw_spin_lock_irqsave(&rnp->lock, flags);
        if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall))
-               rsp->jiffies_stall =
-                       jiffies + RCU_SECONDS_TILL_STALL_RECHECK;
+               rsp->jiffies_stall = jiffies +
+                                    3 * jiffies_till_stall_check() + 3;
        raw_spin_unlock_irqrestore(&rnp->lock, flags);
 
        set_need_resched();  /* kick ourselves to get things going. */
@@ -807,6 +840,7 @@ static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct
                        rdp->passed_quiesce = 0;
                } else
                        rdp->qs_pending = 0;
+               zero_cpu_stall_ticks(rdp);
        }
 }
 
@@ -943,6 +977,10 @@ rcu_start_gp_per_cpu(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_dat
  * in preparation for detecting the next grace period.  The caller must hold
  * the root node's ->lock, which is released before return.  Hard irqs must
  * be disabled.
+ *
+ * Note that it is legal for a dying CPU (which is marked as offline) to
+ * invoke this function.  This can happen when the dying CPU reports its
+ * quiescent state.
  */
 static void
 rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
@@ -980,26 +1018,8 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
        rsp->fqs_state = RCU_GP_INIT; /* Hold off force_quiescent_state. */
        rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
        record_gp_stall_check_time(rsp);
-
-       /* Special-case the common single-level case. */
-       if (NUM_RCU_NODES == 1) {
-               rcu_preempt_check_blocked_tasks(rnp);
-               rnp->qsmask = rnp->qsmaskinit;
-               rnp->gpnum = rsp->gpnum;
-               rnp->completed = rsp->completed;
-               rsp->fqs_state = RCU_SIGNAL_INIT; /* force_quiescent_state OK */
-               rcu_start_gp_per_cpu(rsp, rnp, rdp);
-               rcu_preempt_boost_start_gp(rnp);
-               trace_rcu_grace_period_init(rsp->name, rnp->gpnum,
-                                           rnp->level, rnp->grplo,
-                                           rnp->grphi, rnp->qsmask);
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               return;
-       }
-
        raw_spin_unlock(&rnp->lock);  /* leave irqs disabled. */
 
-
        /* Exclude any concurrent CPU-hotplug operations. */
        raw_spin_lock(&rsp->onofflock);  /* irqs already disabled. */
 
@@ -1245,116 +1265,141 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
 
 /*
  * Move a dying CPU's RCU callbacks to online CPU's callback list.
- * Synchronization is not required because this function executes
- * in stop_machine() context.
+ * Also record a quiescent state for this CPU for the current grace period.
+ * Synchronization and interrupt disabling are not required because
+ * this function executes in stop_machine() context.  Therefore, cleanup
+ * operations that might block must be done later from the CPU_DEAD
+ * notifier.
+ *
+ * Note that the outgoing CPU's bit has already been cleared in the
+ * cpu_online_mask.  This allows us to randomly pick a callback
+ * destination from the bits set in that mask.
  */
-static void rcu_send_cbs_to_online(struct rcu_state *rsp)
+static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
 {
+       unsigned long flags;
        int i;
-       /* current DYING CPU is cleared in the cpu_online_mask */
+       unsigned long mask;
+       int need_report;
        int receive_cpu = cpumask_any(cpu_online_mask);
        struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
        struct rcu_data *receive_rdp = per_cpu_ptr(rsp->rda, receive_cpu);
+       struct rcu_node *rnp = rdp->mynode; /* For dying CPU. */
+
+       /* First, adjust the counts. */
+       if (rdp->nxtlist != NULL) {
+               receive_rdp->qlen_lazy += rdp->qlen_lazy;
+               receive_rdp->qlen += rdp->qlen;
+               rdp->qlen_lazy = 0;
+               rdp->qlen = 0;
+       }
 
-       if (rdp->nxtlist == NULL)
-               return;  /* irqs disabled, so comparison is stable. */
-
-       *receive_rdp->nxttail[RCU_NEXT_TAIL] = rdp->nxtlist;
-       receive_rdp->nxttail[RCU_NEXT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
-       receive_rdp->qlen += rdp->qlen;
-       receive_rdp->n_cbs_adopted += rdp->qlen;
-       rdp->n_cbs_orphaned += rdp->qlen;
-
-       rdp->nxtlist = NULL;
-       for (i = 0; i < RCU_NEXT_SIZE; i++)
-               rdp->nxttail[i] = &rdp->nxtlist;
-       rdp->qlen = 0;
-}
-
-/*
- * Remove the outgoing CPU from the bitmasks in the rcu_node hierarchy
- * and move all callbacks from the outgoing CPU to the current one.
- * There can only be one CPU hotplug operation at a time, so no other
- * CPU can be attempting to update rcu_cpu_kthread_task.
- */
-static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
-{
-       unsigned long flags;
-       unsigned long mask;
-       int need_report = 0;
-       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
-       struct rcu_node *rnp;
-
-       rcu_stop_cpu_kthread(cpu);
+       /*
+        * Next, move ready-to-invoke callbacks to be invoked on some
+        * other CPU.  These will not be required to pass through another
+        * grace period:  They are done, regardless of CPU.
+        */
+       if (rdp->nxtlist != NULL &&
+           rdp->nxttail[RCU_DONE_TAIL] != &rdp->nxtlist) {
+               struct rcu_head *oldhead;
+               struct rcu_head **oldtail;
+               struct rcu_head **newtail;
+
+               oldhead = rdp->nxtlist;
+               oldtail = receive_rdp->nxttail[RCU_DONE_TAIL];
+               rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
+               *rdp->nxttail[RCU_DONE_TAIL] = *oldtail;
+               *receive_rdp->nxttail[RCU_DONE_TAIL] = oldhead;
+               newtail = rdp->nxttail[RCU_DONE_TAIL];
+               for (i = RCU_DONE_TAIL; i < RCU_NEXT_SIZE; i++) {
+                       if (receive_rdp->nxttail[i] == oldtail)
+                               receive_rdp->nxttail[i] = newtail;
+                       if (rdp->nxttail[i] == newtail)
+                               rdp->nxttail[i] = &rdp->nxtlist;
+               }
+       }
 
-       /* Exclude any attempts to start a new grace period. */
-       raw_spin_lock_irqsave(&rsp->onofflock, flags);
+       /*
+        * Finally, put the rest of the callbacks at the end of the list.
+        * The ones that made it partway through get to start over:  We
+        * cannot assume that grace periods are synchronized across CPUs.
+        * (We could splice RCU_WAIT_TAIL into RCU_NEXT_READY_TAIL, but
+        * this does not seem compelling.  Not yet, anyway.)
+        */
+       if (rdp->nxtlist != NULL) {
+               *receive_rdp->nxttail[RCU_NEXT_TAIL] = rdp->nxtlist;
+               receive_rdp->nxttail[RCU_NEXT_TAIL] =
+                               rdp->nxttail[RCU_NEXT_TAIL];
+               receive_rdp->n_cbs_adopted += rdp->qlen;
+               rdp->n_cbs_orphaned += rdp->qlen;
+
+               rdp->nxtlist = NULL;
+               for (i = 0; i < RCU_NEXT_SIZE; i++)
+                       rdp->nxttail[i] = &rdp->nxtlist;
+       }
 
-       /* Remove the outgoing CPU from the masks in the rcu_node hierarchy. */
-       rnp = rdp->mynode;      /* this is the outgoing CPU's rnp. */
+       /*
+        * Record a quiescent state for the dying CPU.  This is safe
+        * only because we have already cleared out the callbacks.
+        * (Otherwise, the RCU core might try to schedule the invocation
+        * of callbacks on this now-offline CPU, which would be bad.)
+        */
        mask = rdp->grpmask;    /* rnp->grplo is constant. */
+       trace_rcu_grace_period(rsp->name,
+                              rnp->gpnum + 1 - !!(rnp->qsmask & mask),
+                              "cpuofl");
+       rcu_report_qs_rdp(smp_processor_id(), rsp, rdp, rsp->gpnum);
+       /* Note that rcu_report_qs_rdp() might call trace_rcu_grace_period(). */
+
+       /*
+        * Remove the dying CPU from the bitmasks in the rcu_node
+        * hierarchy.  Because we are in stop_machine() context, we
+        * automatically exclude ->onofflock critical sections.
+        */
        do {
-               raw_spin_lock(&rnp->lock);      /* irqs already disabled. */
+               raw_spin_lock_irqsave(&rnp->lock, flags);
                rnp->qsmaskinit &= ~mask;
                if (rnp->qsmaskinit != 0) {
-                       if (rnp != rdp->mynode)
-                               raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
-                       else
-                               trace_rcu_grace_period(rsp->name,
-                                                      rnp->gpnum + 1 -
-                                                      !!(rnp->qsmask & mask),
-                                                      "cpuofl");
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
                        break;
                }
                if (rnp == rdp->mynode) {
-                       trace_rcu_grace_period(rsp->name,
-                                              rnp->gpnum + 1 -
-                                              !!(rnp->qsmask & mask),
-                                              "cpuofl");
                        need_report = rcu_preempt_offline_tasks(rsp, rnp, rdp);
+                       if (need_report & RCU_OFL_TASKS_NORM_GP)
+                               rcu_report_unblock_qs_rnp(rnp, flags);
+                       else
+                               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       if (need_report & RCU_OFL_TASKS_EXP_GP)
+                               rcu_report_exp_rnp(rsp, rnp, true);
                } else
-                       raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
                mask = rnp->grpmask;
                rnp = rnp->parent;
        } while (rnp != NULL);
-
-       /*
-        * We still hold the leaf rcu_node structure lock here, and
-        * irqs are still disabled.  The reason for this subterfuge is
-        * because invoking rcu_report_unblock_qs_rnp() with ->onofflock
-        * held leads to deadlock.
-        */
-       raw_spin_unlock(&rsp->onofflock); /* irqs remain disabled. */
-       rnp = rdp->mynode;
-       if (need_report & RCU_OFL_TASKS_NORM_GP)
-               rcu_report_unblock_qs_rnp(rnp, flags);
-       else
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
-       if (need_report & RCU_OFL_TASKS_EXP_GP)
-               rcu_report_exp_rnp(rsp, rnp, true);
-       rcu_node_kthread_setaffinity(rnp, -1);
 }
 
 /*
- * Remove the specified CPU from the RCU hierarchy and move any pending
- * callbacks that it might have to the current CPU.  This code assumes
- * that at least one CPU in the system will remain running at all times.
- * Any attempt to offline -all- CPUs is likely to strand RCU callbacks.
+ * The CPU has been completely removed, and some other CPU is reporting
+ * this fact from process context.  Do the remainder of the cleanup.
+ * There can only be one CPU hotplug operation at a time, so no other
+ * CPU can be attempting to update rcu_cpu_kthread_task.
  */
-static void rcu_offline_cpu(int cpu)
+static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
 {
-       __rcu_offline_cpu(cpu, &rcu_sched_state);
-       __rcu_offline_cpu(cpu, &rcu_bh_state);
-       rcu_preempt_offline_cpu(cpu);
+       struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
+       struct rcu_node *rnp = rdp->mynode;
+
+       rcu_stop_cpu_kthread(cpu);
+       rcu_node_kthread_setaffinity(rnp, -1);
 }
 
 #else /* #ifdef CONFIG_HOTPLUG_CPU */
 
-static void rcu_send_cbs_to_online(struct rcu_state *rsp)
+static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
 {
 }
 
-static void rcu_offline_cpu(int cpu)
+static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
 {
 }
 
@@ -1368,11 +1413,11 @@ 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;
+       int bl, count, count_lazy;
 
        /* If no callbacks are ready, just return.*/
        if (!cpu_has_callbacks_ready_to_invoke(rdp)) {
-               trace_rcu_batch_start(rsp->name, 0, 0);
+               trace_rcu_batch_start(rsp->name, rdp->qlen_lazy, rdp->qlen, 0);
                trace_rcu_batch_end(rsp->name, 0, !!ACCESS_ONCE(rdp->nxtlist),
                                    need_resched(), is_idle_task(current),
                                    rcu_is_callbacks_kthread());
@@ -1384,8 +1429,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
         * races with call_rcu() from interrupt handlers.
         */
        local_irq_save(flags);
+       WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
        bl = rdp->blimit;
-       trace_rcu_batch_start(rsp->name, rdp->qlen, bl);
+       trace_rcu_batch_start(rsp->name, rdp->qlen_lazy, rdp->qlen, bl);
        list = rdp->nxtlist;
        rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
        *rdp->nxttail[RCU_DONE_TAIL] = NULL;
@@ -1396,12 +1442,13 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
        local_irq_restore(flags);
 
        /* Invoke callbacks. */
-       count = 0;
+       count = count_lazy = 0;
        while (list) {
                next = list->next;
                prefetch(next);
                debug_rcu_head_unqueue(list);
-               __rcu_reclaim(rsp->name, list);
+               if (__rcu_reclaim(rsp->name, list))
+                       count_lazy++;
                list = next;
                /* Stop only if limit reached and CPU has something to do. */
                if (++count >= bl &&
@@ -1416,6 +1463,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
                            rcu_is_callbacks_kthread());
 
        /* Update count, and requeue any remaining callbacks. */
+       rdp->qlen_lazy -= count_lazy;
        rdp->qlen -= count;
        rdp->n_cbs_invoked += count;
        if (list != NULL) {
@@ -1458,6 +1506,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 void rcu_check_callbacks(int cpu, int user)
 {
        trace_rcu_utilization("Start scheduler-tick");
+       increment_cpu_stall_ticks();
        if (user || rcu_is_cpu_rrupt_from_idle()) {
 
                /*
@@ -1492,8 +1541,6 @@ void rcu_check_callbacks(int cpu, int user)
        trace_rcu_utilization("End scheduler-tick");
 }
 
-#ifdef CONFIG_SMP
-
 /*
  * Scan the leaf rcu_node structures, processing dyntick state for any that
  * have not yet encountered a quiescent state, using the function specified.
@@ -1616,15 +1663,6 @@ unlock_fqs_ret:
        trace_rcu_utilization("End fqs");
 }
 
-#else /* #ifdef CONFIG_SMP */
-
-static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
-{
-       set_need_resched();
-}
-
-#endif /* #else #ifdef CONFIG_SMP */
-
 /*
  * This does the RCU core processing work for the specified rcu_state
  * and rcu_data structures.  This may be called only from the CPU to
@@ -1702,11 +1740,12 @@ static void invoke_rcu_core(void)
 
 static void
 __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
-          struct rcu_state *rsp)
+          struct rcu_state *rsp, bool lazy)
 {
        unsigned long flags;
        struct rcu_data *rdp;
 
+       WARN_ON_ONCE((unsigned long)head & 0x3); /* Misaligned rcu_head! */
        debug_rcu_head_queue(head);
        head->func = func;
        head->next = NULL;
@@ -1720,18 +1759,21 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
         * a quiescent state betweentimes.
         */
        local_irq_save(flags);
+       WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
        rdp = this_cpu_ptr(rsp->rda);
 
        /* Add the callback to our list. */
        *rdp->nxttail[RCU_NEXT_TAIL] = head;
        rdp->nxttail[RCU_NEXT_TAIL] = &head->next;
        rdp->qlen++;
+       if (lazy)
+               rdp->qlen_lazy++;
 
        if (__is_kfree_rcu_offset((unsigned long)func))
                trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
-                                        rdp->qlen);
+                                        rdp->qlen_lazy, rdp->qlen);
        else
-               trace_rcu_callback(rsp->name, head, rdp->qlen);
+               trace_rcu_callback(rsp->name, head, rdp->qlen_lazy, rdp->qlen);
 
        /* If interrupts were disabled, don't dive into RCU core. */
        if (irqs_disabled_flags(flags)) {
@@ -1778,16 +1820,16 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
  */
 void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 {
-       __call_rcu(head, func, &rcu_sched_state);
+       __call_rcu(head, func, &rcu_sched_state, 0);
 }
 EXPORT_SYMBOL_GPL(call_rcu_sched);
 
 /*
- * Queue an RCU for invocation after a quicker grace period.
+ * Queue an RCU callback for invocation after a quicker grace period.
  */
 void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 {
-       __call_rcu(head, func, &rcu_bh_state);
+       __call_rcu(head, func, &rcu_bh_state, 0);
 }
 EXPORT_SYMBOL_GPL(call_rcu_bh);
 
@@ -1816,6 +1858,10 @@ EXPORT_SYMBOL_GPL(call_rcu_bh);
  */
 void synchronize_sched(void)
 {
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+                          !lock_is_held(&rcu_lock_map) &&
+                          !lock_is_held(&rcu_sched_lock_map),
+                          "Illegal synchronize_sched() in RCU-sched read-side critical section");
        if (rcu_blocking_is_gp())
                return;
        wait_rcu_gp(call_rcu_sched);
@@ -1833,6 +1879,10 @@ EXPORT_SYMBOL_GPL(synchronize_sched);
  */
 void synchronize_rcu_bh(void)
 {
+       rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+                          !lock_is_held(&rcu_lock_map) &&
+                          !lock_is_held(&rcu_sched_lock_map),
+                          "Illegal synchronize_rcu_bh() in RCU-bh read-side critical section");
        if (rcu_blocking_is_gp())
                return;
        wait_rcu_gp(call_rcu_bh);
@@ -1932,7 +1982,7 @@ static int rcu_cpu_has_callbacks(int cpu)
        /* RCU callbacks either ready or pending? */
        return per_cpu(rcu_sched_data, cpu).nxtlist ||
               per_cpu(rcu_bh_data, cpu).nxtlist ||
-              rcu_preempt_needs_cpu(cpu);
+              rcu_preempt_cpu_has_callbacks(cpu);
 }
 
 static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
@@ -2027,6 +2077,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
        rdp->nxtlist = NULL;
        for (i = 0; i < RCU_NEXT_SIZE; i++)
                rdp->nxttail[i] = &rdp->nxtlist;
+       rdp->qlen_lazy = 0;
        rdp->qlen = 0;
        rdp->dynticks = &per_cpu(rcu_dynticks, cpu);
        WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_NESTING);
@@ -2139,16 +2190,18 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
                 * touch any data without introducing corruption. We send the
                 * dying CPU's callbacks to an arbitrarily chosen online CPU.
                 */
-               rcu_send_cbs_to_online(&rcu_bh_state);
-               rcu_send_cbs_to_online(&rcu_sched_state);
-               rcu_preempt_send_cbs_to_online();
+               rcu_cleanup_dying_cpu(&rcu_bh_state);
+               rcu_cleanup_dying_cpu(&rcu_sched_state);
+               rcu_preempt_cleanup_dying_cpu();
                rcu_cleanup_after_idle(cpu);
                break;
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
        case CPU_UP_CANCELED:
        case CPU_UP_CANCELED_FROZEN:
-               rcu_offline_cpu(cpu);
+               rcu_cleanup_dead_cpu(cpu, &rcu_bh_state);
+               rcu_cleanup_dead_cpu(cpu, &rcu_sched_state);
+               rcu_preempt_cleanup_dead_cpu(cpu);
                break;
        default:
                break;
This page took 0.033755 seconds and 5 git commands to generate.