diff options
author | Hidetoshi Seto <[seto.hidetoshi@jp.fujitsu.com]> | 2009-08-06 17:51:57 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2009-09-14 19:19:10 -0400 |
commit | 5959906ee9dee602a46e49c868a7e543e050d605 (patch) | |
tree | 8fe75fa3461aa83d4185d126755a90aa4be4d68a | |
parent | 1726b0883dd08636705ea55d577eb0ec314ba427 (diff) |
[IA64] kdump: Try INIT regardless of
kdump_on_init
CPUs should be frozen if possible, otherwise it might hinder kdump.
So if there are CPUs not respond to IPI, try INIT to stop them.
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>
-rw-r--r-- | arch/ia64/kernel/crash.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c index 9c851b73f276..0995fdc7b299 100644 --- a/arch/ia64/kernel/crash.c +++ b/arch/ia64/kernel/crash.c | |||
@@ -138,8 +138,10 @@ machine_crash_shutdown(struct pt_regs *pt) | |||
138 | */ | 138 | */ |
139 | kdump_smp_send_stop(); | 139 | kdump_smp_send_stop(); |
140 | /* not all cpu response to IPI, send INIT to freeze them */ | 140 | /* not all cpu response to IPI, send INIT to freeze them */ |
141 | if (kdump_wait_cpu_freeze() && kdump_on_init) { | 141 | if (kdump_wait_cpu_freeze()) { |
142 | kdump_smp_send_init(); | 142 | kdump_smp_send_init(); |
143 | /* wait again, don't go ahead if possible */ | ||
144 | kdump_wait_cpu_freeze(); | ||
143 | } | 145 | } |
144 | #endif | 146 | #endif |
145 | } | 147 | } |
@@ -178,6 +180,19 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) | |||
178 | struct ia64_mca_notify_die *nd; | 180 | struct ia64_mca_notify_die *nd; |
179 | struct die_args *args = data; | 181 | struct die_args *args = data; |
180 | 182 | ||
183 | if (atomic_read(&kdump_in_progress)) { | ||
184 | switch (val) { | ||
185 | case DIE_INIT_MONARCH_LEAVE: | ||
186 | if (!kdump_freeze_monarch) | ||
187 | break; | ||
188 | /* fall through */ | ||
189 | case DIE_INIT_SLAVE_LEAVE: | ||
190 | case DIE_MCA_RENDZVOUS_LEAVE: | ||
191 | unw_init_running(kdump_cpu_freeze, NULL); | ||
192 | break; | ||
193 | } | ||
194 | } | ||
195 | |||
181 | if (!kdump_on_init && !kdump_on_fatal_mca) | 196 | if (!kdump_on_init && !kdump_on_fatal_mca) |
182 | return NOTIFY_DONE; | 197 | return NOTIFY_DONE; |
183 | 198 | ||
@@ -190,41 +205,25 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) | |||
190 | } | 205 | } |
191 | 206 | ||
192 | if (val != DIE_INIT_MONARCH_LEAVE && | 207 | if (val != DIE_INIT_MONARCH_LEAVE && |
193 | val != DIE_INIT_SLAVE_LEAVE && | ||
194 | val != DIE_INIT_MONARCH_PROCESS && | 208 | val != DIE_INIT_MONARCH_PROCESS && |
195 | val != DIE_MCA_RENDZVOUS_LEAVE && | ||
196 | val != DIE_MCA_MONARCH_LEAVE) | 209 | val != DIE_MCA_MONARCH_LEAVE) |
197 | return NOTIFY_DONE; | 210 | return NOTIFY_DONE; |
198 | 211 | ||
199 | nd = (struct ia64_mca_notify_die *)args->err; | 212 | nd = (struct ia64_mca_notify_die *)args->err; |
200 | /* Reason code 1 means machine check rendezvous*/ | ||
201 | if ((val == DIE_INIT_MONARCH_LEAVE || val == DIE_INIT_SLAVE_LEAVE | ||
202 | || val == DIE_INIT_MONARCH_PROCESS) && nd->sos->rv_rc == 1) | ||
203 | return NOTIFY_DONE; | ||
204 | 213 | ||
205 | switch (val) { | 214 | switch (val) { |
206 | case DIE_INIT_MONARCH_PROCESS: | 215 | case DIE_INIT_MONARCH_PROCESS: |
207 | if (kdump_on_init) { | 216 | /* Reason code 1 means machine check rendezvous*/ |
217 | if (kdump_on_init && (nd->sos->rv_rc != 1)) { | ||
208 | if (atomic_inc_return(&kdump_in_progress) != 1) | 218 | if (atomic_inc_return(&kdump_in_progress) != 1) |
209 | kdump_freeze_monarch = 1; | 219 | kdump_freeze_monarch = 1; |
210 | *(nd->monarch_cpu) = -1; | 220 | *(nd->monarch_cpu) = -1; |
211 | } | 221 | } |
212 | break; | 222 | break; |
213 | case DIE_INIT_MONARCH_LEAVE: | 223 | case DIE_INIT_MONARCH_LEAVE: |
214 | if (kdump_on_init) { | 224 | /* Reason code 1 means machine check rendezvous*/ |
215 | if (kdump_freeze_monarch) | 225 | if (kdump_on_init && (nd->sos->rv_rc != 1)) |
216 | unw_init_running(kdump_cpu_freeze, NULL); | 226 | machine_kdump_on_init(); |
217 | else | ||
218 | machine_kdump_on_init(); | ||
219 | } | ||
220 | break; | ||
221 | case DIE_INIT_SLAVE_LEAVE: | ||
222 | if (atomic_read(&kdump_in_progress)) | ||
223 | unw_init_running(kdump_cpu_freeze, NULL); | ||
224 | break; | ||
225 | case DIE_MCA_RENDZVOUS_LEAVE: | ||
226 | if (atomic_read(&kdump_in_progress)) | ||
227 | unw_init_running(kdump_cpu_freeze, NULL); | ||
228 | break; | 227 | break; |
229 | case DIE_MCA_MONARCH_LEAVE: | 228 | case DIE_MCA_MONARCH_LEAVE: |
230 | /* *(nd->data) indicate if MCA is recoverable */ | 229 | /* *(nd->data) indicate if MCA is recoverable */ |