Skip to content

Commit

Permalink
tracing: Have reserve_mem use phys_to_virt() and separate from memmap…
Browse files Browse the repository at this point in the history
… buffer

The reserve_mem kernel command line option may pass back a physical
address, but the memory is still part of the normal memory just like
using memblock_alloc() would be. This means that the physical memory
returned by the reserve_mem command line option can be converted directly
to virtual memory by simply using phys_to_virt().

When freeing the buffer there's no need to call vunmap() anymore as the
memory allocated by reserve_mem is freed by the call to
reserve_mem_release_by_name().

Because the persistent ring buffer can also be allocated via the memmap
option, which *is* different than normal memory as it cannot be added back
to the buddy system, it must be treated differently. It still needs to be
virtually mapped to have access to it. It also can not be freed nor can it
ever be memory mapped to user space.

Create a new trace_array flag called TRACE_ARRAY_FL_MEMMAP which gets set
if the buffer is created by the memmap option, and this will prevent the
buffer from being memory mapped by user space.

Also increment the ref count for memmap'ed buffers so that they can never
be freed.

Link: https://lore.kernel.org/all/Z-wFszhJ_9o4dc8O@kernel.org/

Cc: Linus Torvalds <torvalds@linux-foundation.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: Vlastimil Babka <vbabka@suse.cz>
Cc: Jann Horn <jannh@google.com>
Link: https://lore.kernel.org/20250402144953.583750106@goodmis.org
Suggested-by: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
  • Loading branch information
Steven Rostedt committed Apr 2, 2025
1 parent c44a14f commit 34ea8fa
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
23 changes: 16 additions & 7 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -8492,6 +8492,10 @@ static int tracing_buffers_mmap(struct file *filp, struct vm_area_struct *vma)
struct trace_iterator *iter = &info->iter;
int ret = 0;

/* A memmap'ed buffer is not supported for user space mmap */
if (iter->tr->flags & TRACE_ARRAY_FL_MEMMAP)
return -ENODEV;

/* Currently the boot mapped buffer is not supported for mmap */
if (iter->tr->flags & TRACE_ARRAY_FL_BOOT)
return -ENODEV;
Expand Down Expand Up @@ -9600,9 +9604,6 @@ static void free_trace_buffers(struct trace_array *tr)
#ifdef CONFIG_TRACER_MAX_TRACE
free_trace_buffer(&tr->max_buffer);
#endif

if (tr->range_addr_start)
vunmap((void *)tr->range_addr_start);
}

static void init_trace_flags_index(struct trace_array *tr)
Expand Down Expand Up @@ -10696,6 +10697,7 @@ static inline void do_allocate_snapshot(const char *name) { }
__init static void enable_instances(void)
{
struct trace_array *tr;
bool memmap_area = false;
char *curr_str;
char *name;
char *str;
Expand Down Expand Up @@ -10764,6 +10766,7 @@ __init static void enable_instances(void)
name);
continue;
}
memmap_area = true;
} else if (tok) {
if (!reserve_mem_find_by_name(tok, &start, &size)) {
start = 0;
Expand All @@ -10784,7 +10787,10 @@ __init static void enable_instances(void)
continue;
}

addr = map_pages(start, size);
if (memmap_area)
addr = map_pages(start, size);
else
addr = (unsigned long)phys_to_virt(start);
if (addr) {
pr_info("Tracing: mapped boot instance %s at physical memory %pa of size 0x%lx\n",
name, &start, (unsigned long)size);
Expand All @@ -10811,10 +10817,13 @@ __init static void enable_instances(void)
update_printk_trace(tr);

/*
* If start is set, then this is a mapped buffer, and
* cannot be deleted by user space, so keep the reference
* to it.
* memmap'd buffers can not be freed.
*/
if (memmap_area) {
tr->flags |= TRACE_ARRAY_FL_MEMMAP;
tr->ref++;
}

if (start) {
tr->flags |= TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT;
tr->range_name = no_free_ptr(rname);
Expand Down
1 change: 1 addition & 0 deletions kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ enum {
TRACE_ARRAY_FL_BOOT = BIT(1),
TRACE_ARRAY_FL_LAST_BOOT = BIT(2),
TRACE_ARRAY_FL_MOD_INIT = BIT(3),
TRACE_ARRAY_FL_MEMMAP = BIT(4),
};

#ifdef CONFIG_MODULES
Expand Down

0 comments on commit 34ea8fa

Please sign in to comment.