From: Greg Kroah-Hartman Date: Wed, 3 Jan 2024 10:18:46 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v5.10.206~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4eef32594ee7de90b744c091dff3226063ea6ddf;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: ring-buffer-fix-wake-ups-when-buffer_percent-is-set-to-100.patch tracing-fix-blocked-reader-of-snapshot-buffer.patch --- diff --git a/queue-5.10/ring-buffer-fix-wake-ups-when-buffer_percent-is-set-to-100.patch b/queue-5.10/ring-buffer-fix-wake-ups-when-buffer_percent-is-set-to-100.patch new file mode 100644 index 00000000000..910dabeeb25 --- /dev/null +++ b/queue-5.10/ring-buffer-fix-wake-ups-when-buffer_percent-is-set-to-100.patch @@ -0,0 +1,73 @@ +From 623b1f896fa8a669a277ee5a258307a16c7377a3 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Google)" +Date: Tue, 26 Dec 2023 12:59:02 -0500 +Subject: ring-buffer: Fix wake ups when buffer_percent is set to 100 + +From: Steven Rostedt (Google) + +commit 623b1f896fa8a669a277ee5a258307a16c7377a3 upstream. + +The tracefs file "buffer_percent" is to allow user space to set a +water-mark on how much of the tracing ring buffer needs to be filled in +order to wake up a blocked reader. + + 0 - is to wait until any data is in the buffer + 1 - is to wait for 1% of the sub buffers to be filled + 50 - would be half of the sub buffers are filled with data + 100 - is not to wake the waiter until the ring buffer is completely full + +Unfortunately the test for being full was: + + dirty = ring_buffer_nr_dirty_pages(buffer, cpu); + return (dirty * 100) > (full * nr_pages); + +Where "full" is the value for "buffer_percent". + +There is two issues with the above when full == 100. + +1. dirty * 100 > 100 * nr_pages will never be true + That is, the above is basically saying that if the user sets + buffer_percent to 100, more pages need to be dirty than exist in the + ring buffer! + +2. The page that the writer is on is never considered dirty, as dirty + pages are only those that are full. When the writer goes to a new + sub-buffer, it clears the contents of that sub-buffer. + +That is, even if the check was ">=" it would still not be equal as the +most pages that can be considered "dirty" is nr_pages - 1. + +To fix this, add one to dirty and use ">=" in the compare. + +Link: https://lore.kernel.org/linux-trace-kernel/20231226125902.4a057f1d@gandalf.local.home + +Cc: stable@vger.kernel.org +Cc: Mark Rutland +Cc: Mathieu Desnoyers +Acked-by: Masami Hiramatsu (Google) +Fixes: 03329f9939781 ("tracing: Add tracefs file buffer_percentage") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ring_buffer.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -810,9 +810,14 @@ static __always_inline bool full_hit(str + if (!nr_pages || !full) + return true; + +- dirty = ring_buffer_nr_dirty_pages(buffer, cpu); ++ /* ++ * Add one as dirty will never equal nr_pages, as the sub-buffer ++ * that the writer is on is not counted as dirty. ++ * This is needed if "buffer_percent" is set to 100. ++ */ ++ dirty = ring_buffer_nr_dirty_pages(buffer, cpu) + 1; + +- return (dirty * 100) > (full * nr_pages); ++ return (dirty * 100) >= (full * nr_pages); + } + + /* diff --git a/queue-5.10/series b/queue-5.10/series index 185c6972f40..2aee73b2491 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -65,3 +65,5 @@ scsi-core-make-scsi_get_lba-return-the-lba.patch scsi-core-use-scsi_cmd_to_rq-instead-of-scsi_cmnd.re.patch scsi-core-use-a-structure-member-to-track-the-scsi-c.patch scsi-core-always-send-batch-on-reset-or-error-handli.patch +ring-buffer-fix-wake-ups-when-buffer_percent-is-set-to-100.patch +tracing-fix-blocked-reader-of-snapshot-buffer.patch diff --git a/queue-5.10/tracing-fix-blocked-reader-of-snapshot-buffer.patch b/queue-5.10/tracing-fix-blocked-reader-of-snapshot-buffer.patch new file mode 100644 index 00000000000..2ce16a87161 --- /dev/null +++ b/queue-5.10/tracing-fix-blocked-reader-of-snapshot-buffer.patch @@ -0,0 +1,103 @@ +From 39a7dc23a1ed0fe81141792a09449d124c5953bd Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Google)" +Date: Thu, 28 Dec 2023 09:51:49 -0500 +Subject: tracing: Fix blocked reader of snapshot buffer + +From: Steven Rostedt (Google) + +commit 39a7dc23a1ed0fe81141792a09449d124c5953bd upstream. + +If an application blocks on the snapshot or snapshot_raw files, expecting +to be woken up when a snapshot occurs, it will not happen. Or it may +happen with an unexpected result. + +That result is that the application will be reading the main buffer +instead of the snapshot buffer. That is because when the snapshot occurs, +the main and snapshot buffers are swapped. But the reader has a descriptor +still pointing to the buffer that it originally connected to. + +This is fine for the main buffer readers, as they may be blocked waiting +for a watermark to be hit, and when a snapshot occurs, the data that the +main readers want is now on the snapshot buffer. + +But for waiters of the snapshot buffer, they are waiting for an event to +occur that will trigger the snapshot and they can then consume it quickly +to save the snapshot before the next snapshot occurs. But to do this, they +need to read the new snapshot buffer, not the old one that is now +receiving new data. + +Also, it does not make sense to have a watermark "buffer_percent" on the +snapshot buffer, as the snapshot buffer is static and does not receive new +data except all at once. + +Link: https://lore.kernel.org/linux-trace-kernel/20231228095149.77f5b45d@gandalf.local.home + +Cc: stable@vger.kernel.org +Cc: Mathieu Desnoyers +Cc: Mark Rutland +Acked-by: Masami Hiramatsu (Google) +Fixes: debdd57f5145f ("tracing: Make a snapshot feature available from userspace") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ring_buffer.c | 3 ++- + kernel/trace/trace.c | 20 +++++++++++++++++--- + 2 files changed, 19 insertions(+), 4 deletions(-) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -866,7 +866,8 @@ void ring_buffer_wake_waiters(struct tra + /* make sure the waiters see the new index */ + smp_wmb(); + +- rb_wake_up_waiters(&rbwork->work); ++ /* This can be called in any context */ ++ irq_work_queue(&rbwork->work); + } + + /** +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1892,17 +1892,31 @@ update_max_tr_single(struct trace_array + + __update_max_tr(tr, tsk, cpu); + arch_spin_unlock(&tr->max_lock); ++ ++ /* Any waiters on the old snapshot buffer need to wake up */ ++ ring_buffer_wake_waiters(tr->array_buffer.buffer, RING_BUFFER_ALL_CPUS); + } + #endif /* CONFIG_TRACER_MAX_TRACE */ + + static int wait_on_pipe(struct trace_iterator *iter, int full) + { ++ int ret; ++ + /* Iterators are static, they should be filled or empty */ + if (trace_buffer_iter(iter, iter->cpu_file)) + return 0; + +- return ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file, +- full); ++ ret = ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file, full); ++ ++#ifdef CONFIG_TRACER_MAX_TRACE ++ /* ++ * Make sure this is still the snapshot buffer, as if a snapshot were ++ * to happen, this would now be the main buffer. ++ */ ++ if (iter->snapshot) ++ iter->array_buffer = &iter->tr->max_buffer; ++#endif ++ return ret; + } + + #ifdef CONFIG_FTRACE_STARTUP_TEST +@@ -7953,7 +7967,7 @@ tracing_buffers_splice_read(struct file + if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) + goto out; + +- ret = wait_on_pipe(iter, iter->tr->buffer_percent); ++ ret = wait_on_pipe(iter, iter->snapshot ? 0 : iter->tr->buffer_percent); + if (ret) + goto out; +