Skip to content

Commit

Permalink
Merge tag 'trace-ringbuffer-v6.15-2' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/trace/linux-trace

Pull ring-buffer updates from Steven Rostedt:

 - Restructure the persistent memory to have a "scratch" area

   Instead of hard coding the KASLR offset in the persistent memory by
   the ring buffer, push that work up to the callers of the persistent
   memory as they are the ones that need this information. The offsets
   and such is not important to the ring buffer logic and it should not
   be part of that.

   A scratch pad is now created when the caller allocates a ring buffer
   from persistent memory by stating how much memory it needs to save.

 - Allow where modules are loaded to be saved in the new scratch pad

   Save the addresses of modules when they are loaded into the
   persistent memory scratch pad.

 - A new module_for_each_mod() helper function was created

   With the acknowledgement of the module maintainers a new module
   helper function was created to iterate over all the currently loaded
   modules. This has a callback to be called for each module. This is
   needed for when tracing is started in the persistent buffer and the
   currently loaded modules need to be saved in the scratch area.

 - Expose the last boot information where the kernel and modules were
   loaded

   The last_boot_info file is updated to print out the addresses of
   where the kernel "_text" location was loaded from a previous boot, as
   well as where the modules are loaded. If the buffer is recording the
   current boot, it only prints "# Current" so that it does not expose
   the KASLR offset of the currently running kernel.

 - Allow the persistent ring buffer to be released (freed)

   To have this in production environments, where the kernel command
   line can not be changed easily, the ring buffer needs to be freed
   when it is not going to be used. The memory for the buffer will
   always be allocated at boot up, but if the system isn't going to
   enable tracing, the memory needs to be freed. Allow it to be freed
   and added back to the kernel memory pool.

 - Allow stack traces to print the function names in the persistent
   buffer

   Now that the modules are saved in the persistent ring buffer, if the
   same modules are loaded, the printing of the function names will
   examine the saved modules. If the module is found in the scratch area
   and is also loaded, then it will do the offset shift and use kallsyms
   to display the function name. If the address is not found, it simply
   displays the address from the previous boot in hex.

* tag 'trace-ringbuffer-v6.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing: Use _text and the kernel offset in last_boot_info
  tracing: Show last module text symbols in the stacktrace
  ring-buffer: Remove the unused variable bmeta
  tracing: Skip update_last_data() if cleared and remove active check for save_mod()
  tracing: Initialize scratch_size to zero to prevent UB
  tracing: Fix a compilation error without CONFIG_MODULES
  tracing: Freeable reserved ring buffer
  mm/memblock: Add reserved memory release function
  tracing: Update modules to persistent instances when loaded
  tracing: Show module names and addresses of last boot
  tracing: Have persistent trace instances save module addresses
  module: Add module_for_each_mod() function
  tracing: Have persistent trace instances save KASLR offset
  ring-buffer: Add ring_buffer_meta_scratch()
  ring-buffer: Add buffer meta data for persistent ring buffer
  ring-buffer: Use kaslr address instead of text delta
  ring-buffer: Fix bytes_dropped calculation issue
  • Loading branch information
Linus Torvalds committed Mar 31, 2025
2 parents 6097068 + 028a58e commit 46d29f2
Show file tree
Hide file tree
Showing 10 changed files with 639 additions and 159 deletions.
1 change: 1 addition & 0 deletions include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -4110,6 +4110,7 @@ void vma_pgtable_walk_begin(struct vm_area_struct *vma);
void vma_pgtable_walk_end(struct vm_area_struct *vma);

int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *size);
int reserve_mem_release_by_name(const char *name);

#ifdef CONFIG_64BIT
int do_mseal(unsigned long start, size_t len_in, unsigned long flags);
Expand Down
6 changes: 6 additions & 0 deletions include/linux/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,8 @@ static inline bool is_livepatch_module(struct module *mod)

void set_module_sig_enforced(void);

void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data);

#else /* !CONFIG_MODULES... */

static inline struct module *__module_address(unsigned long addr)
Expand Down Expand Up @@ -878,6 +880,10 @@ static inline bool module_is_coming(struct module *mod)
{
return false;
}

static inline void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
{
}
#endif /* CONFIG_MODULES */

#ifdef CONFIG_SYSFS
Expand Down
8 changes: 4 additions & 4 deletions include/linux/ring_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
struct trace_buffer *__ring_buffer_alloc_range(unsigned long size, unsigned flags,
int order, unsigned long start,
unsigned long range_size,
unsigned long scratch_size,
struct lock_class_key *key);

bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, long *text,
long *data);
void *ring_buffer_meta_scratch(struct trace_buffer *buffer, unsigned int *size);

/*
* Because the ring buffer is generic, if other users of the ring buffer get
Expand All @@ -113,11 +113,11 @@ bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, long *text,
* traced by ftrace, it can produce lockdep warnings. We need to keep each
* ring buffer's lock class separate.
*/
#define ring_buffer_alloc_range(size, flags, order, start, range_size) \
#define ring_buffer_alloc_range(size, flags, order, start, range_size, s_size) \
({ \
static struct lock_class_key __key; \
__ring_buffer_alloc_range((size), (flags), (order), (start), \
(range_size), &__key); \
(range_size), (s_size), &__key); \
})

typedef bool (*ring_buffer_cond_fn)(void *data);
Expand Down
13 changes: 13 additions & 0 deletions kernel/module/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3744,6 +3744,19 @@ bool is_module_text_address(unsigned long addr)
return __module_text_address(addr) != NULL;
}

void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
{
struct module *mod;

guard(rcu)();
list_for_each_entry_rcu(mod, &modules, list) {
if (mod->state == MODULE_STATE_UNFORMED)
continue;
if (func(mod, data))
break;
}
}

/**
* __module_text_address() - get the module whose code contains an address.
* @addr: the address.
Expand Down
Loading

0 comments on commit 46d29f2

Please sign in to comment.