linux-trace-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ring-buffer: Include dropped pages in counting dirty patches
@ 2022-10-21 16:30 Steven Rostedt
  2022-10-24 13:13 ` Masami Hiramatsu
  0 siblings, 1 reply; 3+ messages in thread
From: Steven Rostedt @ 2022-10-21 16:30 UTC (permalink / raw)
  To: LKML; +Cc: Linux Trace Kernel, Masami Hiramatsu

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

The function ring_buffer_nr_dirty_pages() was created to find out how many
pages are filled in the ring buffer. There's two running counters. One is
incremented whenever a new page is touched (pages_touched) and the other
is whenever a page is read (pages_read). The dirty count is the number
touched minus the number read. This is used to determine if a blocked task
should be woken up if the percentage of the ring buffer it is waiting for
is hit.

The problem is that it does not take into account dropped pages (when the
new writes overwrite pages that were not read). And then the dirty pages
will always be greater than the percentage.

Add a new counter to keep track of lost pages, and include that in the
accounting of dirty pages so that it is actually accurate.

Fixes: 2c2b0a78b3739 ("ring-buffer: Add percentage of ring buffer full to wake up reader")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 kernel/trace/ring_buffer.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index b60047de897e..f712006f6dd3 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -519,6 +519,7 @@ struct ring_buffer_per_cpu {
 	local_t				committing;
 	local_t				commits;
 	local_t				pages_touched;
+	local_t				pages_lost;
 	local_t				pages_read;
 	long				last_pages_touch;
 	size_t				shortest_full;
@@ -894,10 +895,18 @@ size_t ring_buffer_nr_pages(struct trace_buffer *buffer, int cpu)
 size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu)
 {
 	size_t read;
+	size_t lost;
 	size_t cnt;
 
 	read = local_read(&buffer->buffers[cpu]->pages_read);
+	lost = local_read(&buffer->buffers[cpu]->pages_lost);
 	cnt = local_read(&buffer->buffers[cpu]->pages_touched);
+
+	if (WARN_ON_ONCE(cnt < lost))
+		return 0;
+
+	cnt -= lost;
+
 	/* The reader can read an empty page, but not more than that */
 	if (cnt < read) {
 		WARN_ON_ONCE(read > cnt + 1);
@@ -2020,6 +2029,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
 			 */
 			local_add(page_entries, &cpu_buffer->overrun);
 			local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
+			local_inc(&cpu_buffer->pages_lost);
 		}
 
 		/*
@@ -2504,6 +2514,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
 		 */
 		local_add(entries, &cpu_buffer->overrun);
 		local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
+		local_inc(&cpu_buffer->pages_lost);
 
 		/*
 		 * The entries will be zeroed out when we move the
@@ -5254,6 +5265,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
 	local_set(&cpu_buffer->committing, 0);
 	local_set(&cpu_buffer->commits, 0);
 	local_set(&cpu_buffer->pages_touched, 0);
+	local_set(&cpu_buffer->pages_lost, 0);
 	local_set(&cpu_buffer->pages_read, 0);
 	cpu_buffer->last_pages_touch = 0;
 	cpu_buffer->shortest_full = 0;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] ring-buffer: Include dropped pages in counting dirty patches
  2022-10-21 16:30 [PATCH] ring-buffer: Include dropped pages in counting dirty patches Steven Rostedt
@ 2022-10-24 13:13 ` Masami Hiramatsu
  2022-10-24 14:58   ` Steven Rostedt
  0 siblings, 1 reply; 3+ messages in thread
From: Masami Hiramatsu @ 2022-10-24 13:13 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: LKML, Linux Trace Kernel, Masami Hiramatsu

On Fri, 21 Oct 2022 12:30:13 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

> From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
> 
> The function ring_buffer_nr_dirty_pages() was created to find out how many
> pages are filled in the ring buffer. There's two running counters. One is
> incremented whenever a new page is touched (pages_touched) and the other
> is whenever a page is read (pages_read). The dirty count is the number
> touched minus the number read. This is used to determine if a blocked task
> should be woken up if the percentage of the ring buffer it is waiting for
> is hit.
> 
> The problem is that it does not take into account dropped pages (when the
> new writes overwrite pages that were not read). And then the dirty pages
> will always be greater than the percentage.
> 
> Add a new counter to keep track of lost pages, and include that in the
> accounting of dirty pages so that it is actually accurate.
> 
> Fixes: 2c2b0a78b3739 ("ring-buffer: Add percentage of ring buffer full to wake up reader")
> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

This looks good to me. But I have just a nitpick below.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>


> ---
>  kernel/trace/ring_buffer.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> index b60047de897e..f712006f6dd3 100644
> --- a/kernel/trace/ring_buffer.c
> +++ b/kernel/trace/ring_buffer.c
> @@ -519,6 +519,7 @@ struct ring_buffer_per_cpu {
>  	local_t				committing;
>  	local_t				commits;
>  	local_t				pages_touched;
> +	local_t				pages_lost;
>  	local_t				pages_read;
>  	long				last_pages_touch;
>  	size_t				shortest_full;
> @@ -894,10 +895,18 @@ size_t ring_buffer_nr_pages(struct trace_buffer *buffer, int cpu)
>  size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu)
>  {
>  	size_t read;
> +	size_t lost;
>  	size_t cnt;
>  
>  	read = local_read(&buffer->buffers[cpu]->pages_read);
> +	lost = local_read(&buffer->buffers[cpu]->pages_lost);
>  	cnt = local_read(&buffer->buffers[cpu]->pages_touched);
> +
> +	if (WARN_ON_ONCE(cnt < lost))
> +		return 0;
> +
> +	cnt -= lost;
> +
>  	/* The reader can read an empty page, but not more than that */
>  	if (cnt < read) {
>  		WARN_ON_ONCE(read > cnt + 1);
> @@ -2020,6 +2029,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
>  			 */
>  			local_add(page_entries, &cpu_buffer->overrun);
>  			local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
> +			local_inc(&cpu_buffer->pages_lost);

Maybe we can make this part a static helper function so that we don't
repeat it below?

>  		}
>  
>  		/*
> @@ -2504,6 +2514,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
>  		 */
>  		local_add(entries, &cpu_buffer->overrun);
>  		local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
> +		local_inc(&cpu_buffer->pages_lost);

Thanks,

>  
>  		/*
>  		 * The entries will be zeroed out when we move the
> @@ -5254,6 +5265,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
>  	local_set(&cpu_buffer->committing, 0);
>  	local_set(&cpu_buffer->commits, 0);
>  	local_set(&cpu_buffer->pages_touched, 0);
> +	local_set(&cpu_buffer->pages_lost, 0);
>  	local_set(&cpu_buffer->pages_read, 0);
>  	cpu_buffer->last_pages_touch = 0;
>  	cpu_buffer->shortest_full = 0;
> -- 
> 2.35.1
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ring-buffer: Include dropped pages in counting dirty patches
  2022-10-24 13:13 ` Masami Hiramatsu
@ 2022-10-24 14:58   ` Steven Rostedt
  0 siblings, 0 replies; 3+ messages in thread
From: Steven Rostedt @ 2022-10-24 14:58 UTC (permalink / raw)
  To: Masami Hiramatsu (Google); +Cc: LKML, Linux Trace Kernel

On Mon, 24 Oct 2022 22:13:28 +0900
Masami Hiramatsu (Google) <mhiramat@kernel.org> wrote:

> > @@ -2020,6 +2029,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
> >  			 */
> >  			local_add(page_entries, &cpu_buffer->overrun);
> >  			local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
> > +			local_inc(&cpu_buffer->pages_lost);  
> 
> Maybe we can make this part a static helper function so that we don't
> repeat it below?

Makes sense. I'll send a v2.

-- Steve

> 
> >  		}
> >  
> >  		/*
> > @@ -2504,6 +2514,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
> >  		 */
> >  		local_add(entries, &cpu_buffer->overrun);
> >  		local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
> > +		local_inc(&cpu_buffer->pages_lost);  


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-10-24 20:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-21 16:30 [PATCH] ring-buffer: Include dropped pages in counting dirty patches Steven Rostedt
2022-10-24 13:13 ` Masami Hiramatsu
2022-10-24 14:58   ` Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).