]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/rcuclassic.c
h63xx: nfs mount works, gpe image boots to ts config screen.
[linux-2.6-omap-h63xx.git] / kernel / rcuclassic.c
index 743cf0550ff49d75c16e1d3ba331bcc8fe78c2eb..37f72e551542234d2d7d905741e8a5f6fb7532ec 100644 (file)
@@ -164,6 +164,87 @@ static void __call_rcu(struct rcu_head *head, struct rcu_ctrlblk *rcp,
        }
 }
 
+#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
+
+static void record_gp_stall_check_time(struct rcu_ctrlblk *rcp)
+{
+       rcp->gp_start = jiffies;
+       rcp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_CHECK;
+}
+
+static void print_other_cpu_stall(struct rcu_ctrlblk *rcp)
+{
+       int cpu;
+       long delta;
+       unsigned long flags;
+
+       /* Only let one CPU complain about others per time interval. */
+
+       spin_lock_irqsave(&rcp->lock, flags);
+       delta = jiffies - rcp->jiffies_stall;
+       if (delta < 2 || rcp->cur != rcp->completed) {
+               spin_unlock_irqrestore(&rcp->lock, flags);
+               return;
+       }
+       rcp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_RECHECK;
+       spin_unlock_irqrestore(&rcp->lock, flags);
+
+       /* OK, time to rat on our buddy... */
+
+       printk(KERN_ERR "RCU detected CPU stalls:");
+       for_each_possible_cpu(cpu) {
+               if (cpu_isset(cpu, rcp->cpumask))
+                       printk(" %d", cpu);
+       }
+       printk(" (detected by %d, t=%ld jiffies)\n",
+              smp_processor_id(), (long)(jiffies - rcp->gp_start));
+}
+
+static void print_cpu_stall(struct rcu_ctrlblk *rcp)
+{
+       unsigned long flags;
+
+       printk(KERN_ERR "RCU detected CPU %d stall (t=%lu/%lu jiffies)\n",
+                       smp_processor_id(), jiffies,
+                       jiffies - rcp->gp_start);
+       dump_stack();
+       spin_lock_irqsave(&rcp->lock, flags);
+       if ((long)(jiffies - rcp->jiffies_stall) >= 0)
+               rcp->jiffies_stall =
+                       jiffies + RCU_SECONDS_TILL_STALL_RECHECK;
+       spin_unlock_irqrestore(&rcp->lock, flags);
+       set_need_resched();  /* kick ourselves to get things going. */
+}
+
+static void check_cpu_stall(struct rcu_ctrlblk *rcp)
+{
+       long delta;
+
+       delta = jiffies - rcp->jiffies_stall;
+       if (cpu_isset(smp_processor_id(), rcp->cpumask) && delta >= 0) {
+
+               /* We haven't checked in, so go dump stack. */
+               print_cpu_stall(rcp);
+
+       } else if (rcp->cur != rcp->completed && delta >= 2) {
+
+               /* They had two seconds to dump stack, so complain. */
+               print_other_cpu_stall(rcp);
+       }
+}
+
+#else /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
+
+static void record_gp_stall_check_time(struct rcu_ctrlblk *rcp)
+{
+}
+
+static inline void check_cpu_stall(struct rcu_ctrlblk *rcp)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
+
 /**
  * call_rcu - Queue an RCU callback for invocation after a grace period.
  * @head: structure to be used for queueing the RCU updates.
@@ -293,84 +374,6 @@ static void rcu_do_batch(struct rcu_data *rdp)
  *   period (if necessary).
  */
 
