Hi,
This is v4 of a series to cleanup console buffer handling and
prepare for code sharing with the upcoming threaded/atomic
consoles. v3 is here [0].
The main purpose of the series is to introduce two new lockless
functions to handle reading and formatting of printk messages. These
functions can then be used from any context, which is important for
the upcoming threaded/atomic consoles. The series also helps to
cleanup some of the internal printk interfaces and cleanly separate
formatting code from outputting code.
Some changes in this version were not part of the feedback. However,
from the discussions and examples I decided that some of the names
I had previously chosen were not appropriate. Particularly, structs,
variables, and functions should only use the "console_" prefix if it
is console-specific. Things that are used for general printk
processing should use a "printk_" prefix. This makes the diff to v3
rather large, even though the "real code" has only minor changes.
@Petr: Like with v3, this version uses a wrapper struct for the
message metadata to avoid clobbering. Making the message formatting
code robust enough to handle metadata clobbering was too complex
(particularly with the dropped tracking).
Changes since v3:
- Provide a detailed explanation in the commit message about why
message metadata is put into a wrapper struct instead of the
buffer struct.
- Reorder stack variable definitions so that static variables are at
the top and separated from non-static variables. IMHO it is
important to clearly see which of the variables are static.
- Drop a previous coding-style change from a line not related to
this series.
- In console_prepend_dropped() make sure the buffer is large enough
for the dropped message and at least PREFIX_MAX of the current
message.
- Define the PREFIX_MAX macro for !CONFIG_PRINTK in internal.h
because console_prepend_dropped() now needs it.
- Rename various functions, structs, fields, and macros:
console_get_next_message() -> printk_get_next_message()
struct console_buffers -> struct printk_buffers
struct console_message -> struct printk_message
console_message.cbufs -> printk_message.pbufs
console_message.outbuf_seq -> printk_message.seq
LOG_LINE_MAX -> PRINTKRB_RECORD_MAX
PREFIX_MAX -> PRINTK_PREFIX_MAX
CONSOLE_LOG_MAX and
CONSOLE_EXT_LOG_MAX -> PRINTK_MESSAGE_MAX
- Adjust the values of string limit macros. This is explained in
detail in the commit message.
- Replace @buf and @text_buf in struct devkmsg_user with struct
printk_buffers.
- Replace message formatting code in devkmsg_read() with
printk_get_next_message().
- Define all printk_message structs on the stack.
John Ogness
[0] https://lore.kernel.org/lkml/[email protected]
John Ogness (6):
printk: move size limit macros into internal.h
printk: introduce struct printk_buffers
printk: introduce printk_get_next_message() and printk_message
printk: introduce console_prepend_dropped() for dropped messages
printk: use printk_buffers for devkmsg
printk: adjust string limit macros
Thomas Gleixner (2):
console: Use BIT() macros for @flags values
console: Document struct console
include/linux/console.h | 100 +++++++++----
include/linux/printk.h | 2 -
kernel/printk/internal.h | 45 ++++++
kernel/printk/printk.c | 293 +++++++++++++++++++++++----------------
4 files changed, 288 insertions(+), 152 deletions(-)
base-commit: 6b2b0d839acaa84f05a77184370f793752e786e9
--
2.30.2
Currently "dropped messages" are separately printed immediately
before printing the printk message. Since normal consoles are
now using an output buffer that is much larger than previously,
the "dropped message" could be prepended to the printk message
and then output everything in a single write() call.
Introduce a helper function console_prepend_dropped() to prepend
an existing message with a "dropped message". This simplifies
the code by allowing all message formatting to be handled
together and then only requires a single write() call to output
the full message. And since this helper does not require any
locking, it can be used in the future for other console printing
contexts as well.
Signed-off-by: John Ogness <[email protected]>
---
kernel/printk/internal.h | 4 --
kernel/printk/printk.c | 86 ++++++++++++++++++++++++++--------------
2 files changed, 57 insertions(+), 33 deletions(-)
diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h
index c9bb0cd86372..72df730597f1 100644
--- a/kernel/printk/internal.h
+++ b/kernel/printk/internal.h
@@ -26,9 +26,6 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
/* the maximum size of a formatted extended record */
#define CONSOLE_EXT_LOG_MAX 8192
-/* the maximum size for a dropped text message */
-#define DROPPED_TEXT_MAX 64
-
/* the maximum size allowed to be reserved for a record */
#define LOG_LINE_MAX (CONSOLE_LOG_MAX - PREFIX_MAX)
@@ -69,7 +66,6 @@ u16 printk_parse_prefix(const char *text, int *level,
#define PREFIX_MAX 0
#define CONSOLE_LOG_MAX 0
#define CONSOLE_EXT_LOG_MAX 0
-#define DROPPED_TEXT_MAX 0
#define LOG_LINE_MAX 0
/*
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 6e2a6d5548e9..4fb7d29fb05d 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1995,27 +1995,6 @@ static int console_trylock_spinning(void)
return 1;
}
-/*
- * Call the specified console driver, asking it to write out the specified
- * text and length. If @dropped_text is non-NULL and any records have been
- * dropped, a dropped message will be written out first.
- */
-static void call_console_driver(struct console *con, const char *text, size_t len,
- char *dropped_text)
-{
- size_t dropped_len;
-
- if (con->dropped && dropped_text) {
- dropped_len = snprintf(dropped_text, DROPPED_TEXT_MAX,
- "** %lu printk messages dropped **\n",
- con->dropped);
- con->dropped = 0;
- con->write(con, dropped_text, dropped_len);
- }
-
- con->write(con, text, len);
-}
-
/*
* Recursion is tracked separately on each CPU. If NMIs are supported, an
* additional NMI context per CPU is also separately tracked. Until per-CPU
@@ -2395,10 +2374,6 @@ static ssize_t msg_print_ext_body(char *buf, size_t size,
struct dev_printk_info *dev_info) { return 0; }
static void console_lock_spinning_enable(void) { }
static int console_lock_spinning_disable_and_check(int cookie) { return 0; }
-static void call_console_driver(struct console *con, const char *text, size_t len,
- char *dropped_text)
-{
-}
static bool suppress_message_printing(int level) { return false; }
static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; }
static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; }
@@ -2724,6 +2699,52 @@ static void __console_unlock(void)
up_console_sem();
}
+/*
+ * Prepend the message in @pmsg->pbufs->outbuf with a "dropped message". This
+ * is achieved by shifting the existing message over and inserting the dropped
+ * message.
+ *
+ * @pmsg is the printk message to prepend.
+ *
+ * @dropped is the dropped count to report in the dropped message.
+ *
+ * If the message text in @pmsg->pbufs->outbuf does not have enough space for
+ * the dropped message, the message text will be sufficiently truncated.
+ *
+ * If @pmsg->pbufs->outbuf is modified, @pmsg->outbuf_len is updated.
+ */
+static void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped)
+{
+ struct printk_buffers *pbufs = pmsg->pbufs;
+ const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf);
+ const size_t outbuf_sz = sizeof(pbufs->outbuf);
+ char *scratchbuf = &pbufs->scratchbuf[0];
+ char *outbuf = &pbufs->outbuf[0];
+ size_t len;
+
+ len = snprintf(scratchbuf, scratchbuf_sz,
+ "** %lu printk messages dropped **\n", dropped);
+
+ /*
+ * Make sure outbuf is sufficiently large before prepending.
+ * Keep at least the prefix when the message must be truncated.
+ * It is a rather theoretical problem when someone tries to
+ * use a minimalist buffer.
+ */
+ if (WARN_ON_ONCE(len + PREFIX_MAX >= outbuf_sz))
+ return;
+
+ if (pmsg->outbuf_len + len >= outbuf_sz) {
+ /* Truncate the message, but keep it terminated. */
+ pmsg->outbuf_len = outbuf_sz - (len + 1);
+ outbuf[pmsg->outbuf_len] = 0;
+ }
+
+ memmove(outbuf + len, outbuf, pmsg->outbuf_len + 1);
+ memcpy(outbuf, scratchbuf, len);
+ pmsg->outbuf_len += len;
+}
+
/*
* Read and format the specified record (or a later record if the specified
* record is not available).
@@ -2817,7 +2838,6 @@ static bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
*/
static bool console_emit_next_record(struct console *con, bool *handover, int cookie)
{
- static char dropped_text[DROPPED_TEXT_MAX];
static struct printk_buffers pbufs;
bool is_extended = console_srcu_read_flags(con) & CON_EXTENDED;
@@ -2840,6 +2860,11 @@ static bool console_emit_next_record(struct console *con, bool *handover, int co
goto skip;
}
+ if (con->dropped && !is_extended) {
+ console_prepend_dropped(&pmsg, con->dropped);
+ con->dropped = 0;
+ }
+
/*
* While actively printing out messages, if another printk()
* were to occur on another CPU, it may wait for this one to
@@ -2853,9 +2878,12 @@ static bool console_emit_next_record(struct console *con, bool *handover, int co
printk_safe_enter_irqsave(flags);
console_lock_spinning_enable();
- stop_critical_timings(); /* don't trace print latency */
- call_console_driver(con, outbuf, pmsg.outbuf_len,
- is_extended ? NULL : dropped_text);
+ /* Do not trace print latency. */
+ stop_critical_timings();
+
+ /* Write everything out to the hardware. */
+ con->write(con, outbuf, pmsg.outbuf_len);
+
start_critical_timings();
con->seq = pmsg.seq + 1;
--
2.30.2
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 <[email protected]>
---
kernel/printk/internal.h | 16 ++++++
kernel/printk/printk.c | 115 +++++++++++++++++++++++++++------------
2 files changed, 96 insertions(+), 35 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;
+};
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index bc5d4574c459..6e2a6d5548e9 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2725,35 +2725,35 @@ static void __console_unlock(void)
}
/*
- * Print one record for the given console. The record printed is whatever
- * record is the next available record for the given console.
+ * Read and format the specified record (or a later record if the specified
+ * record is not available).
*
- * @handover will be set to true if a printk waiter has taken over the
- * console_lock, in which case the caller is no longer holding both the
- * console_lock and the SRCU read lock. Otherwise it is set to false.
+ * @pmsg will contain the formatted result. @pmsg->pbufs must point to a
+ * struct printk_buffers.
*
- * @cookie is the cookie from the SRCU read lock.
+ * @seq is the record to read and format. If it is not available, the next
+ * valid record is read.
*
- * Returns false if the given console has no next record to print, otherwise
- * true.
+ * @is_extended specifies if the message should be formatted for extended
+ * console output.
*
- * Requires the console_lock and the SRCU read lock.
+ * Returns false if no record is available. Otherwise true and all fields
+ * of @pmsg are valid. (See the documentation of struct printk_message
+ * for information about the @pmsg fields.)
*/
-static bool console_emit_next_record(struct console *con, bool *handover, int cookie)
+static bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
+ bool is_extended)
{
- static char dropped_text[DROPPED_TEXT_MAX];
- static struct printk_buffers pbufs;
static int panic_console_dropped;
- bool is_extended = console_srcu_read_flags(con) & CON_EXTENDED;
- const size_t scratchbuf_sz = sizeof(pbufs.scratchbuf);
- const size_t outbuf_sz = sizeof(pbufs.outbuf);
- char *scratchbuf = &pbufs.scratchbuf[0];
- char *outbuf = &pbufs.outbuf[0];
+ struct printk_buffers *pbufs = pmsg->pbufs;
+ const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf);
+ const size_t outbuf_sz = sizeof(pbufs->outbuf);
+ char *scratchbuf = &pbufs->scratchbuf[0];
+ char *outbuf = &pbufs->outbuf[0];
struct printk_info info;
struct printk_record r;
- unsigned long flags;
- size_t len;
+ size_t len = 0;
/*
* Formatting extended messages requires a separate buffer, so use the
@@ -2767,25 +2767,26 @@ static bool console_emit_next_record(struct console *con, bool *handover, int co
else
prb_rec_init_rd(&r, &info, outbuf, outbuf_sz);
- *handover = false;
-
- if (!prb_read_valid(prb, con->seq, &r))
+ if (!prb_read_valid(prb, seq, &r))
return false;
- if (con->seq != r.info->seq) {
- con->dropped += r.info->seq - con->seq;
- con->seq = r.info->seq;
- if (panic_in_progress() && panic_console_dropped++ > 10) {
- suppress_panic_printk = 1;
- pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n");
- }
+ pmsg->seq = r.info->seq;
+ pmsg->dropped = r.info->seq - seq;
+
+ /*
+ * Check for dropped messages in panic here so that printk
+ * suppression can occur as early as possible if necessary.
+ */
+ if (pmsg->dropped &&
+ panic_in_progress() &&
+ panic_console_dropped++ > 10) {
+ suppress_panic_printk = 1;
+ pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n");
}
/* Skip record that has level above the console loglevel. */
- if (suppress_message_printing(r.info->level)) {
- con->seq++;
- goto skip;
- }
+ if (suppress_message_printing(r.info->level))
+ goto out;
if (is_extended) {
len = info_print_ext_header(outbuf, outbuf_sz, r.info);
@@ -2794,6 +2795,50 @@ static bool console_emit_next_record(struct console *con, bool *handover, int co
} else {
len = record_print_text(&r, console_msg_format & MSG_FORMAT_SYSLOG, printk_time);
}
+out:
+ pmsg->outbuf_len = len;
+ return true;
+}
+
+/*
+ * Print one record for the given console. The record printed is whatever
+ * record is the next available record for the given console.
+ *
+ * @handover will be set to true if a printk waiter has taken over the
+ * console_lock, in which case the caller is no longer holding both the
+ * console_lock and the SRCU read lock. Otherwise it is set to false.
+ *
+ * @cookie is the cookie from the SRCU read lock.
+ *
+ * Returns false if the given console has no next record to print, otherwise
+ * true.
+ *
+ * Requires the console_lock and the SRCU read lock.
+ */
+static bool console_emit_next_record(struct console *con, bool *handover, int cookie)
+{
+ static char dropped_text[DROPPED_TEXT_MAX];
+ static struct printk_buffers pbufs;
+
+ bool is_extended = console_srcu_read_flags(con) & CON_EXTENDED;
+ char *outbuf = &pbufs.outbuf[0];
+ struct printk_message pmsg = {
+ .pbufs = &pbufs,
+ };
+ unsigned long flags;
+
+ *handover = false;
+
+ if (!printk_get_next_message(&pmsg, con->seq, is_extended))
+ return false;
+
+ con->dropped += pmsg.dropped;
+
+ /* Skip messages of formatted length 0. */
+ if (pmsg.outbuf_len == 0) {
+ con->seq = pmsg.seq + 1;
+ goto skip;
+ }
/*
* While actively printing out messages, if another printk()
@@ -2809,11 +2854,11 @@ static bool console_emit_next_record(struct console *con, bool *handover, int co
console_lock_spinning_enable();
stop_critical_timings(); /* don't trace print latency */
- call_console_driver(con, outbuf, len,
+ call_console_driver(con, outbuf, pmsg.outbuf_len,
is_extended ? NULL : dropped_text);
start_critical_timings();
- con->seq++;
+ con->seq = pmsg.seq + 1;
*handover = console_lock_spinning_disable_and_check(cookie);
printk_safe_exit_irqrestore(flags);
--
2.30.2
On Thu 2023-01-05 11:43:32, John Ogness wrote:
> 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.
Great description!
> Signed-off-by: John Ogness <[email protected]>
Reviewed-by: Petr Mladek <[email protected]>
Best Regards,
Petr
On Thu 2023-01-05 11:43:33, John Ogness wrote:
> Currently "dropped messages" are separately printed immediately
> before printing the printk message. Since normal consoles are
> now using an output buffer that is much larger than previously,
> the "dropped message" could be prepended to the printk message
> and then output everything in a single write() call.
>
> Introduce a helper function console_prepend_dropped() to prepend
> an existing message with a "dropped message". This simplifies
> the code by allowing all message formatting to be handled
> together and then only requires a single write() call to output
> the full message. And since this helper does not require any
> locking, it can be used in the future for other console printing
> contexts as well.
>
> Signed-off-by: John Ogness <[email protected]>
Reviewed-by: Petr Mladek <[email protected]>
A comment below.
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2724,6 +2699,52 @@ static void __console_unlock(void)
> up_console_sem();
> }
>
> +/*
> + * Prepend the message in @pmsg->pbufs->outbuf with a "dropped message". This
> + * is achieved by shifting the existing message over and inserting the dropped
> + * message.
> + *
> + * @pmsg is the printk message to prepend.
> + *
> + * @dropped is the dropped count to report in the dropped message.
> + *
> + * If the message text in @pmsg->pbufs->outbuf does not have enough space for
> + * the dropped message, the message text will be sufficiently truncated.
> + *
> + * If @pmsg->pbufs->outbuf is modified, @pmsg->outbuf_len is updated.
> + */
> +static void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped)
> +{
> + struct printk_buffers *pbufs = pmsg->pbufs;
> + const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf);
> + const size_t outbuf_sz = sizeof(pbufs->outbuf);
> + char *scratchbuf = &pbufs->scratchbuf[0];
> + char *outbuf = &pbufs->outbuf[0];
> + size_t len;
> +
> + len = snprintf(scratchbuf, scratchbuf_sz,
> + "** %lu printk messages dropped **\n", dropped);
> +
> + /*
> + * Make sure outbuf is sufficiently large before prepending.
> + * Keep at least the prefix when the message must be truncated.
> + * It is a rather theoretical problem when someone tries to
> + * use a minimalist buffer.
> + */
> + if (WARN_ON_ONCE(len + PREFIX_MAX >= outbuf_sz))
> + return;
I guess that this will always trigger the compiler warning
when CONFIG_PRINTK is disabled. See the report for v3 at
https://lore.kernel.org/r/[email protected]
Hmm, we might want to fix this warning so that it does not break
build with -Werror.
IMHO, the proper solution would be to define this function only when
CONFIG_PRINTK is defined. But it might require bigger changes
and define many more console functions only when CONFIG_PRINTK
is defined. This is out-of-scope of this patchset.
I wonder if the following would work as an "intermediate" workaround:
if (!IS_ENABLED(CONFIG_PRINTK) ||
WARN_ON_ONCE(len + PREFIX_MAX >= outbuf_sz))
return;
Best Regards,
Petr
On 2023-01-05, Petr Mladek <[email protected]> wrote:
>> + if (WARN_ON_ONCE(len + PREFIX_MAX >= outbuf_sz))
>> + return;
>
> I guess that this will always trigger the compiler warning
> when CONFIG_PRINTK is disabled. See the report for v3 at
> https://lore.kernel.org/r/[email protected]
That report is actually complaining about the check after this one. It
is the same "problem".
> Hmm, we might want to fix this warning so that it does not break
> build with -Werror.
>
> IMHO, the proper solution would be to define this function only when
> CONFIG_PRINTK is defined. But it might require bigger changes
> and define many more console functions only when CONFIG_PRINTK
> is defined. This is out-of-scope of this patchset.
>
> I wonder if the following would work as an "intermediate" workaround:
>
> if (!IS_ENABLED(CONFIG_PRINTK) ||
> WARN_ON_ONCE(len + PREFIX_MAX >= outbuf_sz))
> return;
The whole CONFIG_PRINTK stuff is a total mess right now. We should
definitely get that cleaned up at some point. As an intermediate
workaround, it might make more sense to just put the whole function
inside an "#ifdef CONFIG_PRINTK". It doesn't return anything anyway.
#ifdef CONFIG_PRINTK
static void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped)
{
...
}
#else
#define console_prepend_dropped(pmsg, dropped)
#endif
There are already places in the code that look like this (for example,
print_caller()).
Otherwise, if you want to use IS_ENABLED(), you will need it for both
checks.
John
On Thu 2023-01-05 17:41:59, John Ogness wrote:
> On 2023-01-05, Petr Mladek <[email protected]> wrote:
> >> + if (WARN_ON_ONCE(len + PREFIX_MAX >= outbuf_sz))
> >> + return;
> >
> > I guess that this will always trigger the compiler warning
> > when CONFIG_PRINTK is disabled. See the report for v3 at
> > https://lore.kernel.org/r/[email protected]
>
> That report is actually complaining about the check after this one. It
> is the same "problem".
I see.
> > Hmm, we might want to fix this warning so that it does not break
> > build with -Werror.
> >
> > IMHO, the proper solution would be to define this function only when
> > CONFIG_PRINTK is defined. But it might require bigger changes
> > and define many more console functions only when CONFIG_PRINTK
> > is defined. This is out-of-scope of this patchset.
> >
> > I wonder if the following would work as an "intermediate" workaround:
> >
> > if (!IS_ENABLED(CONFIG_PRINTK) ||
> > WARN_ON_ONCE(len + PREFIX_MAX >= outbuf_sz))
> > return;
>
> The whole CONFIG_PRINTK stuff is a total mess right now. We should
> definitely get that cleaned up at some point. As an intermediate
> workaround, it might make more sense to just put the whole function
> inside an "#ifdef CONFIG_PRINTK". It doesn't return anything anyway.
>
> #ifdef CONFIG_PRINTK
> static void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped)
> {
> ...
> }
> #else
> #define console_prepend_dropped(pmsg, dropped)
> #endif
Looks good.
The question is if we want to do it in this patch or as a follow up
fix.
I slightly prefer to do it as a follow up fix to avoid another respin.
Also we will not need to complicate this patch with explaining
why this is needed.
Best Regards,
Petr
On Thu 2023-01-05 11:43:27, John Ogness wrote:
> Hi,
>
> This is v4 of a series to cleanup console buffer handling and
> prepare for code sharing with the upcoming threaded/atomic
> consoles. v3 is here [0].
>
> The main purpose of the series is to introduce two new lockless
> functions to handle reading and formatting of printk messages. These
> functions can then be used from any context, which is important for
> the upcoming threaded/atomic consoles. The series also helps to
> cleanup some of the internal printk interfaces and cleanly separate
> formatting code from outputting code.
>
> John Ogness (6):
> printk: move size limit macros into internal.h
> printk: introduce struct printk_buffers
> printk: introduce printk_get_next_message() and printk_message
> printk: introduce console_prepend_dropped() for dropped messages
This patch would need a followup fix to prevent the compiler warning.
> printk: use printk_buffers for devkmsg
This one would need respin to fix the problem with suppressed messages.
> printk: adjust string limit macros
>
> Thomas Gleixner (2):
> console: Use BIT() macros for @flags values
> console: Document struct console
The rest looks ready for linux-next.
I see three ways how to move forward:
1. Respin the entire patchset.
2. Respin only 7th patch + send the follow up fix seperately
3. Push first 6 patches and handle the rest separately.
What would be more convenient for you, please?
Honestly, I do not have any real preference.
Best Regards,
Petr
On 2023-01-06, Petr Mladek <[email protected]> wrote:
> On Thu 2023-01-05 11:43:27, John Ogness wrote:
> I see three ways how to move forward:
>
> 1. Respin the entire patchset.
> 2. Respin only 7th patch + send the follow up fix seperately
> 3. Push first 6 patches and handle the rest separately.
I will respin the entire patchset. That is easist for me and makes
things quite straight forward for you.
I still am looking into and will to respond to your comments on patch
7/8 before I do the respin.
John