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 /arch/powerpc/kernel | |
| 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>
Diffstat (limited to 'arch/powerpc/kernel')
| -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); |
