tracing: Add option to use memmapped memory for trace boot instance

Add an option to the trace_instance kernel command line parameter that
allows it to use the reserved memory from memmap boot parameter.

  memmap=12M$0x284500000 trace_instance=boot_mapped@0x284500000:12M

The above will reserves 12 megs at the physical address 0x284500000.
The second parameter will create a "boot_mapped" instance and use the
memory reserved as the memory for the ring buffer.

That will create an instance called "boot_mapped":

  /sys/kernel/tracing/instances/boot_mapped

Note, because the ring buffer is using a defined memory ranged, it will
act just like a memory mapped ring buffer. It will not have a snapshot
buffer, as it can't swap out the buffer. The snapshot files as well as any
tracers that uses a snapshot will not be present in the boot_mapped
instance.

Link: https://lkml.kernel.org/r/20240612232026.329660169@goodmis.org

Cc: linux-mm@kvack.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 5f3b6e83
...@@ -6754,6 +6754,15 @@ ...@@ -6754,6 +6754,15 @@
the same thing would happen if it was left off). The irq_handler_entry the same thing would happen if it was left off). The irq_handler_entry
event, and all events under the "initcall" system. event, and all events under the "initcall" system.
If memory has been reserved (see memmap for x86), the instance
can use that memory:
memmap=12M$0x284500000 trace_instance=boot_map@0x284500000:12M
The above will create a "boot_map" instance that uses the physical
memory at 0x284500000 that is 12Megs. The per CPU buffers of that
instance will be split up accordingly.
trace_options=[option-list] trace_options=[option-list]
[FTRACE] Enable or disable tracer options at boot. [FTRACE] Enable or disable tracer options at boot.
The option-list is a comma delimited list of options The option-list is a comma delimited list of options
......
...@@ -9504,6 +9504,31 @@ static int instance_mkdir(const char *name) ...@@ -9504,6 +9504,31 @@ static int instance_mkdir(const char *name)
return ret; return ret;
} }
static u64 map_pages(u64 start, u64 size)
{
struct page **pages;
phys_addr_t page_start;
unsigned int page_count;
unsigned int i;
void *vaddr;
page_count = DIV_ROUND_UP(size, PAGE_SIZE);
page_start = start;
pages = kmalloc_array(page_count, sizeof(struct page *), GFP_KERNEL);
if (!pages)
return 0;
for (i = 0; i < page_count; i++) {
phys_addr_t addr = page_start + i * PAGE_SIZE;
pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
}
vaddr = vmap(pages, page_count, VM_MAP, PAGE_KERNEL);
kfree(pages);
return (u64)(unsigned long)vaddr;
}
/** /**
* trace_array_get_by_name - Create/Lookup a trace array, given its name. * trace_array_get_by_name - Create/Lookup a trace array, given its name.
* @name: The name of the trace array to be looked up/created. * @name: The name of the trace array to be looked up/created.
...@@ -10350,6 +10375,7 @@ __init static void enable_instances(void) ...@@ -10350,6 +10375,7 @@ __init static void enable_instances(void)
{ {
struct trace_array *tr; struct trace_array *tr;
char *curr_str; char *curr_str;
char *name;
char *str; char *str;
char *tok; char *tok;
...@@ -10358,18 +10384,55 @@ __init static void enable_instances(void) ...@@ -10358,18 +10384,55 @@ __init static void enable_instances(void)
str = boot_instance_info; str = boot_instance_info;
while ((curr_str = strsep(&str, "\t"))) { while ((curr_str = strsep(&str, "\t"))) {
unsigned long start = 0;
unsigned long size = 0;
unsigned long addr = 0;
tok = strsep(&curr_str, ","); tok = strsep(&curr_str, ",");
name = strsep(&tok, "@");
if (tok) {
start = memparse(tok, &tok);
if (!start) {
pr_warn("Tracing: Invalid boot instance address for %s\n",
name);
continue;
}
}
if (start) {
if (*tok != ':') {
pr_warn("Tracing: No size specified for instance %s\n", name);
continue;
}
tok++;
size = memparse(tok, &tok);
if (!size) {
pr_warn("Tracing: Invalid boot instance size for %s\n",
name);
continue;
}
addr = map_pages(start, size);
if (addr) {
pr_info("Tracing: mapped boot instance %s at physical memory 0x%lx of size 0x%lx\n",
name, start, size);
} else {
pr_warn("Tracing: Failed to map boot instance %s\n", name);
continue;
}
} else {
/* Only non mapped buffers have snapshot buffers */
if (IS_ENABLED(CONFIG_TRACER_MAX_TRACE)) if (IS_ENABLED(CONFIG_TRACER_MAX_TRACE))
do_allocate_snapshot(tok); do_allocate_snapshot(name);
}
tr = trace_array_get_by_name(tok, NULL); tr = trace_array_create_systems(name, NULL, addr, size);
if (!tr) { if (!tr) {
pr_warn("Failed to create instance buffer %s\n", curr_str); pr_warn("Tracing: Failed to create instance buffer %s\n", curr_str);
continue; continue;
} }
/* Allow user space to delete it */
/* Only allow non mapped buffers to be deleted */
if (!start)
trace_array_put(tr); trace_array_put(tr);
while ((tok = strsep(&curr_str, ","))) { while ((tok = strsep(&curr_str, ","))) {
......
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