summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0080-printk-nbcon-Add-sequence-handling.patch
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/patches-rt/0080-printk-nbcon-Add-sequence-handling.patch311
1 files changed, 0 insertions, 311 deletions
diff --git a/debian/patches-rt/0080-printk-nbcon-Add-sequence-handling.patch b/debian/patches-rt/0080-printk-nbcon-Add-sequence-handling.patch
deleted file mode 100644
index 3988d6124a..0000000000
--- a/debian/patches-rt/0080-printk-nbcon-Add-sequence-handling.patch
+++ /dev/null
@@ -1,311 +0,0 @@
-From: Thomas Gleixner <tglx@linutronix.de>
-Date: Sat, 16 Sep 2023 21:26:05 +0206
-Subject: [PATCH 080/134] printk: nbcon: Add sequence handling
-Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.6/older/patches-6.6.7-rt18.tar.xz
-
-Add an atomic_long_t field @nbcon_seq to the console struct to
-store the sequence number for nbcon consoles. For nbcon consoles
-this will be used instead of the non-atomic @seq field. The new
-field allows for safe atomic sequence number updates without
-requiring any locking.
-
-On 64bit systems the new field stores the full sequence number.
-On 32bit systems the new field stores the lower 32 bits of the
-sequence number, which are expanded to 64bit as needed by
-folding the values based on the sequence numbers available in
-the ringbuffer.
-
-For 32bit systems, having a 32bit representation in the console
-is sufficient. If a console ever gets more than 2^31 records
-behind the ringbuffer then this is the least of the problems.
-
-Co-developed-by: John Ogness <john.ogness@linutronix.de>
-Signed-off-by: John Ogness <john.ogness@linutronix.de>
-Signed-off-by: Thomas Gleixner (Intel) <tglx@linutronix.de>
-Signed-off-by: Petr Mladek <pmladek@suse.com>
-Link: https://lore.kernel.org/r/20230916192007.608398-7-john.ogness@linutronix.de
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
----
- include/linux/console.h | 4 +
- kernel/printk/internal.h | 7 +++
- kernel/printk/nbcon.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++
- kernel/printk/printk.c | 31 +++++++++++---
- 4 files changed, 136 insertions(+), 7 deletions(-)
-
---- a/include/linux/console.h
-+++ b/include/linux/console.h
-@@ -243,6 +243,7 @@ struct printk_buffers;
- * might cause a system freeze when the console
- * is used later.
- * @pbufs: Pointer to the text buffer for this context
-+ * @seq: The sequence number to print for this context
- */
- struct nbcon_context {
- /* members set by caller */
-@@ -253,6 +254,7 @@ struct nbcon_context {
-
- /* members set by acquire */
- struct printk_buffers *pbufs;
-+ u64 seq;
- };
-
- /**
-@@ -276,6 +278,7 @@ struct nbcon_context {
- * @node: hlist node for the console list
- *
- * @nbcon_state: State for nbcon consoles
-+ * @nbcon_seq: Sequence number of the next record for nbcon to print
- * @pbufs: Pointer to nbcon private buffer
- */
- struct console {
-@@ -299,6 +302,7 @@ struct console {
-
- /* nbcon console specific members */
- atomic_t __private nbcon_state;
-+ atomic_long_t __private nbcon_seq;
- struct printk_buffers *pbufs;
- };
-
---- a/kernel/printk/internal.h
-+++ b/kernel/printk/internal.h
-@@ -4,6 +4,7 @@
- */
- #include <linux/percpu.h>
- #include <linux/console.h>
-+#include "printk_ringbuffer.h"
-
- #if defined(CONFIG_PRINTK) && defined(CONFIG_SYSCTL)
- void __init printk_sysctl_init(void);
-@@ -42,6 +43,8 @@ enum printk_info_flags {
- LOG_CONT = 8, /* text is a fragment of a continuation line */
- };
-
-+extern struct printk_ringbuffer *prb;
-+
- __printf(4, 0)
- int vprintk_store(int facility, int level,
- const struct dev_printk_info *dev_info,
-@@ -69,6 +72,8 @@ void defer_console_output(void);
- u16 printk_parse_prefix(const char *text, int *level,
- enum printk_info_flags *flags);
-
-+u64 nbcon_seq_read(struct console *con);
-+void nbcon_seq_force(struct console *con, u64 seq);
- bool nbcon_alloc(struct console *con);
- void nbcon_init(struct console *con);
- void nbcon_free(struct console *con);
-@@ -88,6 +93,8 @@ void nbcon_free(struct console *con);
- #define printk_safe_exit_irqrestore(flags) local_irq_restore(flags)
-
- static inline bool printk_percpu_data_ready(void) { return false; }
-+static inline u64 nbcon_seq_read(struct console *con) { return 0; }
-+static inline void nbcon_seq_force(struct console *con, u64 seq) { }
- static inline bool nbcon_alloc(struct console *con) { return false; }
- static inline void nbcon_init(struct console *con) { }
- static inline void nbcon_free(struct console *con) { }
---- a/kernel/printk/nbcon.c
-+++ b/kernel/printk/nbcon.c
-@@ -140,6 +140,101 @@ static inline bool nbcon_state_try_cmpxc
- return atomic_try_cmpxchg(&ACCESS_PRIVATE(con, nbcon_state), &cur->atom, new->atom);
- }
-
-+#ifdef CONFIG_64BIT
-+
-+#define __seq_to_nbcon_seq(seq) (seq)
-+#define __nbcon_seq_to_seq(seq) (seq)
-+
-+#else /* CONFIG_64BIT */
-+
-+#define __seq_to_nbcon_seq(seq) ((u32)seq)
-+
-+static inline u64 __nbcon_seq_to_seq(u32 nbcon_seq)
-+{
-+ u64 seq;
-+ u64 rb_next_seq;
-+
-+ /*
-+ * The provided sequence is only the lower 32 bits of the ringbuffer
-+ * sequence. It needs to be expanded to 64bit. Get the next sequence
-+ * number from the ringbuffer and fold it.
-+ *
-+ * Having a 32bit representation in the console is sufficient.
-+ * If a console ever gets more than 2^31 records behind
-+ * the ringbuffer then this is the least of the problems.
-+ *
-+ * Also the access to the ring buffer is always safe.
-+ */
-+ rb_next_seq = prb_next_seq(prb);
-+ seq = rb_next_seq - ((u32)rb_next_seq - nbcon_seq);
-+
-+ return seq;
-+}
-+
-+#endif /* CONFIG_64BIT */
-+
-+/**
-+ * nbcon_seq_read - Read the current console sequence
-+ * @con: Console to read the sequence of
-+ *
-+ * Return: Sequence number of the next record to print on @con.
-+ */
-+u64 nbcon_seq_read(struct console *con)
-+{
-+ unsigned long nbcon_seq = atomic_long_read(&ACCESS_PRIVATE(con, nbcon_seq));
-+
-+ return __nbcon_seq_to_seq(nbcon_seq);
-+}
-+
-+/**
-+ * nbcon_seq_force - Force console sequence to a specific value
-+ * @con: Console to work on
-+ * @seq: Sequence number value to set
-+ *
-+ * Only to be used during init (before registration) or in extreme situations
-+ * (such as panic with CONSOLE_REPLAY_ALL).
-+ */
-+void nbcon_seq_force(struct console *con, u64 seq)
-+{
-+ /*
-+ * If the specified record no longer exists, the oldest available record
-+ * is chosen. This is especially important on 32bit systems because only
-+ * the lower 32 bits of the sequence number are stored. The upper 32 bits
-+ * are derived from the sequence numbers available in the ringbuffer.
-+ */
-+ u64 valid_seq = max_t(u64, seq, prb_first_valid_seq(prb));
-+
-+ atomic_long_set(&ACCESS_PRIVATE(con, nbcon_seq), __seq_to_nbcon_seq(valid_seq));
-+
-+ /* Clear con->seq since nbcon consoles use con->nbcon_seq instead. */
-+ con->seq = 0;
-+}
-+
-+/**
-+ * nbcon_seq_try_update - Try to update the console sequence number
-+ * @ctxt: Pointer to an acquire context that contains
-+ * all information about the acquire mode
-+ * @new_seq: The new sequence number to set
-+ *
-+ * @ctxt->seq is updated to the new value of @con::nbcon_seq (expanded to
-+ * the 64bit value). This could be a different value than @new_seq if
-+ * nbcon_seq_force() was used or the current context no longer owns the
-+ * console. In the later case, it will stop printing anyway.
-+ */
-+__maybe_unused
-+static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)
-+{
-+ unsigned long nbcon_seq = __seq_to_nbcon_seq(ctxt->seq);
-+ struct console *con = ctxt->console;
-+
-+ if (atomic_long_try_cmpxchg(&ACCESS_PRIVATE(con, nbcon_seq), &nbcon_seq,
-+ __seq_to_nbcon_seq(new_seq))) {
-+ ctxt->seq = new_seq;
-+ } else {
-+ ctxt->seq = nbcon_seq_read(con);
-+ }
-+}
-+
- /**
- * nbcon_context_try_acquire_direct - Try to acquire directly
- * @ctxt: The context of the caller
-@@ -510,6 +605,9 @@ static bool nbcon_context_try_acquire(st
- else
- ctxt->pbufs = con->pbufs;
-
-+ /* Set the record sequence for this context to print. */
-+ ctxt->seq = nbcon_seq_read(ctxt->console);
-+
- return true;
- }
-
-@@ -722,6 +820,8 @@ bool nbcon_alloc(struct console *con)
- *
- * nbcon_alloc() *must* be called and succeed before this function
- * is called.
-+ *
-+ * This function expects that the legacy @con->seq has been set.
- */
- void nbcon_init(struct console *con)
- {
-@@ -730,6 +830,7 @@ void nbcon_init(struct console *con)
- /* nbcon_alloc() must have been called and successful! */
- BUG_ON(!con->pbufs);
-
-+ nbcon_seq_force(con, con->seq);
- nbcon_state_set(con, &state);
- }
-
---- a/kernel/printk/printk.c
-+++ b/kernel/printk/printk.c
-@@ -494,7 +494,7 @@ static u32 log_buf_len = __LOG_BUF_LEN;
-
- static struct printk_ringbuffer printk_rb_dynamic;
-
--static struct printk_ringbuffer *prb = &printk_rb_static;
-+struct printk_ringbuffer *prb = &printk_rb_static;
-
- /*
- * We cannot access per-CPU data (e.g. per-CPU flush irq_work) before
-@@ -3168,6 +3168,7 @@ void console_flush_on_panic(enum con_flu
-
- if (mode == CONSOLE_REPLAY_ALL) {
- struct console *c;
-+ short flags;
- int cookie;
- u64 seq;
-
-@@ -3175,11 +3176,17 @@ void console_flush_on_panic(enum con_flu
-
- cookie = console_srcu_read_lock();
- for_each_console_srcu(c) {
-- /*
-- * This is an unsynchronized assignment, but the
-- * kernel is in "hope and pray" mode anyway.
-- */
-- c->seq = seq;
-+ flags = console_srcu_read_flags(c);
-+
-+ if (flags & CON_NBCON) {
-+ nbcon_seq_force(c, seq);
-+ } else {
-+ /*
-+ * This is an unsynchronized assignment. On
-+ * panic legacy consoles are only best effort.
-+ */
-+ c->seq = seq;
-+ }
- }
- console_srcu_read_unlock(cookie);
- }
-@@ -3750,6 +3757,7 @@ static bool __pr_flush(struct console *c
- struct console *c;
- u64 last_diff = 0;
- u64 printk_seq;
-+ short flags;
- int cookie;
- u64 diff;
- u64 seq;
-@@ -3777,6 +3785,9 @@ static bool __pr_flush(struct console *c
- for_each_console_srcu(c) {
- if (con && con != c)
- continue;
-+
-+ flags = console_srcu_read_flags(c);
-+
- /*
- * If consoles are not usable, it cannot be expected
- * that they make forward progress, so only increment
-@@ -3784,7 +3795,13 @@ static bool __pr_flush(struct console *c
- */
- if (!console_is_usable(c))
- continue;
-- printk_seq = c->seq;
-+
-+ if (flags & CON_NBCON) {
-+ printk_seq = nbcon_seq_read(c);
-+ } else {
-+ printk_seq = c->seq;
-+ }
-+
- if (printk_seq < seq)
- diff += seq - printk_seq;
- }