diff options
author | Hidetoshi Seto <[seto.hidetoshi@jp.fujitsu.com]> | 2009-08-06 17:51:58 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2009-09-14 19:19:24 -0400 |
commit | 0cced40e7c58b1105aef3ca446da7b158a18a9a6 (patch) | |
tree | 401e554f0e69375833e6ef70651eacb44ed50909 /arch/ia64/kernel | |
parent | 5959906ee9dee602a46e49c868a7e543e050d605 (diff) |
[IA64] kdump: Short path to freeze CPUs
Setting monarch_cpu = -1 to let slaves frozen might not work, because
there might be slaves being late, not entered the rendezvous yet.
Such slaves might be caught in while (monarch_cpu == -1) loop.
Use kdump_in_progress instead of monarch_cpus to break INIT rendezvous
and let all slaves enter DIE_INIT_SLAVE_LEAVE smoothly.
And monarch no longer need to manage rendezvous if once kdump_in_progress
is set, catch the monarch in DIE_INIT_MONARCH_ENTER then.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Haren Myneni <hbabu@us.ibm.com>
Cc: kexec@lists.infradead.org
Acked-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/crash.c | 15 | ||||
-rw-r--r-- | arch/ia64/kernel/mca.c | 15 |
2 files changed, 19 insertions, 11 deletions
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c index 0995fdc7b299..6631a9dfafdc 100644 --- a/arch/ia64/kernel/crash.c +++ b/arch/ia64/kernel/crash.c | |||
@@ -127,14 +127,13 @@ machine_crash_shutdown(struct pt_regs *pt) | |||
127 | * If an INIT is asserted here: | 127 | * If an INIT is asserted here: |
128 | * - All receivers might be slaves, since some of cpus could already | 128 | * - All receivers might be slaves, since some of cpus could already |
129 | * be frozen and INIT might be masked on monarch. In this case, | 129 | * be frozen and INIT might be masked on monarch. In this case, |
130 | * all slaves will park in while (monarch_cpu == -1) loop before | 130 | * all slaves will be frozen soon since kdump_in_progress will let |
131 | * DIE_INIT_SLAVE_ENTER that for waiting monarch enters. | 131 | * them into DIE_INIT_SLAVE_LEAVE. |
132 | * => TBD: freeze all slaves | ||
133 | * - One might be a monarch, but INIT rendezvous will fail since | 132 | * - One might be a monarch, but INIT rendezvous will fail since |
134 | * at least this cpu already have INIT masked so it never join | 133 | * at least this cpu already have INIT masked so it never join |
135 | * to the rendezvous. In this case, all slaves and monarch will | 134 | * to the rendezvous. In this case, all slaves and monarch will |
136 | * be frozen after timeout of the INIT rendezvous. | 135 | * be frozen soon with no wait since the INIT rendezvous is skipped |
137 | * => TBD: freeze them without waiting timeout | 136 | * by kdump_in_progress. |
138 | */ | 137 | */ |
139 | kdump_smp_send_stop(); | 138 | kdump_smp_send_stop(); |
140 | /* not all cpu response to IPI, send INIT to freeze them */ | 139 | /* not all cpu response to IPI, send INIT to freeze them */ |
@@ -187,6 +186,7 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) | |||
187 | break; | 186 | break; |
188 | /* fall through */ | 187 | /* fall through */ |
189 | case DIE_INIT_SLAVE_LEAVE: | 188 | case DIE_INIT_SLAVE_LEAVE: |
189 | case DIE_INIT_MONARCH_ENTER: | ||
190 | case DIE_MCA_RENDZVOUS_LEAVE: | 190 | case DIE_MCA_RENDZVOUS_LEAVE: |
191 | unw_init_running(kdump_cpu_freeze, NULL); | 191 | unw_init_running(kdump_cpu_freeze, NULL); |
192 | break; | 192 | break; |
@@ -217,7 +217,6 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) | |||
217 | if (kdump_on_init && (nd->sos->rv_rc != 1)) { | 217 | if (kdump_on_init && (nd->sos->rv_rc != 1)) { |
218 | if (atomic_inc_return(&kdump_in_progress) != 1) | 218 | if (atomic_inc_return(&kdump_in_progress) != 1) |
219 | kdump_freeze_monarch = 1; | 219 | kdump_freeze_monarch = 1; |
220 | *(nd->monarch_cpu) = -1; | ||
221 | } | 220 | } |
222 | break; | 221 | break; |
223 | case DIE_INIT_MONARCH_LEAVE: | 222 | case DIE_INIT_MONARCH_LEAVE: |
@@ -228,10 +227,8 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) | |||
228 | case DIE_MCA_MONARCH_LEAVE: | 227 | case DIE_MCA_MONARCH_LEAVE: |
229 | /* *(nd->data) indicate if MCA is recoverable */ | 228 | /* *(nd->data) indicate if MCA is recoverable */ |
230 | if (kdump_on_fatal_mca && !(*(nd->data))) { | 229 | if (kdump_on_fatal_mca && !(*(nd->data))) { |
231 | if (atomic_inc_return(&kdump_in_progress) == 1) { | 230 | if (atomic_inc_return(&kdump_in_progress) == 1) |
232 | *(nd->monarch_cpu) = -1; | ||
233 | machine_kdump_on_init(); | 231 | machine_kdump_on_init(); |
234 | } | ||
235 | /* We got fatal MCA while kdump!? No way!! */ | 232 | /* We got fatal MCA while kdump!? No way!! */ |
236 | } | 233 | } |
237 | break; | 234 | break; |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 7b30d21c5190..d2877a7bfe2e 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1682,14 +1682,25 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1682 | 1682 | ||
1683 | if (!sos->monarch) { | 1683 | if (!sos->monarch) { |
1684 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; | 1684 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; |
1685 | |||
1686 | #ifdef CONFIG_KEXEC | ||
1687 | while (monarch_cpu == -1 && !atomic_read(&kdump_in_progress)) | ||
1688 | udelay(1000); | ||
1689 | #else | ||
1685 | while (monarch_cpu == -1) | 1690 | while (monarch_cpu == -1) |
1686 | cpu_relax(); /* spin until monarch enters */ | 1691 | cpu_relax(); /* spin until monarch enters */ |
1692 | #endif | ||
1687 | 1693 | ||
1688 | NOTIFY_INIT(DIE_INIT_SLAVE_ENTER, regs, (long)&nd, 1); | 1694 | NOTIFY_INIT(DIE_INIT_SLAVE_ENTER, regs, (long)&nd, 1); |
1689 | NOTIFY_INIT(DIE_INIT_SLAVE_PROCESS, regs, (long)&nd, 1); | 1695 | NOTIFY_INIT(DIE_INIT_SLAVE_PROCESS, regs, (long)&nd, 1); |
1690 | 1696 | ||
1697 | #ifdef CONFIG_KEXEC | ||
1698 | while (monarch_cpu != -1 && !atomic_read(&kdump_in_progress)) | ||
1699 | udelay(1000); | ||
1700 | #else | ||
1691 | while (monarch_cpu != -1) | 1701 | while (monarch_cpu != -1) |
1692 | cpu_relax(); /* spin until monarch leaves */ | 1702 | cpu_relax(); /* spin until monarch leaves */ |
1703 | #endif | ||
1693 | 1704 | ||
1694 | NOTIFY_INIT(DIE_INIT_SLAVE_LEAVE, regs, (long)&nd, 1); | 1705 | NOTIFY_INIT(DIE_INIT_SLAVE_LEAVE, regs, (long)&nd, 1); |
1695 | 1706 | ||