Skip to content

Commit

Permalink
powerpc/kexec: Fix orphaned offline CPUs across kexec
Browse files Browse the repository at this point in the history
When CPU hotplug is used, some CPUs may be offline at the time a kexec is
performed.  The subsequent kernel may expect these CPUs to be already running,
and will declare them stuck.  On pseries, there's also a soft-offline (cede)
state that CPUs may be in; this can also cause problems as the kexeced kernel
may ask RTAS if they're online -- and RTAS would say they are.  The CPU will
either appear stuck, or will cause a crash as we replace its cede loop beneath
it.

This patch kicks each present offline CPU awake before the kexec, so that
none are forever lost to these assumptions in the subsequent kernel.

Now, the behaviour is that all available CPUs that were offlined are now
online & usable after the kexec.  This mimics the behaviour of a full reboot
(on which all CPUs will be restarted).

Signed-off-by: Matt Evans <matt@ozlabs.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Matt Evans authored and Benjamin Herrenschmidt committed Jul 31, 2010
1 parent e2f7f73 commit e8e5c21
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion arch/powerpc/kernel/machine_kexec_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/init_task.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/cpu.h>

#include <asm/page.h>
#include <asm/current.h>
Expand Down Expand Up @@ -216,9 +217,32 @@ static void kexec_prepare_cpus_wait(int wait_state)
mb();
}

static void kexec_prepare_cpus(void)
/*
* We need to make sure each present CPU is online. The next kernel will scan
* the device tree and assume primary threads are online and query secondary
* threads via RTAS to online them if required. If we don't online primary
* threads, they will be stuck. However, we also online secondary threads as we
* may be using 'cede offline'. In this case RTAS doesn't see the secondary
* threads as offline -- and again, these CPUs will be stuck.
*
* So, we online all CPUs that should be running, including secondary threads.
*/
static void wake_offline_cpus(void)
{
int cpu = 0;

for_each_present_cpu(cpu) {
if (!cpu_online(cpu)) {
printk(KERN_INFO "kexec: Waking offline cpu %d.\n",
cpu);
cpu_up(cpu);
}
}
}

static void kexec_prepare_cpus(void)
{
wake_offline_cpus();
smp_call_function(kexec_smp_down, NULL, /* wait */0);
local_irq_disable();
mb(); /* make sure IRQs are disabled before we say they are */
Expand Down

0 comments on commit e8e5c21

Please sign in to comment.