diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/rcutree_plugin.h | 2 | ||||
| -rw-r--r-- | kernel/softirq.c | 12 |
2 files changed, 11 insertions, 3 deletions
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index d9d7a89da8bb..8aafbb80b8b0 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
| @@ -318,7 +318,7 @@ static noinline void rcu_read_unlock_special(struct task_struct *t) | |||
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | /* Hardware IRQ handlers cannot block. */ | 320 | /* Hardware IRQ handlers cannot block. */ |
| 321 | if (in_irq()) { | 321 | if (in_irq() || in_serving_softirq()) { |
| 322 | local_irq_restore(flags); | 322 | local_irq_restore(flags); |
| 323 | return; | 323 | return; |
| 324 | } | 324 | } |
diff --git a/kernel/softirq.c b/kernel/softirq.c index 40cf63ddd4b3..fca82c32042b 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
| @@ -315,16 +315,24 @@ static inline void invoke_softirq(void) | |||
| 315 | { | 315 | { |
| 316 | if (!force_irqthreads) | 316 | if (!force_irqthreads) |
| 317 | __do_softirq(); | 317 | __do_softirq(); |
| 318 | else | 318 | else { |
| 319 | __local_bh_disable((unsigned long)__builtin_return_address(0), | ||
| 320 | SOFTIRQ_OFFSET); | ||
| 319 | wakeup_softirqd(); | 321 | wakeup_softirqd(); |
| 322 | __local_bh_enable(SOFTIRQ_OFFSET); | ||
| 323 | } | ||
| 320 | } | 324 | } |
| 321 | #else | 325 | #else |
| 322 | static inline void invoke_softirq(void) | 326 | static inline void invoke_softirq(void) |
| 323 | { | 327 | { |
| 324 | if (!force_irqthreads) | 328 | if (!force_irqthreads) |
| 325 | do_softirq(); | 329 | do_softirq(); |
| 326 | else | 330 | else { |
| 331 | __local_bh_disable((unsigned long)__builtin_return_address(0), | ||
| 332 | SOFTIRQ_OFFSET); | ||
| 327 | wakeup_softirqd(); | 333 | wakeup_softirqd(); |
| 334 | __local_bh_enable(SOFTIRQ_OFFSET); | ||
| 335 | } | ||
| 328 | } | 336 | } |
| 329 | #endif | 337 | #endif |
| 330 | 338 | ||
