diff options
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
-rw-r--r-- | arch/powerpc/kernel/irq.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index edb2b00edbd2..24dc8117b822 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -369,6 +369,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
369 | return NO_IRQ; | 369 | return NO_IRQ; |
370 | 370 | ||
371 | } | 371 | } |
372 | #endif /* CONFIG_PPC64 */ | ||
372 | 373 | ||
373 | #ifdef CONFIG_IRQSTACKS | 374 | #ifdef CONFIG_IRQSTACKS |
374 | struct thread_info *softirq_ctx[NR_CPUS]; | 375 | struct thread_info *softirq_ctx[NR_CPUS]; |
@@ -392,10 +393,24 @@ void irq_ctx_init(void) | |||
392 | } | 393 | } |
393 | } | 394 | } |
394 | 395 | ||
396 | static inline void do_softirq_onstack(void) | ||
397 | { | ||
398 | struct thread_info *curtp, *irqtp; | ||
399 | |||
400 | curtp = current_thread_info(); | ||
401 | irqtp = softirq_ctx[smp_processor_id()]; | ||
402 | irqtp->task = curtp->task; | ||
403 | call_do_softirq(irqtp); | ||
404 | irqtp->task = NULL; | ||
405 | } | ||
406 | |||
407 | #else | ||
408 | #define do_softirq_onstack() __do_softirq() | ||
409 | #endif /* CONFIG_IRQSTACKS */ | ||
410 | |||
395 | void do_softirq(void) | 411 | void do_softirq(void) |
396 | { | 412 | { |
397 | unsigned long flags; | 413 | unsigned long flags; |
398 | struct thread_info *curtp, *irqtp; | ||
399 | 414 | ||
400 | if (in_interrupt()) | 415 | if (in_interrupt()) |
401 | return; | 416 | return; |
@@ -403,19 +418,18 @@ void do_softirq(void) | |||
403 | local_irq_save(flags); | 418 | local_irq_save(flags); |
404 | 419 | ||
405 | if (local_softirq_pending()) { | 420 | if (local_softirq_pending()) { |
406 | curtp = current_thread_info(); | 421 | account_system_vtime(current); |
407 | irqtp = softirq_ctx[smp_processor_id()]; | 422 | local_bh_disable(); |
408 | irqtp->task = curtp->task; | 423 | do_softirq_onstack(); |
409 | call_do_softirq(irqtp); | 424 | account_system_vtime(current); |
410 | irqtp->task = NULL; | 425 | __local_bh_enable(); |
411 | } | 426 | } |
412 | 427 | ||
413 | local_irq_restore(flags); | 428 | local_irq_restore(flags); |
414 | } | 429 | } |
415 | EXPORT_SYMBOL(do_softirq); | 430 | EXPORT_SYMBOL(do_softirq); |
416 | 431 | ||
417 | #endif /* CONFIG_IRQSTACKS */ | 432 | #ifdef CONFIG_PPC64 |
418 | |||
419 | static int __init setup_noirqdistrib(char *str) | 433 | static int __init setup_noirqdistrib(char *str) |
420 | { | 434 | { |
421 | distribute_irqs = 0; | 435 | distribute_irqs = 0; |