From fc0f30cc92e931ebda1bf4ad14bb305ad79d32ab Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto <[seto.hidetoshi@jp.fujitsu.com]> Date: Thu, 6 Aug 2009 14:51:57 -0700 Subject: [PATCH] --- yaml --- r: 163292 b: refs/heads/master c: 1726b0883dd08636705ea55d577eb0ec314ba427 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/ia64/kernel/crash.c | 47 +++++++++++++++++++++--- trunk/arch/ia64/kernel/relocate_kernel.S | 2 +- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index e09914dde464..59c94ea18285 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 68cb14c7c46d9204ba451a534f15a8bc12c88e28 +refs/heads/master: 1726b0883dd08636705ea55d577eb0ec314ba427 diff --git a/trunk/arch/ia64/kernel/crash.c b/trunk/arch/ia64/kernel/crash.c index b2a8b3da8af3..9c851b73f276 100644 --- a/trunk/arch/ia64/kernel/crash.c +++ b/trunk/arch/ia64/kernel/crash.c @@ -23,6 +23,7 @@ int kdump_status[NR_CPUS]; static atomic_t kdump_cpu_frozen; atomic_t kdump_in_progress; +static int kdump_freeze_monarch; static int kdump_on_init = 1; static int kdump_on_fatal_mca = 1; @@ -108,6 +109,33 @@ machine_crash_shutdown(struct pt_regs *pt) */ kexec_disable_iosapic(); #ifdef CONFIG_SMP + /* + * If kdump_on_init is set and an INIT is asserted here, kdump will + * be started again via INIT monarch. + */ + local_irq_disable(); + ia64_set_psr_mc(); /* mask MCA/INIT */ + if (atomic_inc_return(&kdump_in_progress) != 1) + unw_init_running(kdump_cpu_freeze, NULL); + + /* + * Now this cpu is ready for kdump. + * Stop all others by IPI or INIT. They could receive INIT from + * outside and might be INIT monarch, but only thing they have to + * do is falling into kdump_cpu_freeze(). + * + * If an INIT is asserted here: + * - All receivers might be slaves, since some of cpus could already + * be frozen and INIT might be masked on monarch. In this case, + * all slaves will park in while (monarch_cpu == -1) loop before + * DIE_INIT_SLAVE_ENTER that for waiting monarch enters. + * => TBD: freeze all slaves + * - One might be a monarch, but INIT rendezvous will fail since + * at least this cpu already have INIT masked so it never join + * to the rendezvous. In this case, all slaves and monarch will + * be frozen after timeout of the INIT rendezvous. + * => TBD: freeze them without waiting timeout + */ kdump_smp_send_stop(); /* not all cpu response to IPI, send INIT to freeze them */ if (kdump_wait_cpu_freeze() && kdump_on_init) { @@ -177,13 +205,18 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) switch (val) { case DIE_INIT_MONARCH_PROCESS: if (kdump_on_init) { - atomic_set(&kdump_in_progress, 1); + if (atomic_inc_return(&kdump_in_progress) != 1) + kdump_freeze_monarch = 1; *(nd->monarch_cpu) = -1; } break; case DIE_INIT_MONARCH_LEAVE: - if (kdump_on_init) - machine_kdump_on_init(); + if (kdump_on_init) { + if (kdump_freeze_monarch) + unw_init_running(kdump_cpu_freeze, NULL); + else + machine_kdump_on_init(); + } break; case DIE_INIT_SLAVE_LEAVE: if (atomic_read(&kdump_in_progress)) @@ -196,9 +229,11 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) case DIE_MCA_MONARCH_LEAVE: /* *(nd->data) indicate if MCA is recoverable */ if (kdump_on_fatal_mca && !(*(nd->data))) { - atomic_set(&kdump_in_progress, 1); - *(nd->monarch_cpu) = -1; - machine_kdump_on_init(); + if (atomic_inc_return(&kdump_in_progress) == 1) { + *(nd->monarch_cpu) = -1; + machine_kdump_on_init(); + } + /* We got fatal MCA while kdump!? No way!! */ } break; } diff --git a/trunk/arch/ia64/kernel/relocate_kernel.S b/trunk/arch/ia64/kernel/relocate_kernel.S index 903babd22d62..32f6fc131fbe 100644 --- a/trunk/arch/ia64/kernel/relocate_kernel.S +++ b/trunk/arch/ia64/kernel/relocate_kernel.S @@ -52,7 +52,7 @@ GLOBAL_ENTRY(relocate_new_kernel) srlz.i ;; mov ar.rnat=r18 - rfi + rfi // note: this unmask MCA/INIT (psr.mc) ;; 1: //physical mode code begin