diff options
Diffstat (limited to 'arch/powerpc/kernel/crash.c')
-rw-r--r-- | arch/powerpc/kernel/crash.c | 91 |
1 files changed, 46 insertions, 45 deletions
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 5b5e1f002a8e..4e6ee944495a 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -64,9 +64,9 @@ void crash_ipi_callback(struct pt_regs *regs) | |||
64 | return; | 64 | return; |
65 | 65 | ||
66 | hard_irq_disable(); | 66 | hard_irq_disable(); |
67 | if (!cpu_isset(cpu, cpus_in_crash)) | 67 | if (!cpumask_test_cpu(cpu, &cpus_in_crash)) |
68 | crash_save_cpu(regs, cpu); | 68 | crash_save_cpu(regs, cpu); |
69 | cpu_set(cpu, cpus_in_crash); | 69 | cpumask_set_cpu(cpu, &cpus_in_crash); |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Entered via soft-reset - could be the kdump | 72 | * Entered via soft-reset - could be the kdump |
@@ -77,8 +77,8 @@ void crash_ipi_callback(struct pt_regs *regs) | |||
77 | * Tell the kexec CPU that entered via soft-reset and ready | 77 | * Tell the kexec CPU that entered via soft-reset and ready |
78 | * to go down. | 78 | * to go down. |
79 | */ | 79 | */ |
80 | if (cpu_isset(cpu, cpus_in_sr)) { | 80 | if (cpumask_test_cpu(cpu, &cpus_in_sr)) { |
81 | cpu_clear(cpu, cpus_in_sr); | 81 | cpumask_clear_cpu(cpu, &cpus_in_sr); |
82 | atomic_inc(&enter_on_soft_reset); | 82 | atomic_inc(&enter_on_soft_reset); |
83 | } | 83 | } |
84 | 84 | ||
@@ -87,7 +87,7 @@ void crash_ipi_callback(struct pt_regs *regs) | |||
87 | * This barrier is needed to make sure that all CPUs are stopped. | 87 | * This barrier is needed to make sure that all CPUs are stopped. |
88 | * If not, soft-reset will be invoked to bring other CPUs. | 88 | * If not, soft-reset will be invoked to bring other CPUs. |
89 | */ | 89 | */ |
90 | while (!cpu_isset(crashing_cpu, cpus_in_crash)) | 90 | while (!cpumask_test_cpu(crashing_cpu, &cpus_in_crash)) |
91 | cpu_relax(); | 91 | cpu_relax(); |
92 | 92 | ||
93 | if (ppc_md.kexec_cpu_down) | 93 | if (ppc_md.kexec_cpu_down) |
@@ -109,7 +109,7 @@ static void crash_soft_reset_check(int cpu) | |||
109 | { | 109 | { |
110 | unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ | 110 | unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ |
111 | 111 | ||
112 | cpu_clear(cpu, cpus_in_sr); | 112 | cpumask_clear_cpu(cpu, &cpus_in_sr); |
113 | while (atomic_read(&enter_on_soft_reset) != ncpus) | 113 | while (atomic_read(&enter_on_soft_reset) != ncpus) |
114 | cpu_relax(); | 114 | cpu_relax(); |
115 | } | 115 | } |
@@ -132,7 +132,7 @@ static void crash_kexec_prepare_cpus(int cpu) | |||
132 | */ | 132 | */ |
133 | printk(KERN_EMERG "Sending IPI to other cpus...\n"); | 133 | printk(KERN_EMERG "Sending IPI to other cpus...\n"); |
134 | msecs = 10000; | 134 | msecs = 10000; |
135 | while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { | 135 | while ((cpumask_weight(&cpus_in_crash) < ncpus) && (--msecs > 0)) { |
136 | cpu_relax(); | 136 | cpu_relax(); |
137 | mdelay(1); | 137 | mdelay(1); |
138 | } | 138 | } |
@@ -144,52 +144,24 @@ static void crash_kexec_prepare_cpus(int cpu) | |||
144 | * user to do soft reset such that we get all. | 144 | * user to do soft reset such that we get all. |
145 | * Soft-reset will be used until better mechanism is implemented. | 145 | * Soft-reset will be used until better mechanism is implemented. |
146 | */ | 146 | */ |
147 | if (cpus_weight(cpus_in_crash) < ncpus) { | 147 | if (cpumask_weight(&cpus_in_crash) < ncpus) { |
148 | printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", | 148 | printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", |
149 | ncpus - cpus_weight(cpus_in_crash)); | 149 | ncpus - cpumask_weight(&cpus_in_crash)); |
150 | printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); | 150 | printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); |
151 | cpus_in_sr = CPU_MASK_NONE; | 151 | cpumask_clear(&cpus_in_sr); |
152 | atomic_set(&enter_on_soft_reset, 0); | 152 | atomic_set(&enter_on_soft_reset, 0); |
153 | while (cpus_weight(cpus_in_crash) < ncpus) | 153 | while (cpumask_weight(&cpus_in_crash) < ncpus) |
154 | cpu_relax(); | 154 | cpu_relax(); |
155 | } | 155 | } |
156 | /* | 156 | /* |
157 | * Make sure all CPUs are entered via soft-reset if the kdump is | 157 | * Make sure all CPUs are entered via soft-reset if the kdump is |
158 | * invoked using soft-reset. | 158 | * invoked using soft-reset. |
159 | */ | 159 | */ |
160 | if (cpu_isset(cpu, cpus_in_sr)) | 160 | if (cpumask_test_cpu(cpu, &cpus_in_sr)) |
161 | crash_soft_reset_check(cpu); | 161 | crash_soft_reset_check(cpu); |
162 | /* Leave the IPI callback set */ | 162 | /* Leave the IPI callback set */ |
163 | } | 163 | } |
164 | 164 | ||
165 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ | ||
166 | #ifdef CONFIG_PPC_STD_MMU_64 | ||
167 | static void crash_kexec_wait_realmode(int cpu) | ||
168 | { | ||
169 | unsigned int msecs; | ||
170 | int i; | ||
171 | |||
172 | msecs = 10000; | ||
173 | for (i=0; i < NR_CPUS && msecs > 0; i++) { | ||
174 | if (i == cpu) | ||
175 | continue; | ||
176 | |||
177 | while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { | ||
178 | barrier(); | ||
179 | if (!cpu_possible(i)) { | ||
180 | break; | ||
181 | } | ||
182 | if (!cpu_online(i)) { | ||
183 | break; | ||
184 | } | ||
185 | msecs--; | ||
186 | mdelay(1); | ||
187 | } | ||
188 | } | ||
189 | mb(); | ||
190 | } | ||
191 | #endif /* CONFIG_PPC_STD_MMU_64 */ | ||
192 | |||
193 | /* | 165 | /* |
194 | * This function will be called by secondary cpus or by kexec cpu | 166 | * This function will be called by secondary cpus or by kexec cpu |
195 | * if soft-reset is activated to stop some CPUs. | 167 | * if soft-reset is activated to stop some CPUs. |
@@ -210,7 +182,7 @@ void crash_kexec_secondary(struct pt_regs *regs) | |||
210 | * exited using 'x'(exit and recover) or | 182 | * exited using 'x'(exit and recover) or |
211 | * kexec_should_crash() failed for all running tasks. | 183 | * kexec_should_crash() failed for all running tasks. |
212 | */ | 184 | */ |
213 | cpu_clear(cpu, cpus_in_sr); | 185 | cpumask_clear_cpu(cpu, &cpus_in_sr); |
214 | local_irq_restore(flags); | 186 | local_irq_restore(flags); |
215 | return; | 187 | return; |
216 | } | 188 | } |
@@ -224,7 +196,7 @@ void crash_kexec_secondary(struct pt_regs *regs) | |||
224 | * then start kexec boot. | 196 | * then start kexec boot. |
225 | */ | 197 | */ |
226 | crash_soft_reset_check(cpu); | 198 | crash_soft_reset_check(cpu); |
227 | cpu_set(crashing_cpu, cpus_in_crash); | 199 | cpumask_set_cpu(crashing_cpu, &cpus_in_crash); |
228 | if (ppc_md.kexec_cpu_down) | 200 | if (ppc_md.kexec_cpu_down) |
229 | ppc_md.kexec_cpu_down(1, 0); | 201 | ppc_md.kexec_cpu_down(1, 0); |
230 | machine_kexec(kexec_crash_image); | 202 | machine_kexec(kexec_crash_image); |
@@ -234,7 +206,6 @@ void crash_kexec_secondary(struct pt_regs *regs) | |||
234 | } | 206 | } |
235 | 207 | ||
236 | #else /* ! CONFIG_SMP */ | 208 | #else /* ! CONFIG_SMP */ |
237 | static inline void crash_kexec_wait_realmode(int cpu) {} | ||
238 | 209 | ||
239 | static void crash_kexec_prepare_cpus(int cpu) | 210 | static void crash_kexec_prepare_cpus(int cpu) |
240 | { | 211 | { |
@@ -253,10 +224,40 @@ static void crash_kexec_prepare_cpus(int cpu) | |||
253 | 224 | ||
254 | void crash_kexec_secondary(struct pt_regs *regs) | 225 | void crash_kexec_secondary(struct pt_regs *regs) |
255 | { | 226 | { |
256 | cpus_in_sr = CPU_MASK_NONE; | 227 | cpumask_clear(&cpus_in_sr); |
257 | } | 228 | } |
258 | #endif /* CONFIG_SMP */ | 229 | #endif /* CONFIG_SMP */ |
259 | 230 | ||
231 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ | ||
232 | #if defined(CONFIG_SMP) && defined(CONFIG_PPC_STD_MMU_64) | ||
233 | static void crash_kexec_wait_realmode(int cpu) | ||
234 | { | ||
235 | unsigned int msecs; | ||
236 | int i; | ||
237 | |||
238 | msecs = 10000; | ||
239 | for (i=0; i < nr_cpu_ids && msecs > 0; i++) { | ||
240 | if (i == cpu) | ||
241 | continue; | ||
242 | |||
243 | while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { | ||
244 | barrier(); | ||
245 | if (!cpu_possible(i)) { | ||
246 | break; | ||
247 | } | ||
248 | if (!cpu_online(i)) { | ||
249 | break; | ||
250 | } | ||
251 | msecs--; | ||
252 | mdelay(1); | ||
253 | } | ||
254 | } | ||
255 | mb(); | ||
256 | } | ||
257 | #else | ||
258 | static inline void crash_kexec_wait_realmode(int cpu) {} | ||
259 | #endif /* CONFIG_SMP && CONFIG_PPC_STD_MMU_64 */ | ||
260 | |||
260 | /* | 261 | /* |
261 | * Register a function to be called on shutdown. Only use this if you | 262 | * Register a function to be called on shutdown. Only use this if you |
262 | * can't reset your device in the second kernel. | 263 | * can't reset your device in the second kernel. |
@@ -345,7 +346,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
345 | crashing_cpu = smp_processor_id(); | 346 | crashing_cpu = smp_processor_id(); |
346 | crash_save_cpu(regs, crashing_cpu); | 347 | crash_save_cpu(regs, crashing_cpu); |
347 | crash_kexec_prepare_cpus(crashing_cpu); | 348 | crash_kexec_prepare_cpus(crashing_cpu); |
348 | cpu_set(crashing_cpu, cpus_in_crash); | 349 | cpumask_set_cpu(crashing_cpu, &cpus_in_crash); |
349 | crash_kexec_wait_realmode(crashing_cpu); | 350 | crash_kexec_wait_realmode(crashing_cpu); |
350 | 351 | ||
351 | machine_kexec_mask_interrupts(); | 352 | machine_kexec_mask_interrupts(); |