Skip to content

Commit 46d29f2

Browse files
committed
Merge tag 'trace-ringbuffer-v6.15-2' of git://git.kernel.org/pub/scm/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
2 parents 6097068 + 028a58e commit 46d29f2

File tree

10 files changed

+639
-159
lines changed

10 files changed

+639
-159
lines changed

Diff for: include/linux/mm.h

+1
Original file line numberDiff line numberDiff line change
@@ -4110,6 +4110,7 @@ void vma_pgtable_walk_begin(struct vm_area_struct *vma);
41104110
void vma_pgtable_walk_end(struct vm_area_struct *vma);
41114111

41124112
int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *size);
4113+
int reserve_mem_release_by_name(const char *name);
41134114

41144115
#ifdef CONFIG_64BIT
41154116
int do_mseal(unsigned long start, size_t len_in, unsigned long flags);

Diff for: include/linux/module.h

+6
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ static inline bool is_livepatch_module(struct module *mod)
771771

772772
void set_module_sig_enforced(void);
773773

774+
void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data);
775+
774776
#else /* !CONFIG_MODULES... */
775777

776778
static inline struct module *__module_address(unsigned long addr)
@@ -878,6 +880,10 @@ static inline bool module_is_coming(struct module *mod)
878880
{
879881
return false;
880882
}
883+
884+
static inline void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
885+
{
886+
}
881887
#endif /* CONFIG_MODULES */
882888

883889
#ifdef CONFIG_SYSFS

Diff for: include/linux/ring_buffer.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
9292
struct trace_buffer *__ring_buffer_alloc_range(unsigned long size, unsigned flags,
9393
int order, unsigned long start,
9494
unsigned long range_size,
95+
unsigned long scratch_size,
9596
struct lock_class_key *key);
9697

97-
bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, long *text,
98-
long *data);
98+
void *ring_buffer_meta_scratch(struct trace_buffer *buffer, unsigned int *size);
9999

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

123123
typedef bool (*ring_buffer_cond_fn)(void *data);

Diff for: kernel/module/main.c

+13
Original file line numberDiff line numberDiff line change
@@ -3744,6 +3744,19 @@ bool is_module_text_address(unsigned long addr)
37443744
return __module_text_address(addr) != NULL;
37453745
}
37463746

3747+
void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
3748+
{
3749+
struct module *mod;
3750+
3751+
guard(rcu)();
3752+
list_for_each_entry_rcu(mod, &modules, list) {
3753+
if (mod->state == MODULE_STATE_UNFORMED)
3754+
continue;
3755+
if (func(mod, data))
3756+
break;
3757+
}
3758+
}
3759+
37473760
/**
37483761
* __module_text_address() - get the module whose code contains an address.
37493762
* @addr: the address.

0 commit comments

Comments
 (0)