Skip to content

Commit

Permalink
ARM: CPU hotplug: fix reporting of spurious wakeups
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Russell King committed Dec 20, 2010
1 parent 58613cd commit d445026
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 27 deletions.
20 changes: 11 additions & 9 deletions arch/arm/mach-realview/hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand 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)++;
}
}

Expand All @@ -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)
Expand Down
20 changes: 11 additions & 9 deletions arch/arm/mach-s5pv310/hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand 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)++;
}
}

Expand All @@ -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)
Expand Down
20 changes: 11 additions & 9 deletions arch/arm/mach-tegra/hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand 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)++;
}
}

Expand All @@ -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)
Expand Down

0 comments on commit d445026

Please sign in to comment.