ring-buffer: Make sure the spare sub buffer used for reads has same size
authorSteven Rostedt (Google) <rostedt@goodmis.org>
Tue, 19 Dec 2023 18:54:22 +0000 (13:54 -0500)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Thu, 21 Dec 2023 15:55:04 +0000 (10:55 -0500)
Now that the ring buffer specifies the size of its sub buffers, they all
need to be the same size. When doing a read, a swap is done with a spare
page. Make sure they are the same size before doing the swap, otherwise
the read will fail.

Link: https://lore.kernel.org/linux-trace-kernel/20231219185629.763664788@goodmis.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
Cc: Vincent Donnefort <vdonnefort@google.com>
Cc: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
kernel/trace/trace.c

index 711095aa731d33afc5b07f6cb124f6c6bced3221..4dcdc30aa1100b2899be7b7229f2abc8de2130bf 100644 (file)
@@ -7582,6 +7582,7 @@ struct ftrace_buffer_info {
        struct trace_iterator   iter;
        void                    *spare;
        unsigned int            spare_cpu;
+       unsigned int            spare_size;
        unsigned int            read;
 };
 
@@ -8301,6 +8302,15 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
 
        page_size = ring_buffer_subbuf_size_get(iter->array_buffer->buffer);
 
+       /* Make sure the spare matches the current sub buffer size */
+       if (info->spare) {
+               if (page_size != info->spare_size) {
+                       ring_buffer_free_read_page(iter->array_buffer->buffer,
+                                                  info->spare_cpu, info->spare);
+                       info->spare = NULL;
+               }
+       }
+
        if (!info->spare) {
                info->spare = ring_buffer_alloc_read_page(iter->array_buffer->buffer,
                                                          iter->cpu_file);
@@ -8309,6 +8319,7 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
                        info->spare = NULL;
                } else {
                        info->spare_cpu = iter->cpu_file;
+                       info->spare_size = page_size;
                }
        }
        if (!info->spare)