-#ifdef CONFIG_DEBUG_RCU_STALL
-
-static inline void record_gp_check_time(struct rcu_ctrlblk *rcp)
-{
-       rcp->gp_check = get_seconds() + 3;
-}
-
-static void print_other_cpu_stall(struct rcu_ctrlblk *rcp)
-{
-       int cpu;
-       long delta;
-       unsigned long flags;
-
-       /* Only let one CPU complain about others per time interval. */
-
-       spin_lock_irqsave(&rcp->lock, flags);
-       delta = get_seconds() - rcp->gp_check;
-       if (delta < 2L || cpus_empty(rcp->cpumask)) {
-               spin_unlock(&rcp->lock);
-               return;
-       }
-       rcp->gp_check = get_seconds() + 30;
-       spin_unlock_irqrestore(&rcp->lock, flags);
-
-       /* OK, time to rat on our buddy... */
-
-       printk(KERN_ERR "RCU detected CPU stalls:");
-       for_each_cpu_mask(cpu, rcp->cpumask)
-               printk(" %d", cpu);
-       printk(" (detected by %d, t=%lu/%lu)\n",
-              smp_processor_id(), get_seconds(), rcp->gp_check);
-}
-
-static void print_cpu_stall(struct rcu_ctrlblk *rcp)
-{
-       unsigned long flags;
-
-       printk(KERN_ERR "RCU detected CPU %d stall (t=%lu/%lu)\n",
-                       smp_processor_id(), get_seconds(), rcp->gp_check);
-       dump_stack();
-       spin_lock_irqsave(&rcp->lock, flags);
-       if ((long)(get_seconds() - rcp->gp_check) >= 0L)
-               rcp->gp_check = get_seconds() + 30;
-       spin_unlock_irqrestore(&rcp->lock, flags);
-}
-
-static void check_cpu_stall(struct rcu_ctrlblk *rcp, struct rcu_data *rdp)
-{
-       long delta;
-
-       delta = get_seconds() - rcp->gp_check;
-       if (cpu_isset(smp_processor_id(), rcp->cpumask) && delta >= 0L) {
-
-               /* We haven't checked in, so go dump stack. */
-
-               print_cpu_stall(rcp);
-
-       } else {
-               if (!cpus_empty(rcp->cpumask) && delta >= 2L) {
-                       /* They had two seconds to dump stack, so complain. */
-                       print_other_cpu_stall(rcp);
-               }
-       }
-}
-
-#else /* #ifdef CONFIG_DEBUG_RCU_STALL */
-
-static inline void record_gp_check_time(struct rcu_ctrlblk *rcp)
-{
-}
-
-static inline void
-check_cpu_stall(struct rcu_ctrlblk *rcp, struct rcu_data *rdp)
-{
-}
-
-#endif /* #else #ifdef CONFIG_DEBUG_RCU_STALL */
-
 /*
  * Register a new batch of callbacks, and start it up if there is currently no
  * active batch and the batch to be registered has not already occurred.
@@ -381,7 +384,7 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp)
        if (rcp->cur != rcp->pending &&
                        rcp->completed == rcp->cur) {
                rcp->cur++;
-               record_gp_check_time(rcp);
+               record_gp_stall_check_time(rcp);
 
                /*
                 * Accessing nohz_cpu_mask before incrementing rcp->cur needs a
@@ -561,15 +564,15 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp,
                local_irq_restore(flags);
 
                if (rcu_batch_after(rdp->batch, rcp->pending)) {
-                       unsigned long flags;
+                       unsigned long flags2;
 
                        /* and start it/schedule start if it's a new batch */
-                       spin_lock_irqsave(&rcp->lock, flags);
+                       spin_lock_irqsave(&rcp->lock, flags2);
                        if (rcu_batch_after(rdp->batch, rcp->pending)) {
                                rcp->pending = rdp->batch;
                                rcu_start_batch(rcp);
                        }
-                       spin_unlock_irqrestore(&rcp->lock, flags);
+                       spin_unlock_irqrestore(&rcp->lock, flags2);
                }
        }
 
@@ -603,7 +606,7 @@ static void rcu_process_callbacks(struct softirq_action *unused)
 static int __rcu_pending(struct rcu_ctrlblk *rcp, struct rcu_data *rdp)
 {
        /* Check for CPU stalls, if enabled. */
-       check_cpu_stall(rcp, rdp);
+       check_cpu_stall(rcp);
 
        if (rdp->nxtlist) {
                long completed_snap = ACCESS_ONCE(rcp->completed);
@@ -769,6 +772,9 @@ static struct notifier_block __cpuinitdata rcu_nb = {
  */
 void __init __rcu_init(void)
 {
+#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
+       printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
+#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
        rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE,
                        (void *)(long)smp_processor_id());
        /* Register notifier for non-boot CPUs */