ARM: CPU hotplug: fix reporting of spurious wakeups
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 19 Dec 2010 11:30:43 +0000 (11:30 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 20 Dec 2010 15:09:14 +0000 (15:09 +0000)
The original scheme for reporting spurious wakeups was broken - it
tried to use printk() from a context which wasn't coherent with the
other CPUs, which risks corrupting the printk() data.

Fix this by noting the number spurious wakeups, and only report them
when we are properly woken - when we will be coherent with the rest
of the system.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-realview/hotplug.c
arch/arm/mach-s5pv310/hotplug.c
arch/arm/mach-tegra/hotplug.c

index e06572e6c4904138dfd4ed17466166eaf7521b36..b6387cfe70443a97b51fe19f7795022545b2cfeb 100644 (file)
@@ -53,7 +53,7 @@ static inline void cpu_leave_lowpower(void)
          : "cc");
 }
 
-static inline void platform_do_lowpower(unsigned int cpu)
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 {
        /*
         * there is no power-control hardware on this platform, so all
@@ -77,16 +77,13 @@ static inline void platform_do_lowpower(unsigned int cpu)
                }
 
                /*
-                * getting here, means that we have come out of WFI without
+                * Getting here, means that we have come out of WFI without
                 * having been woken up - this shouldn't happen
                 *
-                * The trouble is, letting people know about this is not really
-                * possible, since we are currently running incoherently, and
-                * therefore cannot safely call printk() or anything else
+                * Just note it happening - when we're woken, we can report
+                * its occurrence.
                 */
-#ifdef DEBUG
-               printk("CPU%u: spurious wakeup call\n", cpu);
-#endif
+               (*spurious)++;
        }
 }
 
@@ -102,17 +99,22 @@ int platform_cpu_kill(unsigned int cpu)
  */
 void platform_cpu_die(unsigned int cpu)
 {
+       int spurious = 0;
+
        /*
         * we're ready for shutdown now, so do it
         */
        cpu_enter_lowpower();
-       platform_do_lowpower(cpu);
+       platform_do_lowpower(cpu, &spurious);
 
        /*
         * bring this CPU back into the world of cache
         * coherency, and then restore interrupts
         */
        cpu_leave_lowpower();
+
+       if (spurious)
+               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
 }
 
 int platform_cpu_disable(unsigned int cpu)
index ea951ef6ea544fb91d0a9584f555370c90d1d8d9..951ba6d63d215222b79502a235b2c153cd3a2696 100644 (file)
@@ -56,7 +56,7 @@ static inline void cpu_leave_lowpower(void)
          : "cc");
 }
 
-static inline void platform_do_lowpower(unsigned int cpu)
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 {
        /*
         * there is no power-control hardware on this platform, so all
@@ -80,16 +80,13 @@ static inline void platform_do_lowpower(unsigned int cpu)
                }
 
                /*
-                * getting here, means that we have come out of WFI without
+                * Getting here, means that we have come out of WFI without
                 * having been woken up - this shouldn't happen
                 *
-                * The trouble is, letting people know about this is not really
-                * possible, since we are currently running incoherently, and
-                * therefore cannot safely call printk() or anything else
+                * Just note it happening - when we're woken, we can report
+                * its occurrence.
                 */
-#ifdef DEBUG
-               printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
-#endif
+               (*spurious)++;
        }
 }
 
@@ -105,17 +102,22 @@ int platform_cpu_kill(unsigned int cpu)
  */
 void platform_cpu_die(unsigned int cpu)
 {
+       int spurious = 0;
+
        /*
         * we're ready for shutdown now, so do it
         */
        cpu_enter_lowpower();
-       platform_do_lowpower(cpu);
+       platform_do_lowpower(cpu, &spurious);
 
        /*
         * bring this CPU back into the world of cache
         * coherency, and then restore interrupts
         */
        cpu_leave_lowpower();
+
+       if (spurious)
+               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
 }
 
 int platform_cpu_disable(unsigned int cpu)
index a5eeb9126645da9806de475625d3d745859c6bbd..17faf777af23a5c99ef0846b314b464bf107f178 100644 (file)
@@ -52,7 +52,7 @@ static inline void cpu_leave_lowpower(void)
          : "cc");
 }
 
-static inline void platform_do_lowpower(unsigned int cpu)
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 {
        /*
         * there is no power-control hardware on this platform, so all
@@ -76,16 +76,13 @@ static inline void platform_do_lowpower(unsigned int cpu)
                /*}*/
 
                /*
-                * getting here, means that we have come out of WFI without
+                * Getting here, means that we have come out of WFI without
                 * having been woken up - this shouldn't happen
                 *
-                * The trouble is, letting people know about this is not really
-                * possible, since we are currently running incoherently, and
-                * therefore cannot safely call printk() or anything else
+                * Just note it happening - when we're woken, we can report
+                * its occurrence.
                 */
-#ifdef DEBUG
-               printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
-#endif
+               (*spurious)++;
        }
 }
 
@@ -101,17 +98,22 @@ int platform_cpu_kill(unsigned int cpu)
  */
 void platform_cpu_die(unsigned int cpu)
 {
+       int spurious = 0;
+
        /*
         * we're ready for shutdown now, so do it
         */
        cpu_enter_lowpower();
-       platform_do_lowpower(cpu);
+       platform_do_lowpower(cpu, &spurious);
 
        /*
         * bring this CPU back into the world of cache
         * coherency, and then restore interrupts
         */
        cpu_leave_lowpower();
+
+       if (spurious)
+               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
 }
 
 int platform_cpu_disable(unsigned int cpu)