History

Merge tag 'printk-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux

Pull printk updates from Petr Mladek: - Refactor printk code for formatting messages that are shown on consoles. This is a preparatory step for introducing atomic consoles which could not share the global buffers - Prevent memory leak when removing printk index in debugfs - Dump also the newest printk message by the sample gdbmacro - Fix a compiler warning * tag 'printk-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux: printf: fix errname.c list kernel/printk/index.c: fix memory leak with using debugfs_lookup() printk: Use scnprintf() to print the message about the dropped messages on a console printk: adjust string limit macros printk: use printk_buffers for devkmsg printk: introduce console_prepend_dropped() for dropped messages printk: introduce printk_get_next_message() and printk_message printk: introduce struct printk_buffers console: Document struct console console: Use BIT() macros for @flags values printk: move size limit macros into internal.h docs: gdbmacros: print newest record

Linus Torvalds committed 3 years ago

Commit d8763152 parents cd43b50 392143c7 files · +313 −168Browse files

Showing the changes to kernel (3 of 7 files). Show all

Unified · Split

3 files
  1. kernel/printk/index.c +1 −1
  2. kernel/printk/internal.h +45 −0
  3. kernel/printk/printk.c +179 −129
kernel/printk/index.c+1−1
@@ -145,7 +145,7 @@ static void pi_create_file(struct module *mod) · 144 unmodified lines
145145 #ifdef CONFIG_MODULES
146146 static void pi_remove_file(struct module *mod)
147147 {
148− debugfs_remove(debugfs_lookup(pi_get_module_name(mod), dfs_index));
148+ debugfs_lookup_and_remove(pi_get_module_name(mod), dfs_index);
149149 }
150150
151151 static int pi_module_notify(struct notifier_block *nb, unsigned long op,
kernel/printk/internal.h+45−0
@@ -14,6 +14,21 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, · 13 unmodified lines
1414
1515 #ifdef CONFIG_PRINTK
1616
17+#ifdef CONFIG_PRINTK_CALLER
18+#define PRINTK_PREFIX_MAX 48
19+#else
20+#define PRINTK_PREFIX_MAX 32
21+#endif
22+
23+/*
24+ * the maximum size of a formatted record (i.e. with prefix added
25+ * per line and dropped messages or in extended message format)
26+ */
27+#define PRINTK_MESSAGE_MAX 2048
28+
29+/* the maximum size allowed to be reserved for a record */
30+#define PRINTKRB_RECORD_MAX 1024
31+
1732 /* Flags for a single printk record. */
1833 enum printk_info_flags {
1934 LOG_NEWLINE = 2, /* text ended with a newline */
@@ -48,6 +63,10 @@ u16 printk_parse_prefix(const char *text, int *level, · 28 unmodified lines
4863 enum printk_info_flags *flags);
4964 #else
5065
66+#define PRINTK_PREFIX_MAX 0
67+#define PRINTK_MESSAGE_MAX 0
68+#define PRINTKRB_RECORD_MAX 0
69+
5170 /*
5271 * In !PRINTK builds we still export console_sem
5372 * semaphore and some of console functions (console_unlock()/etc.), so
@@ -58,3 +77,29 @@ u16 printk_parse_prefix(const char *text, int *level, · 4 unmodified lines
5877
5978 static inline bool printk_percpu_data_ready(void) { return false; }
6079 #endif /* CONFIG_PRINTK */
80+
81+/**
82+ * struct printk_buffers - Buffers to read/format/output printk messages.
83+ * @outbuf: After formatting, contains text to output.
84+ * @scratchbuf: Used as temporary ringbuffer reading and string-print space.
85+ */
86+struct printk_buffers {
87+ char outbuf[PRINTK_MESSAGE_MAX];
88+ char scratchbuf[PRINTKRB_RECORD_MAX];
89+};
90+
91+/**
92+ * struct printk_message - Container for a prepared printk message.
93+ * @pbufs: printk buffers used to prepare the message.
94+ * @outbuf_len: The length of prepared text in @pbufs->outbuf to output. This
95+ * does not count the terminator. A value of 0 means there is
96+ * nothing to output and this record should be skipped.
97+ * @seq: The sequence number of the record used for @pbufs->outbuf.
98+ * @dropped: The number of dropped records from reading @seq.
99+ */
100+struct printk_message {
101+ struct printk_buffers *pbufs;
102+ unsigned int outbuf_len;
103+ u64 seq;
104+ unsigned long dropped;
105+};
kernel/printk/printk.c+179−129
@@ -466,21 +466,6 @@ static struct latched_seq clear_seq = { · 465 unmodified lines
466466 .val[1] = 0,
467467 };
468468
469−#ifdef CONFIG_PRINTK_CALLER
470−#define PREFIX_MAX 48
471−#else
472−#define PREFIX_MAX 32
473−#endif
474−
475−/* the maximum size of a formatted record (i.e. with prefix added per line) */
476−#define CONSOLE_LOG_MAX 1024
477−
478−/* the maximum size for a dropped text message */
479−#define DROPPED_TEXT_MAX 64
480−
481−/* the maximum size allowed to be reserved for a record */
482−#define LOG_LINE_MAX (CONSOLE_LOG_MAX - PREFIX_MAX)
483−
484469 #define LOG_LEVEL(v) ((v) & 0x07)
485470 #define LOG_FACILITY(v) ((v) >> 3 & 0xff)
486471
@@ -711,16 +696,15 @@ out: · 224 unmodified lines
711696 return len;
712697 }
713698
699+static bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
700+ bool is_extended, bool may_supress);
701+
714702 /* /dev/kmsg - userspace message inject/listen interface */
715703 struct devkmsg_user {
716704 atomic64_t seq;
717705 struct ratelimit_state rs;
718706 struct mutex lock;
719− char buf[CONSOLE_EXT_LOG_MAX];
720−
721− struct printk_info info;
722− char text_buf[CONSOLE_EXT_LOG_MAX];
723− struct printk_record record;
707+ struct printk_buffers pbufs;
724708 };
725709
726710 static __printf(3, 4) __cold
@@ -746,7 +730,7 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) · 19 unmodified lines
746730 size_t len = iov_iter_count(from);
747731 ssize_t ret = len;
748732
749− if (!user || len > LOG_LINE_MAX)
733+ if (!user || len > PRINTKRB_RECORD_MAX)
750734 return -EINVAL;
751735
752736 /* Ignore when user logging is disabled. */
@@ -802,8 +786,10 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, · 49 unmodified lines
802786 size_t count, loff_t *ppos)
803787 {
804788 struct devkmsg_user *user = file->private_data;
805− struct printk_record *r = &user->record;
806− size_t len;
789+ char *outbuf = &user->pbufs.outbuf[0];
790+ struct printk_message pmsg = {
791+ .pbufs = &user->pbufs,
792+ };
807793 ssize_t ret;
808794
809795 if (!user)
@@ -813,7 +799,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, · 3 unmodified lines
813799 if (ret)
814800 return ret;
815801
816− if (!prb_read_valid(prb, atomic64_read(&user->seq), r)) {
802+ if (!printk_get_next_message(&pmsg, atomic64_read(&user->seq), true, false)) {
817803 if (file->f_flags & O_NONBLOCK) {
818804 ret = -EAGAIN;
819805 goto out;
@@ -830,36 +816,31 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, · 10 unmodified lines
830816 * This pairs with __wake_up_klogd:A.
831817 */
832818 ret = wait_event_interruptible(log_wait,
833− prb_read_valid(prb,
834− atomic64_read(&user->seq), r)); /* LMM(devkmsg_read:A) */
819+ printk_get_next_message(&pmsg, atomic64_read(&user->seq), true,
820+ false)); /* LMM(devkmsg_read:A) */
835821 if (ret)
836822 goto out;
837823 }
838824
839− if (r->info->seq != atomic64_read(&user->seq)) {
825+ if (pmsg.dropped) {
840826 /* our last seen message is gone, return error and reset */
841− atomic64_set(&user->seq, r->info->seq);
827+ atomic64_set(&user->seq, pmsg.seq);
842828 ret = -EPIPE;
843829 goto out;
844830 }
845831
846− len = info_print_ext_header(user->buf, sizeof(user->buf), r->info);
847− len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len,
848− &r->text_buf[0], r->info->text_len,
849− &r->info->dev_info);
850−
851− atomic64_set(&user->seq, r->info->seq + 1);
832+ atomic64_set(&user->seq, pmsg.seq + 1);
852833
853− if (len > count) {
834+ if (pmsg.outbuf_len > count) {
854835 ret = -EINVAL;
855836 goto out;
856837 }
857838
858− if (copy_to_user(buf, user->buf, len)) {
839+ if (copy_to_user(buf, outbuf, pmsg.outbuf_len)) {
859840 ret = -EFAULT;
860841 goto out;
861842 }
862− ret = len;
843+ ret = pmsg.outbuf_len;
863844 out:
864845 mutex_unlock(&user->lock);
865846 return ret;
@@ -953,9 +934,6 @@ static int devkmsg_open(struct inode *inode, struct file *file) · 87 unmodified lines
953934
954935 mutex_init(&user->lock);
955936
956− prb_rec_init_rd(&user->record, &user->info,
957− &user->text_buf[0], sizeof(user->text_buf));
958−
959937 atomic64_set(&user->seq, prb_first_valid_seq(prb));
960938
961939 file->private_data = user;
@@ -1150,7 +1128,7 @@ static unsigned int __init add_to_rb(struct printk_ringbuffer *rb, · 188 unmodified lines
11501128 return prb_record_text_space(&e);
11511129 }
11521130
1153−static char setup_text_buf[LOG_LINE_MAX] __initdata;
1131+static char setup_text_buf[PRINTKRB_RECORD_MAX] __initdata;
11541132
11551133 void __init setup_log_buf(int early)
11561134 {
@@ -1416,7 +1394,7 @@ static size_t record_print_text(struct printk_record *r, bool syslog, · 259 unmodified lines
14161394 size_t text_len = r->info->text_len;
14171395 size_t buf_size = r->text_buf_size;
14181396 char *text = r->text_buf;
1419− char prefix[PREFIX_MAX];
1397+ char prefix[PRINTK_PREFIX_MAX];
14201398 bool truncated = false;
14211399 size_t prefix_len;
14221400 size_t line_len;
@@ -1515,7 +1493,7 @@ static size_t get_record_print_text_size(struct printk_info *info, · 92 unmodified lines
15151493 unsigned int line_count,
15161494 bool syslog, bool time)
15171495 {
1518− char prefix[PREFIX_MAX];
1496+ char prefix[PRINTK_PREFIX_MAX];
15191497 size_t prefix_len;
15201498
15211499 prefix_len = info_print_prefix(info, syslog, time, prefix);
@@ -1581,11 +1559,11 @@ static int syslog_print(char __user *buf, int size) · 59 unmodified lines
15811559 int len = 0;
15821560 u64 seq;
15831561
1584− text = kmalloc(CONSOLE_LOG_MAX, GFP_KERNEL);
1562+ text = kmalloc(PRINTK_MESSAGE_MAX, GFP_KERNEL);
15851563 if (!text)
15861564 return -ENOMEM;
15871565
1588− prb_rec_init_rd(&r, &info, text, CONSOLE_LOG_MAX);
1566+ prb_rec_init_rd(&r, &info, text, PRINTK_MESSAGE_MAX);
15891567
15901568 mutex_lock(&syslog_lock);
15911569
@@ -1686,7 +1664,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) · 94 unmodified lines
16861664 u64 seq;
16871665 bool time;
16881666
1689− text = kmalloc(CONSOLE_LOG_MAX, GFP_KERNEL);
1667+ text = kmalloc(PRINTK_MESSAGE_MAX, GFP_KERNEL);
16901668 if (!text)
16911669 return -ENOMEM;
16921670
@@ -1698,7 +1676,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) · 5 unmodified lines
16981676 seq = find_first_fitting_seq(latched_seq_read_nolock(&clear_seq), -1,
16991677 size, true, time);
17001678
1701− prb_rec_init_rd(&r, &info, text, CONSOLE_LOG_MAX);
1679+ prb_rec_init_rd(&r, &info, text, PRINTK_MESSAGE_MAX);
17021680
17031681 len = 0;
17041682 prb_for_each_record(seq, prb, seq, &r) {
@@ -2012,27 +1990,6 @@ static int console_trylock_spinning(void) · 307 unmodified lines
20121990 return 1;
20131991 }
20141992
2015−/*
2016− * Call the specified console driver, asking it to write out the specified
2017− * text and length. If @dropped_text is non-NULL and any records have been
2018− * dropped, a dropped message will be written out first.
2019− */
2020−static void call_console_driver(struct console *con, const char *text, size_t len,
2021− char *dropped_text)
2022−{
2023− size_t dropped_len;
2024−
2025− if (con->dropped && dropped_text) {
2026− dropped_len = snprintf(dropped_text, DROPPED_TEXT_MAX,
2027− "** %lu printk messages dropped **\n",
2028− con->dropped);
2029− con->dropped = 0;
2030− con->write(con, dropped_text, dropped_len);
2031− }
2032−
2033− con->write(con, text, len);
2034−}
2035−
20361993 /*
20371994 * Recursion is tracked separately on each CPU. If NMIs are supported, an
20381995 * additional NMI context per CPU is also separately tracked. Until per-CPU
@@ -2243,8 +2200,8 @@ int vprintk_store(int facility, int level, · 204 unmodified lines
22432200 reserve_size = vsnprintf(&prefix_buf[0], sizeof(prefix_buf), fmt, args2) + 1;
22442201 va_end(args2);
22452202
2246− if (reserve_size > LOG_LINE_MAX)
2247− reserve_size = LOG_LINE_MAX;
2203+ if (reserve_size > PRINTKRB_RECORD_MAX)
2204+ reserve_size = PRINTKRB_RECORD_MAX;
22482205
22492206 /* Extract log level or control flags. */
22502207 if (facility == 0)
@@ -2258,7 +2215,7 @@ int vprintk_store(int facility, int level, · 7 unmodified lines
22582215
22592216 if (flags & LOG_CONT) {
22602217 prb_rec_init_wr(&r, reserve_size);
2261− if (prb_reserve_in_last(&e, prb, &r, caller_id, LOG_LINE_MAX)) {
2218+ if (prb_reserve_in_last(&e, prb, &r, caller_id, PRINTKRB_RECORD_MAX)) {
22622219 text_len = printk_sprint(&r.text_buf[r.info->text_len], reserve_size,
22632220 facility, &flags, fmt, args);
22642221 r.info->text_len += text_len;
@@ -2389,8 +2346,6 @@ static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre · 124 unmodified lines
23892346
23902347 #else /* CONFIG_PRINTK */
23912348
2392−#define CONSOLE_LOG_MAX 0
2393−#define DROPPED_TEXT_MAX 0
23942349 #define printk_time false
23952350
23962351 #define prb_read_valid(rb, seq, r) false
@@ -2414,10 +2369,6 @@ static ssize_t msg_print_ext_body(char *buf, size_t size, · 17 unmodified lines
24142369 struct dev_printk_info *dev_info) { return 0; }
24152370 static void console_lock_spinning_enable(void) { }
24162371 static int console_lock_spinning_disable_and_check(int cookie) { return 0; }
2417−static void call_console_driver(struct console *con, const char *text, size_t len,
2418− char *dropped_text)
2419−{
2420−}
24212372 static bool suppress_message_printing(int level) { return false; }
24222373 static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; }
24232374 static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; }
@@ -2744,16 +2695,136 @@ static void __console_unlock(void) · 320 unmodified lines
27442695 }
27452696
27462697 /*
2747− * Print one record for the given console. The record printed is whatever
2748− * record is the next available record for the given console.
2698+ * Prepend the message in @pmsg->pbufs->outbuf with a "dropped message". This
2699+ * is achieved by shifting the existing message over and inserting the dropped
2700+ * message.
2701+ *
2702+ * @pmsg is the printk message to prepend.
27492703 *
2750− * @text is a buffer of size CONSOLE_LOG_MAX.
2704+ * @dropped is the dropped count to report in the dropped message.
27512705 *
2752− * If extended messages should be printed, @ext_text is a buffer of size
2753− * CONSOLE_EXT_LOG_MAX. Otherwise @ext_text must be NULL.
2706+ * If the message text in @pmsg->pbufs->outbuf does not have enough space for
2707+ * the dropped message, the message text will be sufficiently truncated.
27542708 *
2755− * If dropped messages should be printed, @dropped_text is a buffer of size
2756− * DROPPED_TEXT_MAX. Otherwise @dropped_text must be NULL.
2709+ * If @pmsg->pbufs->outbuf is modified, @pmsg->outbuf_len is updated.
2710+ */
2711+#ifdef CONFIG_PRINTK
2712+static void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped)
2713+{
2714+ struct printk_buffers *pbufs = pmsg->pbufs;
2715+ const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf);
2716+ const size_t outbuf_sz = sizeof(pbufs->outbuf);
2717+ char *scratchbuf = &pbufs->scratchbuf[0];
2718+ char *outbuf = &pbufs->outbuf[0];
2719+ size_t len;
2720+
2721+ len = scnprintf(scratchbuf, scratchbuf_sz,
2722+ "** %lu printk messages dropped **\n", dropped);
2723+
2724+ /*
2725+ * Make sure outbuf is sufficiently large before prepending.
2726+ * Keep at least the prefix when the message must be truncated.
2727+ * It is a rather theoretical problem when someone tries to
2728+ * use a minimalist buffer.
2729+ */
2730+ if (WARN_ON_ONCE(len + PRINTK_PREFIX_MAX >= outbuf_sz))
2731+ return;
2732+
2733+ if (pmsg->outbuf_len + len >= outbuf_sz) {
2734+ /* Truncate the message, but keep it terminated. */
2735+ pmsg->outbuf_len = outbuf_sz - (len + 1);
2736+ outbuf[pmsg->outbuf_len] = 0;
2737+ }
2738+
2739+ memmove(outbuf + len, outbuf, pmsg->outbuf_len + 1);
2740+ memcpy(outbuf, scratchbuf, len);
2741+ pmsg->outbuf_len += len;
2742+}
2743+#else
2744+#define console_prepend_dropped(pmsg, dropped)
2745+#endif /* CONFIG_PRINTK */
2746+
2747+/*
2748+ * Read and format the specified record (or a later record if the specified
2749+ * record is not available).
2750+ *
2751+ * @pmsg will contain the formatted result. @pmsg->pbufs must point to a
2752+ * struct printk_buffers.
2753+ *
2754+ * @seq is the record to read and format. If it is not available, the next
2755+ * valid record is read.
2756+ *
2757+ * @is_extended specifies if the message should be formatted for extended
2758+ * console output.
2759+ *
2760+ * @may_supress specifies if records may be skipped based on loglevel.
2761+ *
2762+ * Returns false if no record is available. Otherwise true and all fields
2763+ * of @pmsg are valid. (See the documentation of struct printk_message
2764+ * for information about the @pmsg fields.)
2765+ */
2766+static bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
2767+ bool is_extended, bool may_suppress)
2768+{
2769+ static int panic_console_dropped;
2770+
2771+ struct printk_buffers *pbufs = pmsg->pbufs;
2772+ const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf);
2773+ const size_t outbuf_sz = sizeof(pbufs->outbuf);
2774+ char *scratchbuf = &pbufs->scratchbuf[0];
2775+ char *outbuf = &pbufs->outbuf[0];
2776+ struct printk_info info;
2777+ struct printk_record r;
2778+ size_t len = 0;
2779+
2780+ /*
2781+ * Formatting extended messages requires a separate buffer, so use the
2782+ * scratch buffer to read in the ringbuffer text.
2783+ *
2784+ * Formatting normal messages is done in-place, so read the ringbuffer
2785+ * text directly into the output buffer.
2786+ */
2787+ if (is_extended)
2788+ prb_rec_init_rd(&r, &info, scratchbuf, scratchbuf_sz);
2789+ else
2790+ prb_rec_init_rd(&r, &info, outbuf, outbuf_sz);
2791+
2792+ if (!prb_read_valid(prb, seq, &r))
2793+ return false;
2794+
2795+ pmsg->seq = r.info->seq;
2796+ pmsg->dropped = r.info->seq - seq;
2797+
2798+ /*
2799+ * Check for dropped messages in panic here so that printk
2800+ * suppression can occur as early as possible if necessary.
2801+ */
2802+ if (pmsg->dropped &&
2803+ panic_in_progress() &&
2804+ panic_console_dropped++ > 10) {
2805+ suppress_panic_printk = 1;
2806+ pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n");
2807+ }
2808+
2809+ /* Skip record that has level above the console loglevel. */
2810+ if (may_suppress && suppress_message_printing(r.info->level))
2811+ goto out;
2812+
2813+ if (is_extended) {
2814+ len = info_print_ext_header(outbuf, outbuf_sz, r.info);
2815+ len += msg_print_ext_body(outbuf + len, outbuf_sz - len,
2816+ &r.text_buf[0], r.info->text_len, &r.info->dev_info);
2817+ } else {
2818+ len = record_print_text(&r, console_msg_format & MSG_FORMAT_SYSLOG, printk_time);
2819+ }
2820+out:
2821+ pmsg->outbuf_len = len;
2822+ return true;
2823+}
2824+
2825+/*
2826+ * Print one record for the given console. The record printed is whatever
2827+ * record is the next available record for the given console.
27572828 *
27582829 * @handover will be set to true if a printk waiter has taken over the
27592830 * console_lock, in which case the caller is no longer holding both the
@@ -2766,46 +2837,33 @@ static void __console_unlock(void) · 6 unmodified lines
27662837 *
27672838 * Requires the console_lock and the SRCU read lock.
27682839 */
2769−static bool console_emit_next_record(struct console *con, char *text, char *ext_text,
2770− char *dropped_text, bool *handover, int cookie)
2840+static bool console_emit_next_record(struct console *con, bool *handover, int cookie)
27712841 {
2772− static int panic_console_dropped;
2773− struct printk_info info;
2774− struct printk_record r;
2775− unsigned long flags;
2776− char *write_text;
2777− size_t len;
2842+ static struct printk_buffers pbufs;
27782843
2779− prb_rec_init_rd(&r, &info, text, CONSOLE_LOG_MAX);
2844+ bool is_extended = console_srcu_read_flags(con) & CON_EXTENDED;
2845+ char *outbuf = &pbufs.outbuf[0];
2846+ struct printk_message pmsg = {
2847+ .pbufs = &pbufs,
2848+ };
2849+ unsigned long flags;
27802850
27812851 *handover = false;
27822852
2783− if (!prb_read_valid(prb, con->seq, &r))
2853+ if (!printk_get_next_message(&pmsg, con->seq, is_extended, true))
27842854 return false;
27852855
2786− if (con->seq != r.info->seq) {
2787− con->dropped += r.info->seq - con->seq;
2788− con->seq = r.info->seq;
2789− if (panic_in_progress() && panic_console_dropped++ > 10) {
2790− suppress_panic_printk = 1;
2791− pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n");
2792− }
2793− }
2856+ con->dropped += pmsg.dropped;
27942857
2795− /* Skip record that has level above the console loglevel. */
2796− if (suppress_message_printing(r.info->level)) {
2797− con->seq++;
2858+ /* Skip messages of formatted length 0. */
2859+ if (pmsg.outbuf_len == 0) {
2860+ con->seq = pmsg.seq + 1;
27982861 goto skip;
27992862 }
28002863
2801− if (ext_text) {
2802− write_text = ext_text;
2803− len = info_print_ext_header(ext_text, CONSOLE_EXT_LOG_MAX, r.info);
2804− len += msg_print_ext_body(ext_text + len, CONSOLE_EXT_LOG_MAX - len,
2805− &r.text_buf[0], r.info->text_len, &r.info->dev_info);
2806− } else {
2807− write_text = text;
2808− len = record_print_text(&r, console_msg_format & MSG_FORMAT_SYSLOG, printk_time);
2864+ if (con->dropped && !is_extended) {
2865+ console_prepend_dropped(&pmsg, con->dropped);
2866+ con->dropped = 0;
28092867 }
28102868
28112869 /*
@@ -2821,11 +2879,15 @@ static bool console_emit_next_record(struct console *con, char *text, char *ext_ · 9 unmodified lines
28212879 printk_safe_enter_irqsave(flags);
28222880 console_lock_spinning_enable();
28232881
2824− stop_critical_timings(); /* don't trace print latency */
2825− call_console_driver(con, write_text, len, dropped_text);
2882+ /* Do not trace print latency. */
2883+ stop_critical_timings();
2884+
2885+ /* Write everything out to the hardware. */
2886+ con->write(con, outbuf, pmsg.outbuf_len);
2887+
28262888 start_critical_timings();
28272889
2828− con->seq++;
2890+ con->seq = pmsg.seq + 1;
28292891
28302892 *handover = console_lock_spinning_disable_and_check(cookie);
28312893 printk_safe_exit_irqrestore(flags);
@@ -2858,9 +2920,6 @@ skip: · 26 unmodified lines
28582920 */
28592921 static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handover)
28602922 {
2861− static char dropped_text[DROPPED_TEXT_MAX];
2862− static char ext_text[CONSOLE_EXT_LOG_MAX];
2863− static char text[CONSOLE_LOG_MAX];
28642923 bool any_usable = false;
28652924 struct console *con;
28662925 bool any_progress;
@@ -2880,16 +2939,7 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove · 13 unmodified lines
28802939 continue;
28812940 any_usable = true;
28822941
2883− if (console_srcu_read_flags(con) & CON_EXTENDED) {
2884− /* Extended consoles do not print "dropped messages". */
2885− progress = console_emit_next_record(con, &text[0],
2886− &ext_text[0], NULL,
2887− handover, cookie);
2888− } else {
2889− progress = console_emit_next_record(con, &text[0],
2890− NULL, &dropped_text[0],
2891− handover, cookie);
2892− }
2942+ progress = console_emit_next_record(con, handover, cookie);
28932943
28942944 /*
28952945 * If a handover has occurred, the SRCU read lock