lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 13 May 2020 18:27:30 +0200
From:   Sebastian Andrzej Siewior <bigeasy@...utronix.de>
To:     linux-kernel@...r.kernel.org
Cc:     Tejun Heo <tj@...nel.org>, Lai Jiangshan <jiangshanlai@...il.com>,
        Peter Zijlstra <peterz@...radead.org>,
        Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...nel.org>,
        Linus Torvalds <torvalds@...ux-foundation.org>,
        Sebastian Andrzej Siewior <bigeasy@...utronix.de>
Subject: [PATCH 1/3] sched/swait: Add swait_event_lock_irq()

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@...utronix.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