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
Showing the changes to kernel (3 of 7 files). Show all
Unified · Split
| @@ -145,7 +145,7 @@ static void pi_create_file(struct module *mod) · 144 unmodified lines | |||
| 145 | #ifdef CONFIG_MODULES | 145 | #ifdef CONFIG_MODULES |
| 146 | static void pi_remove_file(struct module *mod) | 146 | static 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 | ||
| 151 | static int pi_module_notify(struct notifier_block *nb, unsigned long op, | 151 | static int pi_module_notify(struct notifier_block *nb, unsigned long op, |
| @@ -14,6 +14,21 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #ifdef CONFIG_PRINTK | 15 | #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. */ |
| 18 | enum printk_info_flags { | 33 | enum 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 | #else | 64 | #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_sem | 71 | * In !PRINTK builds we still export console_sem |
| 53 | * semaphore and some of console functions (console_unlock()/etc.), so | 72 | * 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 | ||
| 59 | static inline bool printk_percpu_data_ready(void) { return false; } | 78 | static 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 | */ | ||
| 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 | }; | ||
| @@ -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 | ||
| 699 | static 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 */ |
| 715 | struct devkmsg_user { | 703 | struct 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 | ||
| 726 | static __printf(3, 4) __cold | 710 | static __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; |
| 863 | out: | 844 | out: |
| 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 | ||
| 1153 | static char setup_text_buf[LOG_LINE_MAX] __initdata; | 1131 | static char setup_text_buf[PRINTKRB_RECORD_MAX] __initdata; |
| 1154 | 1132 | ||
| 1155 | void __init setup_log_buf(int early) | 1133 | void __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 | */ | ||
| 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 | |||
| 2036 | /* | 1993 | /* |
| 2037 | * Recursion is tracked separately on each CPU. If NMIs are supported, an | 1994 | * Recursion is tracked separately on each CPU. If NMIs are supported, an |
| 2038 | * additional NMI context per CPU is also separately tracked. Until per-CPU | 1995 | * 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 false | 2349 | #define printk_time false |
| 2395 | 2350 | ||
| 2396 | #define prb_read_valid(rb, seq, r) false | 2351 | #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; } |
| 2415 | static void console_lock_spinning_enable(void) { } | 2370 | static void console_lock_spinning_enable(void) { } |
| 2416 | static int console_lock_spinning_disable_and_check(int cookie) { return 0; } | 2371 | 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 | } | ||
| 2421 | static bool suppress_message_printing(int level) { return false; } | 2372 | static bool suppress_message_printing(int level) { return false; } |
| 2422 | static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; } | 2373 | static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; } |
| 2423 | static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; } | 2374 | 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 | |||
| 2744 | } | 2695 | } |
| 2745 | 2696 | ||
| 2746 | /* | 2697 | /* |
| 2747 | * Print one record for the given console. The record printed is whatever | 2698 | * 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 size | 2706 | * 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 size | 2709 | * 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 | ||
| 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. | ||
| 2757 | * | 2828 | * |
| 2758 | * @handover will be set to true if a printk waiter has taken over the | 2829 | * @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 the | 2830 | * 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 | */ |
| 2769 | static bool console_emit_next_record(struct console *con, char *text, char *ext_text, | 2840 | static 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 | */ |
| 2859 | static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handover) | 2921 | static 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 lock | 2945 | * If a handover has occurred, the SRCU read lock |