Skip to content

Commit 623b1f8

Browse files
committed
ring-buffer: Fix wake ups when buffer_percent is set to 100
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 <mark.rutland@arm.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Fixes: 03329f9 ("tracing: Add tracefs file buffer_percentage") Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 7e8358e commit 623b1f8

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

kernel/trace/ring_buffer.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -881,9 +881,14 @@ static __always_inline bool full_hit(struct trace_buffer *buffer, int cpu, int f
881881
if (!nr_pages || !full)
882882
return true;
883883

884-
dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
884+
/*
885+
* Add one as dirty will never equal nr_pages, as the sub-buffer
886+
* that the writer is on is not counted as dirty.
887+
* This is needed if "buffer_percent" is set to 100.
888+
*/
889+
dirty = ring_buffer_nr_dirty_pages(buffer, cpu) + 1;
885890

886-
return (dirty * 100) > (full * nr_pages);
891+
return (dirty * 100) >= (full * nr_pages);
887892
}
888893

889894
/*

0 commit comments

Comments
 (0)