diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches-rt/0085-printk-consolidate-kmsg_dump_get_buffer-syslog_print.patch | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/debian/patches-rt/0085-printk-consolidate-kmsg_dump_get_buffer-syslog_print.patch b/debian/patches-rt/0085-printk-consolidate-kmsg_dump_get_buffer-syslog_print.patch new file mode 100644 index 000000000..acc8de768 --- /dev/null +++ b/debian/patches-rt/0085-printk-consolidate-kmsg_dump_get_buffer-syslog_print.patch @@ -0,0 +1,147 @@ +From 922cda1ee8d183c2e98429cdabf907a92df72465 Mon Sep 17 00:00:00 2001 +From: John Ogness <john.ogness@linutronix.de> +Date: Wed, 13 Jan 2021 11:29:53 +0106 +Subject: [PATCH 085/323] printk: consolidate + kmsg_dump_get_buffer/syslog_print_all code +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.10/older/patches-5.10.204-rt100.tar.xz + +The logic for finding records to fit into a buffer is the same for +kmsg_dump_get_buffer() and syslog_print_all(). Introduce a helper +function find_first_fitting_seq() to handle this logic. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +--- + kernel/printk/printk.c | 87 ++++++++++++++++++++++++------------------ + 1 file changed, 50 insertions(+), 37 deletions(-) + +diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c +index ad7edcb693d4..1f710a2a40b6 100644 +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -1424,6 +1424,50 @@ static size_t get_record_print_text_size(struct printk_info *info, + return ((prefix_len * line_count) + info->text_len + 1); + } + ++/* ++ * Beginning with @start_seq, find the first record where it and all following ++ * records up to (but not including) @max_seq fit into @size. ++ * ++ * @max_seq is simply an upper bound and does not need to exist. If the caller ++ * does not require an upper bound, -1 can be used for @max_seq. ++ */ ++static u64 find_first_fitting_seq(u64 start_seq, u64 max_seq, size_t size, ++ bool syslog, bool time) ++{ ++ struct printk_info info; ++ unsigned int line_count; ++ size_t len = 0; ++ u64 seq; ++ ++ /* Determine the size of the records up to @max_seq. */ ++ prb_for_each_info(start_seq, prb, seq, &info, &line_count) { ++ if (info.seq >= max_seq) ++ break; ++ len += get_record_print_text_size(&info, line_count, syslog, time); ++ } ++ ++ /* ++ * Adjust the upper bound for the next loop to avoid subtracting ++ * lengths that were never added. ++ */ ++ if (seq < max_seq) ++ max_seq = seq; ++ ++ /* ++ * Move first record forward until length fits into the buffer. Ignore ++ * newest messages that were not counted in the above cycle. Messages ++ * might appear and get lost in the meantime. This is a best effort ++ * that prevents an infinite loop that could occur with a retry. ++ */ ++ prb_for_each_info(start_seq, prb, seq, &info, &line_count) { ++ if (len <= size || info.seq >= max_seq) ++ break; ++ len -= get_record_print_text_size(&info, line_count, syslog, time); ++ } ++ ++ return seq; ++} ++ + static int syslog_print(char __user *buf, int size) + { + struct printk_info info; +@@ -1495,9 +1539,7 @@ static int syslog_print(char __user *buf, int size) + static int syslog_print_all(char __user *buf, int size, bool clear) + { + struct printk_info info; +- unsigned int line_count; + struct printk_record r; +- u64 max_seq; + char *text; + int len = 0; + u64 seq; +@@ -1513,21 +1555,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) + * Find first record that fits, including all following records, + * into the user-provided buffer for this dump. + */ +- prb_for_each_info(clear_seq, prb, seq, &info, &line_count) +- len += get_record_print_text_size(&info, line_count, true, time); +- +- /* +- * Set an upper bound for the next loop to avoid subtracting lengths +- * that were never added. +- */ +- max_seq = seq; +- +- /* move first record forward until length fits into the buffer */ +- prb_for_each_info(clear_seq, prb, seq, &info, &line_count) { +- if (len <= size || info.seq >= max_seq) +- break; +- len -= get_record_print_text_size(&info, line_count, true, time); +- } ++ seq = find_first_fitting_seq(clear_seq, -1, size, true, time); + + prb_rec_init_rd(&r, &info, text, LOG_LINE_MAX + PREFIX_MAX); + +@@ -3432,7 +3460,6 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + char *buf, size_t size, size_t *len_out) + { + struct printk_info info; +- unsigned int line_count; + struct printk_record r; + unsigned long flags; + u64 seq; +@@ -3460,26 +3487,12 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, + + /* + * Find first record that fits, including all following records, +- * into the user-provided buffer for this dump. ++ * into the user-provided buffer for this dump. Pass in size-1 ++ * because this function (by way of record_print_text()) will ++ * not write more than size-1 bytes of text into @buf. + */ +- +- prb_for_each_info(dumper->cur_seq, prb, seq, &info, &line_count) { +- if (info.seq >= dumper->next_seq) +- break; +- len += get_record_print_text_size(&info, line_count, syslog, time); +- } +- +- /* +- * Move first record forward until length fits into the buffer. Ignore +- * newest messages that were not counted in the above cycle. Messages +- * might appear and get lost in the meantime. This is the best effort +- * that prevents an infinite loop. +- */ +- prb_for_each_info(dumper->cur_seq, prb, seq, &info, &line_count) { +- if (len < size || info.seq >= dumper->next_seq) +- break; +- len -= get_record_print_text_size(&info, line_count, syslog, time); +- } ++ seq = find_first_fitting_seq(dumper->cur_seq, dumper->next_seq, ++ size - 1, syslog, time); + + /* + * Next kmsg_dump_get_buffer() invocation will dump block of +-- +2.43.0 + |