[PATCH v3 4/5] ring-buffer: Use flush_kernel_vmap_range() over flush_dcache_folio()

Steven Rostedt posted 5 patches 1 month, 1 week ago
[PATCH v3 4/5] ring-buffer: Use flush_kernel_vmap_range() over flush_dcache_folio()
Posted by Steven Rostedt 1 month, 1 week ago
From: Steven Rostedt <rostedt@goodmis.org>

Some architectures do not have data cache coherency between user and
kernel space. For these architectures, the cache needs to be flushed on
both the kernel and user addresses so that user space can see the updates
the kernel has made.

Instead of using flush_dcache_folio() and playing with virt_to_folio()
within the call to that function, use flush_kernel_vmap_range() which
takes the virtual address and does the work for those architectures that
need it.

Link: https://lore.kernel.org/all/CAG48ez3w0my4Rwttbc5tEbNsme6tc0mrSN95thjXUFaJ3aQ6SA@mail.gmail.com/

Suggested-by: Jann Horn <jannh@google.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 kernel/trace/ring_buffer.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index f25966b3a1fc..d4b0f7b55cce 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -6016,7 +6016,7 @@ static void rb_update_meta_page(struct ring_buffer_per_cpu *cpu_buffer)
 	meta->read = cpu_buffer->read;
 
 	/* Some archs do not have data cache coherency between kernel and user-space */
-	flush_dcache_folio(virt_to_folio(cpu_buffer->meta_page));
+	flush_kernel_vmap_range(cpu_buffer->meta_page, PAGE_SIZE);
 }
 
 static void
@@ -7319,7 +7319,8 @@ int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu)
 
 out:
 	/* Some archs do not have data cache coherency between kernel and user-space */
-	flush_dcache_folio(virt_to_folio(cpu_buffer->reader_page->page));
+	flush_kernel_vmap_range(cpu_buffer->reader_page->page,
+				buffer->subbuf_size + BUF_PAGE_HDR_SIZE);
 
 	rb_update_meta_page(cpu_buffer);
 
-- 
2.47.2
Re: [PATCH v3 4/5] ring-buffer: Use flush_kernel_vmap_range() over flush_dcache_folio()
Posted by Steven Rostedt 1 month, 1 week ago
On Tue, 01 Apr 2025 16:25:53 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

>  
>  static void
> @@ -7319,7 +7319,8 @@ int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu)
>  
>  out:
>  	/* Some archs do not have data cache coherency between kernel and user-space */
> -	flush_dcache_folio(virt_to_folio(cpu_buffer->reader_page->page));
> +	flush_kernel_vmap_range(cpu_buffer->reader_page->page,
> +				buffer->subbuf_size + BUF_PAGE_HDR_SIZE);
>  
>  	rb_update_meta_page(cpu_buffer);
>  

This patch actually fixes a bug (I need to update the change log).

The previous code only flushed a page. But if the sub-buffer size was 2 or
more pages, it would not flush the rest of the sub-buffer.

-- Steve