diff options
author | Steven Rostedt (Google) <rostedt@goodmis.org> | 2024-02-28 14:28:05 -0500 |
---|---|---|
committer | Steven Rostedt (Google) <rostedt@goodmis.org> | 2024-05-10 18:58:57 -0400 |
commit | 8e378b52e968ed1adf33f35649a7c2ca8a72a4b5 (patch) | |
tree | 9528c8e8291c3c6fa5c9f9dbb56b59c76f853446 | |
parent | f4ec0909dfcc6c147161bc41cdacd2ee1001ab4d (diff) | |
download | linux-trace-trace/persistent-ring-buf-v5.15.tar.gz |
tracing: Add option to use memmap boot memory for trace boot instancetrace/persistent-ring-buf-v5.15
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*4096:trace trace_instance=boot_mapped@trace
The above will allocate 12 megs with 4096 alignment and label it "trace".
The second parameter will create a "boot_mapped" instance and use the
memory reserved and labeled as "trace" 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.
Change-Id: Ib68138b3d932c4bef69ae743f48da20ba12c0a61
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-rw-r--r-- | kernel/trace/trace.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a5e073701ed7f..bc3ece409d797 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -9739,6 +9739,31 @@ out_unlock: 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. * @name: The name of the trace array to be looked up/created. @@ -10470,6 +10495,7 @@ __init static void enable_instances(void) { struct trace_array *tr; char *curr_str; + char *name; char *str; char *tok; @@ -10478,16 +10504,30 @@ __init static void enable_instances(void) str = boot_instance_info; while ((curr_str = strsep(&str, "\t"))) { + unsigned long size = 0; + u64 start = 0; tok = strsep(&curr_str, ","); + name = strsep(&tok, "@"); + + if (tok) { + if (memmap_named(tok, &start, &size)) + start = map_pages(start, size); + if (!start) { + pr_warn("Failed to map boot instance %s to %s\n", name, tok); + continue; + } + } - tr = trace_array_get_by_name(tok); + tr = trace_array_create(name, start, size); if (!tr) { pr_warn("Failed to create instance buffer %s\n", curr_str); continue; } - /* Allow user space to delete it */ - trace_array_put(tr); + + /* Do not allow mapped buffers to be deleted */ + if (start) + tr->ref++; } } |