summaryrefslogtreecommitdiff
path: root/kernel/printk/internal.h
diff options
context:
space:
mode:
authorJohn Ogness <john.ogness@linutronix.de>2023-01-09 11:13:57 +0106
committerPetr Mladek <pmladek@suse.com>2023-01-11 15:35:11 +0100
commit2830eec14afd18c7af333b5222f47a1244adea11 (patch)
treea19777945d6de3e367b0e64939f6f6b75e1bb0cf /kernel/printk/internal.h
parentdaaab5b5bba36a5aef790230b610556b9bbd9cfc (diff)
printk: introduce printk_get_next_message() and printk_message
Code for performing the console output is intermixed with code that is formatting the output for that console. Introduce a new helper function printk_get_next_message() to handle the reading and formatting of the printk text. The helper does not require any locking so that in the future it can be used for other printing contexts as well. This also introduces a new struct printk_message to wrap the struct printk_buffers, adding metadata about its contents. This allows users of printk_get_next_message() to receive all relevant information about the message that was read and formatted. Why is struct printk_message a wrapper struct? It is intentional that a wrapper struct is introduced instead of adding the metadata directly to struct printk_buffers. The upcoming atomic consoles support multiple printing contexts per CPU. This means that while a CPU is formatting a message, it can be interrupted and the interrupting context may also format a (possibly different) message. Since the printk buffers are rather large, there will only be one struct printk_buffers per CPU and it must be shared by the possible contexts of that CPU. If the metadata was part of struct printk_buffers, interrupting contexts would clobber the metadata being prepared by the interrupted context. This could be handled by robustifying the message formatting functions to cope with metadata unexpectedly changing. However, this would require significant amounts of extra data copying, also adding significant complexity to the code. Instead, the metadata can live on the stack of the formatting context and the message formatting functions do not need to be concerned about the metadata changing underneath them. Note that the message formatting functions can handle unexpected text buffer changes. So it is perfectly OK if a shared text buffer is clobbered by an interrupting context. The atomic console implementation will recognize the interruption and avoid printing the (probably garbage) text buffer. Signed-off-by: John Ogness <john.ogness@linutronix.de> Reviewed-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Petr Mladek <pmladek@suse.com> Link: https://lore.kernel.org/r/20230109100800.1085541-6-john.ogness@linutronix.de
Diffstat (limited to 'kernel/printk/internal.h')
-rw-r--r--kernel/printk/internal.h16
1 files changed, 16 insertions, 0 deletions
diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h
index 6080d289a342..c9bb0cd86372 100644
--- a/kernel/printk/internal.h
+++ b/kernel/printk/internal.h
@@ -92,3 +92,19 @@ struct printk_buffers {
char outbuf[CONSOLE_EXT_LOG_MAX];
char scratchbuf[LOG_LINE_MAX];
};
+
+/**
+ * struct printk_message - Container for a prepared printk message.
+ * @pbufs: printk buffers used to prepare the message.
+ * @outbuf_len: The length of prepared text in @pbufs->outbuf to output. This
+ * does not count the terminator. A value of 0 means there is
+ * nothing to output and this record should be skipped.
+ * @seq: The sequence number of the record used for @pbufs->outbuf.
+ * @dropped: The number of dropped records from reading @seq.
+ */
+struct printk_message {
+ struct printk_buffers *pbufs;
+ unsigned int outbuf_len;
+ u64 seq;
+ unsigned long dropped;
+};