summaryrefslogtreecommitdiff
path: root/kernel/printk
diff options
context:
space:
mode:
authorPetr Mladek <pmladek@suse.com>2024-11-18 14:07:05 +0100
committerPetr Mladek <pmladek@suse.com>2024-11-18 14:07:05 +0100
commit34767e5357fc8051b192ff3fd921ade7c1b37c46 (patch)
tree9a5035eed562a39281164e4ab95e5ea818d073f6 /kernel/printk
parenta961ec4e2860af4933e8c1763fe4f038c2d6ac80 (diff)
parentda115c4ee29f589bb72ec2e86eb5e196b6bbcb41 (diff)
Merge branch 'for-6.13-force-console' into for-linus
Diffstat (limited to 'kernel/printk')
-rw-r--r--kernel/printk/internal.h3
-rw-r--r--kernel/printk/printk.c21
-rw-r--r--kernel/printk/printk_safe.c18
3 files changed, 37 insertions, 5 deletions
diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h
index 3fcb48502adb..c6bb47666aef 100644
--- a/kernel/printk/internal.h
+++ b/kernel/printk/internal.h
@@ -53,6 +53,8 @@ int devkmsg_sysctl_set_loglvl(const struct ctl_table *table, int write,
/* Flags for a single printk record. */
enum printk_info_flags {
+ /* always show on console, ignore console_loglevel */
+ LOG_FORCE_CON = 1,
LOG_NEWLINE = 2, /* text ended with a newline */
LOG_CONT = 8, /* text is a fragment of a continuation line */
};
@@ -90,6 +92,7 @@ bool printk_percpu_data_ready(void);
void defer_console_output(void);
bool is_printk_legacy_deferred(void);
+bool is_printk_force_console(void);
u16 printk_parse_prefix(const char *text, int *level,
enum printk_info_flags *flags);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 968830cfc606..d27a64d58023 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1337,11 +1337,11 @@ static void boot_delay_msec(int level)
{
unsigned long long k;
unsigned long timeout;
+ bool suppress = !is_printk_force_console() &&
+ suppress_message_printing(level);
- if ((boot_delay == 0 || system_state >= SYSTEM_RUNNING)
- || suppress_message_printing(level)) {
+ if ((boot_delay == 0 || system_state >= SYSTEM_RUNNING) || suppress)
return;
- }
k = (unsigned long long)loops_per_msec * boot_delay;
@@ -2291,6 +2291,9 @@ int vprintk_store(int facility, int level,
if (dev_info)
flags |= LOG_NEWLINE;
+ if (is_printk_force_console())
+ flags |= LOG_FORCE_CON;
+
if (flags & LOG_CONT) {
prb_rec_init_wr(&r, reserve_size);
if (prb_reserve_in_last(&e, prb, &r, caller_id, PRINTKRB_RECORD_MAX)) {
@@ -2298,6 +2301,9 @@ int vprintk_store(int facility, int level,
facility, &flags, fmt, args);
r.info->text_len += text_len;
+ if (flags & LOG_FORCE_CON)
+ r.info->flags |= LOG_FORCE_CON;
+
if (flags & LOG_NEWLINE) {
r.info->flags |= LOG_NEWLINE;
prb_final_commit(&e);
@@ -2965,6 +2971,7 @@ bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
struct printk_info info;
struct printk_record r;
size_t len = 0;
+ bool force_con;
/*
* Formatting extended messages requires a separate buffer, so use the
@@ -2983,9 +2990,13 @@ bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
pmsg->seq = r.info->seq;
pmsg->dropped = r.info->seq - seq;
+ force_con = r.info->flags & LOG_FORCE_CON;
- /* Skip record that has level above the console loglevel. */
- if (may_suppress && suppress_message_printing(r.info->level))
+ /*
+ * Skip records that are not forced to be printed on consoles and that
+ * has level above the console loglevel.
+ */
+ if (!force_con && may_suppress && suppress_message_printing(r.info->level))
goto out;
if (is_extended) {
diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c
index 2b35a9d3919d..6f94418d53ff 100644
--- a/kernel/printk/printk_safe.c
+++ b/kernel/printk/printk_safe.c
@@ -12,6 +12,24 @@
#include "internal.h"
+/* Context where printk messages are never suppressed */
+static atomic_t force_con;
+
+void printk_force_console_enter(void)
+{
+ atomic_inc(&force_con);
+}
+
+void printk_force_console_exit(void)
+{
+ atomic_dec(&force_con);
+}
+
+bool is_printk_force_console(void)
+{
+ return atomic_read(&force_con);
+}
+
static DEFINE_PER_CPU(int, printk_context);
/* Can be preempted by NMI. */