tracing: Implement creating an instance based on a given memory region

Allow for creating a new instance by passing in an address and size to map
the ring buffer for the instance to.

This will allow features like a pstore memory mapped region to be used for
an tracing instance ring buffer that can be retrieved from one boot to the
next.

Link: https://lkml.kernel.org/r/20240612232025.692086240@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: Vincent Donnefort <vdonnefort@google.com>
Cc: Joel Fernandes <joel@joelfernandes.org>
Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vineeth Pillai <vineeth@bitbyteword.org>
Cc: Youssef Esmat <youssefesmat@google.com>
Cc: Beau Belgrave <beaub@linux.microsoft.com>
Cc: Alexander Graf <graf@amazon.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Ross Zwisler <zwisler@google.com>
Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent b14d0329
...@@ -4921,6 +4921,11 @@ static int tracing_open(struct inode *inode, struct file *file) ...@@ -4921,6 +4921,11 @@ static int tracing_open(struct inode *inode, struct file *file)
static bool static bool
trace_ok_for_array(struct tracer *t, struct trace_array *tr) trace_ok_for_array(struct tracer *t, struct trace_array *tr)
{ {
#ifdef CONFIG_TRACER_SNAPSHOT
/* arrays with mapped buffer range do not have snapshots */
if (tr->range_addr_start && t->use_max_tr)
return false;
#endif
return (tr->flags & TRACE_ARRAY_FL_GLOBAL) || t->allow_instances; return (tr->flags & TRACE_ARRAY_FL_GLOBAL) || t->allow_instances;
} }
...@@ -8664,11 +8669,13 @@ tracing_init_tracefs_percpu(struct trace_array *tr, long cpu) ...@@ -8664,11 +8669,13 @@ tracing_init_tracefs_percpu(struct trace_array *tr, long cpu)
tr, cpu, &tracing_entries_fops); tr, cpu, &tracing_entries_fops);
#ifdef CONFIG_TRACER_SNAPSHOT #ifdef CONFIG_TRACER_SNAPSHOT
if (!tr->range_addr_start) {
trace_create_cpu_file("snapshot", TRACE_MODE_WRITE, d_cpu, trace_create_cpu_file("snapshot", TRACE_MODE_WRITE, d_cpu,
tr, cpu, &snapshot_fops); tr, cpu, &snapshot_fops);
trace_create_cpu_file("snapshot_raw", TRACE_MODE_READ, d_cpu, trace_create_cpu_file("snapshot_raw", TRACE_MODE_READ, d_cpu,
tr, cpu, &snapshot_raw_fops); tr, cpu, &snapshot_raw_fops);
}
#endif #endif
} }
...@@ -9205,7 +9212,18 @@ allocate_trace_buffer(struct trace_array *tr, struct array_buffer *buf, int size ...@@ -9205,7 +9212,18 @@ allocate_trace_buffer(struct trace_array *tr, struct array_buffer *buf, int size
buf->tr = tr; buf->tr = tr;
if (tr->range_addr_start && tr->range_addr_size) {
buf->buffer = ring_buffer_alloc_range(size, rb_flags, 0,
tr->range_addr_start,
tr->range_addr_size);
/*
* This is basically the same as a mapped buffer,
* with the same restrictions.
*/
tr->mapped++;
} else {
buf->buffer = ring_buffer_alloc(size, rb_flags); buf->buffer = ring_buffer_alloc(size, rb_flags);
}
if (!buf->buffer) if (!buf->buffer)
return -ENOMEM; return -ENOMEM;
...@@ -9242,6 +9260,10 @@ static int allocate_trace_buffers(struct trace_array *tr, int size) ...@@ -9242,6 +9260,10 @@ static int allocate_trace_buffers(struct trace_array *tr, int size)
return ret; return ret;
#ifdef CONFIG_TRACER_MAX_TRACE #ifdef CONFIG_TRACER_MAX_TRACE
/* Fix mapped buffer trace arrays do not have snapshot buffers */
if (tr->range_addr_start)
return 0;
ret = allocate_trace_buffer(tr, &tr->max_buffer, ret = allocate_trace_buffer(tr, &tr->max_buffer,
allocate_snapshot ? size : 1); allocate_snapshot ? size : 1);
if (MEM_FAIL(ret, "Failed to allocate trace buffer\n")) { if (MEM_FAIL(ret, "Failed to allocate trace buffer\n")) {
...@@ -9342,7 +9364,9 @@ static int trace_array_create_dir(struct trace_array *tr) ...@@ -9342,7 +9364,9 @@ static int trace_array_create_dir(struct trace_array *tr)
} }
static struct trace_array * static struct trace_array *
trace_array_create_systems(const char *name, const char *systems) trace_array_create_systems(const char *name, const char *systems,
unsigned long range_addr_start,
unsigned long range_addr_size)
{ {
struct trace_array *tr; struct trace_array *tr;
int ret; int ret;
...@@ -9368,6 +9392,10 @@ trace_array_create_systems(const char *name, const char *systems) ...@@ -9368,6 +9392,10 @@ trace_array_create_systems(const char *name, const char *systems)
goto out_free_tr; goto out_free_tr;
} }
/* Only for boot up memory mapped ring buffers */
tr->range_addr_start = range_addr_start;
tr->range_addr_size = range_addr_size;
tr->trace_flags = global_trace.trace_flags & ~ZEROED_TRACE_FLAGS; tr->trace_flags = global_trace.trace_flags & ~ZEROED_TRACE_FLAGS;
cpumask_copy(tr->tracing_cpumask, cpu_all_mask); cpumask_copy(tr->tracing_cpumask, cpu_all_mask);
...@@ -9425,7 +9453,7 @@ trace_array_create_systems(const char *name, const char *systems) ...@@ -9425,7 +9453,7 @@ trace_array_create_systems(const char *name, const char *systems)
static struct trace_array *trace_array_create(const char *name) static struct trace_array *trace_array_create(const char *name)
{ {
return trace_array_create_systems(name, NULL); return trace_array_create_systems(name, NULL, 0, 0);
} }
static int instance_mkdir(const char *name) static int instance_mkdir(const char *name)
...@@ -9479,7 +9507,7 @@ struct trace_array *trace_array_get_by_name(const char *name, const char *system ...@@ -9479,7 +9507,7 @@ struct trace_array *trace_array_get_by_name(const char *name, const char *system
goto out_unlock; goto out_unlock;
} }
tr = trace_array_create_systems(name, systems); tr = trace_array_create_systems(name, systems, 0, 0);
if (IS_ERR(tr)) if (IS_ERR(tr))
tr = NULL; tr = NULL;
...@@ -9672,8 +9700,10 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) ...@@ -9672,8 +9700,10 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
MEM_FAIL(1, "Could not allocate function filter files"); MEM_FAIL(1, "Could not allocate function filter files");
#ifdef CONFIG_TRACER_SNAPSHOT #ifdef CONFIG_TRACER_SNAPSHOT
if (!tr->range_addr_start) {
trace_create_file("snapshot", TRACE_MODE_WRITE, d_tracer, trace_create_file("snapshot", TRACE_MODE_WRITE, d_tracer,
tr, &snapshot_fops); tr, &snapshot_fops);
}
#endif #endif
trace_create_file("error_log", TRACE_MODE_WRITE, d_tracer, trace_create_file("error_log", TRACE_MODE_WRITE, d_tracer,
......
...@@ -336,7 +336,6 @@ struct trace_array { ...@@ -336,7 +336,6 @@ struct trace_array {
bool allocated_snapshot; bool allocated_snapshot;
spinlock_t snapshot_trigger_lock; spinlock_t snapshot_trigger_lock;
unsigned int snapshot; unsigned int snapshot;
unsigned int mapped;
unsigned long max_latency; unsigned long max_latency;
#ifdef CONFIG_FSNOTIFY #ifdef CONFIG_FSNOTIFY
struct dentry *d_max_latency; struct dentry *d_max_latency;
...@@ -344,6 +343,11 @@ struct trace_array { ...@@ -344,6 +343,11 @@ struct trace_array {
struct irq_work fsnotify_irqwork; struct irq_work fsnotify_irqwork;
#endif #endif
#endif #endif
/* The below is for memory mapped ring buffer */
unsigned int mapped;
unsigned long range_addr_start;
unsigned long range_addr_size;
struct trace_pid_list __rcu *filtered_pids; struct trace_pid_list __rcu *filtered_pids;
struct trace_pid_list __rcu *filtered_no_pids; struct trace_pid_list __rcu *filtered_no_pids;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment