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
145#ifdef CONFIG_MODULES145#ifdef CONFIG_MODULES
146static void pi_remove_file(struct module *mod)146static void pi_remove_file(struct module *mod)
147{147{
148 debugfs_remove(debugfs_lookup(pi_get_module_name(mod), dfs_index));148 debugfs_lookup_and_remove(pi_get_module_name(mod), dfs_index);
149}149}
150 150
151static int pi_module_notify(struct notifier_block *nb, unsigned long op,151static 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
14 14
15#ifdef CONFIG_PRINTK15#ifdef CONFIG_PRINTK
16 16
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
17/* Flags for a single printk record. */32/* Flags for a single printk record. */
18enum printk_info_flags {33enum printk_info_flags {
19 LOG_NEWLINE = 2, /* text ended with a newline */34 LOG_NEWLINE = 2, /* text ended with a newline */
@@ -48,6 +63,10 @@ u16 printk_parse_prefix(const char *text, int *level, · 28 unmodified lines
48 enum printk_info_flags *flags);63 enum printk_info_flags *flags);
49#else64#else
50 65
66#define PRINTK_PREFIX_MAX 0
67#define PRINTK_MESSAGE_MAX 0
68#define PRINTKRB_RECORD_MAX 0
69
51/*70/*
52 * In !PRINTK builds we still export console_sem71 * In !PRINTK builds we still export console_sem
53 * semaphore and some of console functions (console_unlock()/etc.), so72 * 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
58 77
59static inline bool printk_percpu_data_ready(void) { return false; }78static inline bool printk_percpu_data_ready(void) { return false; }
60#endif /* CONFIG_PRINTK */79#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 */
86struct 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 */
100struct 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
466 .val[1] = 0,466 .val[1] = 0,
467};467};
468 468
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
484#define LOG_LEVEL(v) ((v) & 0x07)469#define LOG_LEVEL(v) ((v) & 0x07)
485#define LOG_FACILITY(v) ((v) >> 3 & 0xff)470#define LOG_FACILITY(v) ((v) >> 3 & 0xff)
486 471
@@ -711,16 +696,15 @@ out: · 224 unmodified lines
711 return len;696 return len;
712}697}
713 698
699static bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
700 bool is_extended, bool may_supress);
701
714/* /dev/kmsg - userspace message inject/listen interface */702/* /dev/kmsg - userspace message inject/listen interface */
715struct devkmsg_user {703struct devkmsg_user {
716 atomic64_t seq;704 atomic64_t seq;
717 struct ratelimit_state rs;705 struct ratelimit_state rs;
718 struct mutex lock;706 struct mutex lock;
719 char buf[CONSOLE_EXT_LOG_MAX];707 struct printk_buffers pbufs;
720
721 struct printk_info info;
722 char text_buf[CONSOLE_EXT_LOG_MAX];
723 struct printk_record record;
724};708};
725 709
726static __printf(3, 4) __cold710static __printf(3, 4) __cold
@@ -746,7 +730,7 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) · 19 unmodified lines
746 size_t len = iov_iter_count(from);730 size_t len = iov_iter_count(from);
747 ssize_t ret = len;731 ssize_t ret = len;
748 732
749 if (!user || len > LOG_LINE_MAX)733 if (!user || len > PRINTKRB_RECORD_MAX)
750 return -EINVAL;734 return -EINVAL;
751 735
752 /* Ignore when user logging is disabled. */736 /* Ignore when user logging is disabled. */
@@ -802,8 +786,10 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, · 49 unmodified lines
802 size_t count, loff_t *ppos)786 size_t count, loff_t *ppos)
803{787{
804 struct devkmsg_user *user = file->private_data;788 struct devkmsg_user *user = file->private_data;
805 struct printk_record *r = &user->record;789 char *outbuf = &user->pbufs.outbuf[0];
806 size_t len;790 struct printk_message pmsg = {
791 .pbufs = &user->pbufs,
792 };
807 ssize_t ret;793 ssize_t ret;
808 794
809 if (!user)795 if (!user)
@@ -813,7 +799,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, · 3 unmodified lines
813 if (ret)799 if (ret)
814 return ret;800 return ret;
815 801
816 if (!prb_read_valid(prb, atomic64_read(&user->seq), r)) {802 if (!printk_get_next_message(&pmsg, atomic64_read(&user->seq), true, false)) {
817 if (file->f_flags & O_NONBLOCK) {803 if (file->f_flags & O_NONBLOCK) {
818 ret = -EAGAIN;804 ret = -EAGAIN;
819 goto out;805 goto out;
@@ -830,36 +816,31 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, · 10 unmodified lines
830 * This pairs with __wake_up_klogd:A.816 * This pairs with __wake_up_klogd:A.
831 */817 */
832 ret = wait_event_interruptible(log_wait,818 ret = wait_event_interruptible(log_wait,
833 prb_read_valid(prb,819 printk_get_next_message(&pmsg, atomic64_read(&user->seq), true,
834 atomic64_read(&user->seq), r)); /* LMM(devkmsg_read:A) */820 false)); /* LMM(devkmsg_read:A) */
835 if (ret)821 if (ret)
836 goto out;822 goto out;
837 }823 }
838 824
839 if (r->info->seq != atomic64_read(&user->seq)) {825 if (pmsg.dropped) {
840 /* our last seen message is gone, return error and reset */826 /* 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);
842 ret = -EPIPE;828 ret = -EPIPE;
843 goto out;829 goto out;
844 }830 }
845 831
846 len = info_print_ext_header(user->buf, sizeof(user->buf), r->info);832 atomic64_set(&user->seq, pmsg.seq + 1);
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);
852 833
853 if (len > count) {834 if (pmsg.outbuf_len > count) {
854 ret = -EINVAL;835 ret = -EINVAL;
855 goto out;836 goto out;
856 }837 }
857 838
858 if (copy_to_user(buf, user->buf, len)) {839 if (copy_to_user(buf, outbuf, pmsg.outbuf_len)) {
859 ret = -EFAULT;840 ret = -EFAULT;
860 goto out;841 goto out;
861 }842 }
862 ret = len;843 ret = pmsg.outbuf_len;
863out:844out:
864 mutex_unlock(&user->lock);845 mutex_unlock(&user->lock);
865 return ret;846 return ret;
@@ -953,9 +934,6 @@ static int devkmsg_open(struct inode *inode, struct file *file) · 87 unmodified lines
953 934
954 mutex_init(&user->lock);935 mutex_init(&user->lock);
955 936
956 prb_rec_init_rd(&user->record, &user->info,
957 &user->text_buf[0], sizeof(user->text_buf));
958
959 atomic64_set(&user->seq, prb_first_valid_seq(prb));937 atomic64_set(&user->seq, prb_first_valid_seq(prb));
960 938
961 file->private_data = user;939 file->private_data = user;
@@ -1150,7 +1128,7 @@ static unsigned int __init add_to_rb(struct printk_ringbuffer *rb, · 188 unmodified lines
1150 return prb_record_text_space(&e);1128 return prb_record_text_space(&e);
1151}1129}
1152 1130
1153static char setup_text_buf[LOG_LINE_MAX] __initdata;1131static char setup_text_buf[PRINTKRB_RECORD_MAX] __initdata;
1154 1132
1155void __init setup_log_buf(int early)1133void __init setup_log_buf(int early)
1156{1134{
@@ -1416,7 +1394,7 @@ static size_t record_print_text(struct printk_record *r, bool syslog, · 259 unmodified lines
1416 size_t text_len = r->info->text_len;1394 size_t text_len = r->info->text_len;
1417 size_t buf_size = r->text_buf_size;1395 size_t buf_size = r->text_buf_size;
1418 char *text = r->text_buf;1396 char *text = r->text_buf;
1419 char prefix[PREFIX_MAX];1397 char prefix[PRINTK_PREFIX_MAX];
1420 bool truncated = false;1398 bool truncated = false;
1421 size_t prefix_len;1399 size_t prefix_len;
1422 size_t line_len;1400 size_t line_len;
@@ -1515,7 +1493,7 @@ static size_t get_record_print_text_size(struct printk_info *info, · 92 unmodified lines
1515 unsigned int line_count,1493 unsigned int line_count,
1516 bool syslog, bool time)1494 bool syslog, bool time)
1517{1495{
1518 char prefix[PREFIX_MAX];1496 char prefix[PRINTK_PREFIX_MAX];
1519 size_t prefix_len;1497 size_t prefix_len;
1520 1498
1521 prefix_len = info_print_prefix(info, syslog, time, prefix);1499 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
1581 int len = 0;1559 int len = 0;
1582 u64 seq;1560 u64 seq;
1583 1561
1584 text = kmalloc(CONSOLE_LOG_MAX, GFP_KERNEL);1562 text = kmalloc(PRINTK_MESSAGE_MAX, GFP_KERNEL);
1585 if (!text)1563 if (!text)
1586 return -ENOMEM;1564 return -ENOMEM;
1587 1565
1588 prb_rec_init_rd(&r, &info, text, CONSOLE_LOG_MAX);1566 prb_rec_init_rd(&r, &info, text, PRINTK_MESSAGE_MAX);
1589 1567
1590 mutex_lock(&syslog_lock);1568 mutex_lock(&syslog_lock);
1591 1569
@@ -1686,7 +1664,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) · 94 unmodified lines
1686 u64 seq;1664 u64 seq;
1687 bool time;1665 bool time;
1688 1666
1689 text = kmalloc(CONSOLE_LOG_MAX, GFP_KERNEL);1667 text = kmalloc(PRINTK_MESSAGE_MAX, GFP_KERNEL);
1690 if (!text)1668 if (!text)
1691 return -ENOMEM;1669 return -ENOMEM;
1692 1670
@@ -1698,7 +1676,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) · 5 unmodified lines
1698 seq = find_first_fitting_seq(latched_seq_read_nolock(&clear_seq), -1,1676 seq = find_first_fitting_seq(latched_seq_read_nolock(&clear_seq), -1,
1699 size, true, time);1677 size, true, time);
1700 1678
1701 prb_rec_init_rd(&r, &info, text, CONSOLE_LOG_MAX);1679 prb_rec_init_rd(&r, &info, text, PRINTK_MESSAGE_MAX);
1702 1680
1703 len = 0;1681 len = 0;
1704 prb_for_each_record(seq, prb, seq, &r) {1682 prb_for_each_record(seq, prb, seq, &r) {
@@ -2012,27 +1990,6 @@ static int console_trylock_spinning(void) · 307 unmodified lines
2012 return 1;1990 return 1;
2013}1991}
2014 1992
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 */
2020static 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
2036/*1993/*
2037 * Recursion is tracked separately on each CPU. If NMIs are supported, an1994 * Recursion is tracked separately on each CPU. If NMIs are supported, an
2038 * additional NMI context per CPU is also separately tracked. Until per-CPU1995 * 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
2243 reserve_size = vsnprintf(&prefix_buf[0], sizeof(prefix_buf), fmt, args2) + 1;2200 reserve_size = vsnprintf(&prefix_buf[0], sizeof(prefix_buf), fmt, args2) + 1;
2244 va_end(args2);2201 va_end(args2);
2245 2202
2246 if (reserve_size > LOG_LINE_MAX)2203 if (reserve_size > PRINTKRB_RECORD_MAX)
2247 reserve_size = LOG_LINE_MAX;2204 reserve_size = PRINTKRB_RECORD_MAX;
2248 2205
2249 /* Extract log level or control flags. */2206 /* Extract log level or control flags. */
2250 if (facility == 0)2207 if (facility == 0)
@@ -2258,7 +2215,7 @@ int vprintk_store(int facility, int level, · 7 unmodified lines
2258 2215
2259 if (flags & LOG_CONT) {2216 if (flags & LOG_CONT) {
2260 prb_rec_init_wr(&r, reserve_size);2217 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)) {
2262 text_len = printk_sprint(&r.text_buf[r.info->text_len], reserve_size,2219 text_len = printk_sprint(&r.text_buf[r.info->text_len], reserve_size,
2263 facility, &flags, fmt, args);2220 facility, &flags, fmt, args);
2264 r.info->text_len += text_len;2221 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
2389 2346
2390#else /* CONFIG_PRINTK */2347#else /* CONFIG_PRINTK */
2391 2348
2392#define CONSOLE_LOG_MAX 0
2393#define DROPPED_TEXT_MAX 0
2394#define printk_time false2349#define printk_time false
2395 2350
2396#define prb_read_valid(rb, seq, r) false2351#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
2414 struct dev_printk_info *dev_info) { return 0; }2369 struct dev_printk_info *dev_info) { return 0; }
2415static void console_lock_spinning_enable(void) { }2370static void console_lock_spinning_enable(void) { }
2416static int console_lock_spinning_disable_and_check(int cookie) { return 0; }2371static int console_lock_spinning_disable_and_check(int cookie) { return 0; }
2417static void call_console_driver(struct console *con, const char *text, size_t len,
2418 char *dropped_text)
2419{
2420}
2421static bool suppress_message_printing(int level) { return false; }2372static bool suppress_message_printing(int level) { return false; }
2422static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; }2373static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; }
2423static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; }2374static 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
2744}2695}
2745 2696
2746/*2697/*
2747 * Print one record for the given console. The record printed is whatever2698 * Prepend the message in @pmsg->pbufs->outbuf with a "dropped message". This
2748 * record is the next available record for the given console.2699 * is achieved by shifting the existing message over and inserting the dropped
2700 * message.
2701 *
2702 * @pmsg is the printk message to prepend.
2749 *2703 *
2750 * @text is a buffer of size CONSOLE_LOG_MAX.2704 * @dropped is the dropped count to report in the dropped message.
2751 *2705 *
2752 * If extended messages should be printed, @ext_text is a buffer of size2706 * If the message text in @pmsg->pbufs->outbuf does not have enough space for
2753 * CONSOLE_EXT_LOG_MAX. Otherwise @ext_text must be NULL.2707 * the dropped message, the message text will be sufficiently truncated.
2754 *2708 *
2755 * If dropped messages should be printed, @dropped_text is a buffer of size2709 * If @pmsg->pbufs->outbuf is modified, @pmsg->outbuf_len is updated.
2756 * DROPPED_TEXT_MAX. Otherwise @dropped_text must be NULL.2710 */
2711#ifdef CONFIG_PRINTK
2712static 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 */
2766static 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 }
2820out:
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.
2757 *2828 *
2758 * @handover will be set to true if a printk waiter has taken over the2829 * @handover will be set to true if a printk waiter has taken over the
2759 * console_lock, in which case the caller is no longer holding both the2830 * 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
2766 *2837 *
2767 * Requires the console_lock and the SRCU read lock.2838 * Requires the console_lock and the SRCU read lock.
2768 */2839 */
2769static bool console_emit_next_record(struct console *con, char *text, char *ext_text,2840static bool console_emit_next_record(struct console *con, bool *handover, int cookie)
2770 char *dropped_text, bool *handover, int cookie)
2771{2841{
2772 static int panic_console_dropped;2842 static struct printk_buffers pbufs;
2773 struct printk_info info;
2774 struct printk_record r;
2775 unsigned long flags;
2776 char *write_text;
2777 size_t len;
2778 2843
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;
2780 2850
2781 *handover = false;2851 *handover = false;
2782 2852
2783 if (!prb_read_valid(prb, con->seq, &r))2853 if (!printk_get_next_message(&pmsg, con->seq, is_extended, true))
2784 return false;2854 return false;
2785 2855
2786 if (con->seq != r.info->seq) {2856 con->dropped += pmsg.dropped;
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 }
2794 2857
2795 /* Skip record that has level above the console loglevel. */2858 /* Skip messages of formatted length 0. */
2796 if (suppress_message_printing(r.info->level)) {2859 if (pmsg.outbuf_len == 0) {
2797 con->seq++;2860 con->seq = pmsg.seq + 1;
2798 goto skip;2861 goto skip;
2799 }2862 }
2800 2863
2801 if (ext_text) {2864 if (con->dropped && !is_extended) {
2802 write_text = ext_text;2865 console_prepend_dropped(&pmsg, con->dropped);
2803 len = info_print_ext_header(ext_text, CONSOLE_EXT_LOG_MAX, r.info);2866 con->dropped = 0;
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);
2809 }2867 }
2810 2868
2811 /*2869 /*
@@ -2821,11 +2879,15 @@ static bool console_emit_next_record(struct console *con, char *text, char *ext_ · 9 unmodified lines
2821 printk_safe_enter_irqsave(flags);2879 printk_safe_enter_irqsave(flags);
2822 console_lock_spinning_enable();2880 console_lock_spinning_enable();
2823 2881
2824 stop_critical_timings(); /* don't trace print latency */2882 /* Do not trace print latency. */
2825 call_console_driver(con, write_text, len, dropped_text);2883 stop_critical_timings();
2884
2885 /* Write everything out to the hardware. */
2886 con->write(con, outbuf, pmsg.outbuf_len);
2887
2826 start_critical_timings();2888 start_critical_timings();
2827 2889
2828 con->seq++;2890 con->seq = pmsg.seq + 1;
2829 2891
2830 *handover = console_lock_spinning_disable_and_check(cookie);2892 *handover = console_lock_spinning_disable_and_check(cookie);
2831 printk_safe_exit_irqrestore(flags);2893 printk_safe_exit_irqrestore(flags);
@@ -2858,9 +2920,6 @@ skip: · 26 unmodified lines
2858 */2920 */
2859static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handover)2921static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handover)
2860{2922{
2861 static char dropped_text[DROPPED_TEXT_MAX];
2862 static char ext_text[CONSOLE_EXT_LOG_MAX];
2863 static char text[CONSOLE_LOG_MAX];
2864 bool any_usable = false;2923 bool any_usable = false;
2865 struct console *con;2924 struct console *con;
2866 bool any_progress;2925 bool any_progress;
@@ -2880,16 +2939,7 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove · 13 unmodified lines
2880 continue;2939 continue;
2881 any_usable = true;2940 any_usable = true;
2882 2941
2883 if (console_srcu_read_flags(con) & CON_EXTENDED) {2942 progress = console_emit_next_record(con, handover, cookie);
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 }
2893 2943
2894 /*2944 /*
2895 * If a handover has occurred, the SRCU read lock2945 * If a handover has occurred, the SRCU read lock