Messages in this thread Patch in this message | | | From | Sebastian Andrzej Siewior <> | Subject | [PATCH 1/3] sched/swait: Add swait_event_lock_irq() | Date | Wed, 13 May 2020 18:27:30 +0200 |
| |
The workqueue code is currently not RT compatible due to nesting of regular spinlocks inside of raw spinlocks and locking of spinlocks inside of regions which are truly atomic even on a RT kernel.
One part of this problem are the wait queues as they use regular spinlocks internally.
The semantical requirements of the workqueue code are also met by simple waitqueues. This allows to solve the lock nesting problem because they use a raw spinlock to protect the waiter list.
But workqueues use wait_event_lock_irq() which is not yet provided by the simple waitqueue code.
Provide the straight forward counterpart to prepare for the conversion.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- include/linux/swait.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/include/linux/swait.h b/include/linux/swait.h index 73e06e9986d4b..d86bc68a39d3d 100644 --- a/include/linux/swait.h +++ b/include/linux/swait.h @@ -297,4 +297,30 @@ do { \ __ret; \ }) +#define __swait_event_lock_irq(wq, condition, lock, cmd) \ + ___swait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, \ + raw_spin_unlock_irq(&lock); \ + cmd; \ + schedule(); \ + raw_spin_lock_irq(&lock)) + +/** + * swait_event_lock_irq - Sleep until a condition gets true. + * @wq: The waitqueue to wait on. + * @condition: A C expression for the event to wait for. + * @lock: A locked raw_spinlock_t which will be released during schedule(). + * + * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the @condition + * evaluates to true. The @condition is checked each time the waitqueue @wq is + * woken up with @lock acquired. The @lock is released during schedule(). The + * function must be invoked with the lock acquired and it exits with the lock + * acquired. + */ +#define swait_event_lock_irq(wq, condition, lock) \ + do { \ + if (condition) \ + break; \ + __swait_event_lock_irq(wq, condition, lock, ); \ + } while (0) + #endif /* _LINUX_SWAIT_H */ -- 2.26.2
| |