diff options
author | Satyam Sharma <satyam@infradead.org> | 2007-09-17 19:43:40 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-09-22 00:49:22 -0400 |
commit | 8fd7675c092f79f240246c76728477ec4e7f7f09 (patch) | |
tree | 848a6f4d312711a84b882e74c093e30158a86c7b | |
parent | 17b5ee04c09a158129eb538933eae7be956190e9 (diff) |
[POWERPC] Avoid pointless WARN_ON(irqs_disabled()) from panic codepath
> ------------[ cut here ]------------
> Badness at arch/powerpc/kernel/smp.c:202
comes when smp_call_function_map() has been called with irqs disabled,
which is illegal. However, there is a special case, the panic() codepath,
when we do not want to warn about this -- warning at that time is pointless
anyway, and only serves to scroll away the *real* cause of the panic and
distracts from the real bug.
* So let's extract the WARN_ON() from smp_call_function_map() into all its
callers -- smp_call_function() and smp_call_function_single()
* Also, introduce another caller of smp_call_function_map(), namely
__smp_call_function() (and make smp_call_function() a wrapper over this)
which does *not* warn about disabled irqs
* Use this __smp_call_function() from the panic codepath's smp_send_stop()
We also end having to move code of smp_send_stop() below the definition
of __smp_call_function().
Signed-off-by: Satyam Sharma <satyam@infradead.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/kernel/smp.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 1ea43160f543..b24dcbaeecaa 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -152,11 +152,6 @@ static void stop_this_cpu(void *dummy) | |||
152 | ; | 152 | ; |
153 | } | 153 | } |
154 | 154 | ||
155 | void smp_send_stop(void) | ||
156 | { | ||
157 | smp_call_function(stop_this_cpu, NULL, 1, 0); | ||
158 | } | ||
159 | |||
160 | /* | 155 | /* |
161 | * Structure and data for smp_call_function(). This is designed to minimise | 156 | * Structure and data for smp_call_function(). This is designed to minimise |
162 | * static memory requirements. It also looks cleaner. | 157 | * static memory requirements. It also looks cleaner. |
@@ -198,9 +193,6 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, | |||
198 | int cpu; | 193 | int cpu; |
199 | u64 timeout; | 194 | u64 timeout; |
200 | 195 | ||
201 | /* Can deadlock when called with interrupts disabled */ | ||
202 | WARN_ON(irqs_disabled()); | ||
203 | |||
204 | if (unlikely(smp_ops == NULL)) | 196 | if (unlikely(smp_ops == NULL)) |
205 | return ret; | 197 | return ret; |
206 | 198 | ||
@@ -270,10 +262,19 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, | |||
270 | return ret; | 262 | return ret; |
271 | } | 263 | } |
272 | 264 | ||
265 | static int __smp_call_function(void (*func)(void *info), void *info, | ||
266 | int nonatomic, int wait) | ||
267 | { | ||
268 | return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map); | ||
269 | } | ||
270 | |||
273 | int smp_call_function(void (*func) (void *info), void *info, int nonatomic, | 271 | int smp_call_function(void (*func) (void *info), void *info, int nonatomic, |
274 | int wait) | 272 | int wait) |
275 | { | 273 | { |
276 | return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map); | 274 | /* Can deadlock when called with interrupts disabled */ |
275 | WARN_ON(irqs_disabled()); | ||
276 | |||
277 | return __smp_call_function(func, info, nonatomic, wait); | ||
277 | } | 278 | } |
278 | EXPORT_SYMBOL(smp_call_function); | 279 | EXPORT_SYMBOL(smp_call_function); |
279 | 280 | ||
@@ -283,6 +284,9 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int | |||
283 | cpumask_t map = CPU_MASK_NONE; | 284 | cpumask_t map = CPU_MASK_NONE; |
284 | int ret = 0; | 285 | int ret = 0; |
285 | 286 | ||
287 | /* Can deadlock when called with interrupts disabled */ | ||
288 | WARN_ON(irqs_disabled()); | ||
289 | |||
286 | if (!cpu_online(cpu)) | 290 | if (!cpu_online(cpu)) |
287 | return -EINVAL; | 291 | return -EINVAL; |
288 | 292 | ||
@@ -299,6 +303,11 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int | |||
299 | } | 303 | } |
300 | EXPORT_SYMBOL(smp_call_function_single); | 304 | EXPORT_SYMBOL(smp_call_function_single); |
301 | 305 | ||
306 | void smp_send_stop(void) | ||
307 | { | ||
308 | __smp_call_function(stop_this_cpu, NULL, 1, 0); | ||
309 | } | ||
310 | |||
302 | void smp_call_function_interrupt(void) | 311 | void smp_call_function_interrupt(void) |
303 | { | 312 | { |
304 | void (*func) (void *info); | 313 | void (*func) (void *info); |