History

irq_work: Also rcuwait for !IRQ_WORK_HARD_IRQ on PREEMPT_RT

On PREEMPT_RT most items are processed as LAZY via softirq context. Avoid to spin-wait for them because irq_work_sync() could have higher priority and not allow the irq-work to be completed. Wait additionally for !IRQ_WORK_HARD_IRQ irq_work items on PREEMPT_RT.

Sebastian Andrzej Siewior committed 5 years ago

Commit 09089db1 parent b4c6f862 files · +9 −2Browse files

Showing the changes to kernel (1 of 2 files). Show all

Unified · Split

kernel/irq_work.c+4−2
@@ -217,7 +217,8 @@ void irq_work_single(void *arg) · 216 unmodified lines
217217 */
218218 (void)atomic_cmpxchg(&work->node.a_flags, flags, flags & ~IRQ_WORK_BUSY);
219219
220− if (!arch_irq_work_has_interrupt())
220+ if ((IS_ENABLED(CONFIG_PREEMPT_RT) && !irq_work_is_hard(work)) ||
221+ !arch_irq_work_has_interrupt())
221222 rcuwait_wake_up(&work->irqwait);
222223 }
223224
@@ -277,7 +278,8 @@ void irq_work_sync(struct irq_work *work) · 53 unmodified lines
277278 lockdep_assert_irqs_enabled();
278279 might_sleep();
279280
280− if (!arch_irq_work_has_interrupt()) {
281+ if ((IS_ENABLED(CONFIG_PREEMPT_RT) && !irq_work_is_hard(work)) ||
282+ !arch_irq_work_has_interrupt()) {
281283 rcuwait_wait_event(&work->irqwait, !irq_work_is_busy(work),
282284 TASK_UNINTERRUPTIBLE);
283285 return;