|
@@ -328,10 +328,19 @@ void irq_enter(void)
|
|
|
|
|
|
static inline void invoke_softirq(void)
|
|
|
{
|
|
|
- if (!force_irqthreads)
|
|
|
- __do_softirq();
|
|
|
- else
|
|
|
+ if (!force_irqthreads) {
|
|
|
+ /*
|
|
|
+ * We can safely execute softirq on the current stack if
|
|
|
+ * it is the irq stack, because it should be near empty
|
|
|
+ * at this stage. But we have no way to know if the arch
|
|
|
+ * calls irq_exit() on the irq stack. So call softirq
|
|
|
+ * in its own stack to prevent from any overrun on top
|
|
|
+ * of a potentially deep task stack.
|
|
|
+ */
|
|
|
+ do_softirq();
|
|
|
+ } else {
|
|
|
wakeup_softirqd();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static inline void tick_irq_exit(void)
|