aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Google) <rostedt@goodmis.org>2024-02-28 14:28:05 -0500
committerSteven Rostedt (Google) <rostedt@goodmis.org>2024-05-10 18:58:57 -0400
commit8e378b52e968ed1adf33f35649a7c2ca8a72a4b5 (patch)
tree9528c8e8291c3c6fa5c9f9dbb56b59c76f853446
parentf4ec0909dfcc6c147161bc41cdacd2ee1001ab4d (diff)
downloadlinux-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.c46
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++;
}
}