From: John Ogness <john.ogness@linutronix.de>
To: Petr Mladek <pmladek@suse.com>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>,
Steven Rostedt <rostedt@goodmis.org>,
Thomas Gleixner <tglx@linutronix.de>,
linux-kernel@vger.kernel.org,
Peter Zijlstra <peterz@infradead.org>,
"Paul E. McKenney" <paulmck@kernel.org>
Subject: [PATCH next v2 2/2] printk: fix cpu lock ordering
Date: Mon, 7 Jun 2021 22:02:32 +0200 [thread overview]
Message-ID: <20210607200232.22211-3-john.ogness@linutronix.de> (raw)
In-Reply-To: <20210607200232.22211-1-john.ogness@linutronix.de>
The cpu lock implementation uses a full memory barrier to take
the lock, but no memory barriers when releasing the lock. This
means that changes performed by a lock owner may not be seen by
the next lock owner. This may have been "good enough" for use
by dump_stack() as a serialization mechanism, but it is not
enough to provide proper protection for a critical section.
Correct this problem by using acquire/release memory barriers
for lock/unlock, respectively.
Note that it is not necessary for a cpu lock to disable
interrupts. However, in upcoming work this cpu lock will be used
for emergency tasks (for example, atomic consoles during kernel
crashes) and any interruptions should be avoided if possible.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
kernel/printk/printk.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index f94babb38493..8c870581cfb4 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3560,10 +3560,29 @@ void printk_cpu_lock_irqsave(bool *lock_flag, unsigned long *irq_flags)
cpu = smp_processor_id();
- old = atomic_cmpxchg(&printk_cpulock_owner, -1, cpu);
+ /*
+ * Guarantee loads and stores from the previous lock owner are
+ * visible to this CPU once it is the lock owner. This pairs
+ * with cpu_unlock:B.
+ *
+ * Memory barrier involvement:
+ *
+ * If cpu_lock:A reads from cpu_unlock:B, then cpu_lock:B
+ * reads from cpu_unlock:A.
+ *
+ * Relies on:
+ *
+ * RELEASE from cpu_unlock:A to cpu_unlock:B
+ * matching
+ * ACQUIRE from cpu_lock:A to cpu_lock:B
+ */
+ old = atomic_cmpxchg_acquire(&printk_cpulock_owner,
+ -1, cpu); /* LMM(cpu_lock:A) */
if (old == -1) {
/* This CPU is now the owner. */
+ /* This CPU begins loading/storing data: LMM(cpu_lock:B) */
+
*lock_flag = true;
} else if (old == cpu) {
@@ -3600,7 +3619,14 @@ EXPORT_SYMBOL(printk_cpu_lock_irqsave);
void printk_cpu_unlock_irqrestore(bool lock_flag, unsigned long irq_flags)
{
if (lock_flag) {
- atomic_set(&printk_cpulock_owner, -1);
+ /* This CPU is finished loading/storing data: LMM(cpu_unlock:A) */
+
+ /*
+ * Guarantee loads and stores from this CPU when it was the
+ * lock owner are visible to the next lock owner. This pairs
+ * with cpu_lock:A.
+ */
+ atomic_set_release(&printk_cpulock_owner, -1); /* LMM(cpu_unlock:B) */
local_irq_restore(irq_flags);
}
--
2.20.1
next prev parent reply other threads:[~2021-06-07 20:02 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-07 20:02 [PATCH next v2 0/2] introduce printk cpu lock John Ogness
2021-06-07 20:02 ` [PATCH next v2 1/2] dump_stack: move cpu lock to printk.c John Ogness
2021-06-08 2:43 ` kernel test robot
2021-06-08 13:48 ` Petr Mladek
2021-06-10 13:26 ` John Ogness
2021-06-11 7:00 ` Petr Mladek
2021-06-08 11:40 ` Petr Mladek
2021-06-08 13:55 ` John Ogness
2021-06-08 14:54 ` Petr Mladek
2021-06-07 20:02 ` John Ogness [this message]
2021-06-08 12:55 ` [PATCH next v2 2/2] printk: fix cpu lock ordering Petr Mladek
2021-06-08 14:18 ` John Ogness
2021-06-08 14:49 ` Petr Mladek
2021-06-10 14:44 ` John Ogness
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210607200232.22211-3-john.ogness@linutronix.de \
--to=john.ogness@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=rostedt@goodmis.org \
--cc=senozhatsky@chromium.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®