diff options
Diffstat (limited to 'kernel/softirq.c')
-rw-r--r-- | kernel/softirq.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c index be3d3514c325..d7d498d8cc4f 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -328,10 +328,19 @@ void irq_enter(void) | |||
328 | 328 | ||
329 | static inline void invoke_softirq(void) | 329 | static inline void invoke_softirq(void) |
330 | { | 330 | { |
331 | if (!force_irqthreads) | 331 | if (!force_irqthreads) { |
332 | __do_softirq(); | 332 | /* |
333 | else | 333 | * We can safely execute softirq on the current stack if |
334 | * it is the irq stack, because it should be near empty | ||
335 | * at this stage. But we have no way to know if the arch | ||
336 | * calls irq_exit() on the irq stack. So call softirq | ||
337 | * in its own stack to prevent from any overrun on top | ||
338 | * of a potentially deep task stack. | ||
339 | */ | ||
340 | do_softirq(); | ||
341 | } else { | ||
334 | wakeup_softirqd(); | 342 | wakeup_softirqd(); |
343 | } | ||
335 | } | 344 | } |
336 | 345 | ||
337 | static inline void tick_irq_exit(void) | 346 | static inline void tick_irq_exit(void) |
@@ -876,7 +885,6 @@ int __init __weak early_irq_init(void) | |||
876 | return 0; | 885 | return 0; |
877 | } | 886 | } |
878 | 887 | ||
879 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
880 | int __init __weak arch_probe_nr_irqs(void) | 888 | int __init __weak arch_probe_nr_irqs(void) |
881 | { | 889 | { |
882 | return NR_IRQS_LEGACY; | 890 | return NR_IRQS_LEGACY; |
@@ -886,4 +894,3 @@ int __init __weak arch_early_irq_init(void) | |||
886 | { | 894 | { |
887 | return 0; | 895 | return 0; |
888 | } | 896 | } |
889 | #endif | ||