Skip to content

Commit b355247

Browse files
committed
tracing: Cache ":mod:" events for modules not loaded yet
When the :mod: command is written into /sys/kernel/tracing/set_event (or that file within an instance), if the module specified after the ":mod:" is not yet loaded, it will store that string internally. When the module is loaded, it will enable the events as if the module was loaded when the string was written into the set_event file. This can also be useful to enable events that are in the init section of the module, as the events are enabled before the init section is executed. This also works on the kernel command line: trace_event=:mod:<module> Will enable the events for <module> when it is loaded. 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> Link: https://lore.kernel.org/20250116143533.514730995@goodmis.org Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 4c86bc5 commit b355247

File tree

6 files changed

+279
-29
lines changed

6 files changed

+279
-29
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6858,6 +6858,14 @@
68586858
comma-separated list of trace events to enable. See
68596859
also Documentation/trace/events.rst
68606860

6861+
To enable modules, use :mod: keyword:
6862+
6863+
trace_event=:mod:<module>
6864+
6865+
The value before :mod: will only enable specific events
6866+
that are part of the module. See the above mentioned
6867+
document for more information.
6868+
68616869
trace_instance=[instance-info]
68626870
[FTRACE] Create a ring buffer instance early in boot up.
68636871
This will be listed in:

Documentation/trace/events.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ a specific module::
6060

6161
# echo ':mod:<module>' > /sys/kernel/tracing/set_event
6262

63-
Will enable all events in the module ``<module>``.
63+
Will enable all events in the module ``<module>``. If the module is not yet
64+
loaded, the string will be saved and when a module is that matches ``<module>``
65+
is loaded, then it will apply the enabling of events then.
6466

6567
The text before ``:mod:`` will be parsed to specify specific events that the
6668
module creates::

kernel/trace/ftrace.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4930,23 +4930,6 @@ static int ftrace_hash_move_and_update_ops(struct ftrace_ops *ops,
49304930
return __ftrace_hash_move_and_update_ops(ops, orig_hash, hash, enable);
49314931
}
49324932

4933-
static bool module_exists(const char *module)
4934-
{
4935-
/* All modules have the symbol __this_module */
4936-
static const char this_mod[] = "__this_module";
4937-
char modname[MAX_PARAM_PREFIX_LEN + sizeof(this_mod) + 2];
4938-
unsigned long val;
4939-
int n;
4940-
4941-
n = snprintf(modname, sizeof(modname), "%s:%s", module, this_mod);
4942-
4943-
if (n > sizeof(modname) - 1)
4944-
return false;
4945-
4946-
val = module_kallsyms_lookup_name(modname);
4947-
return val != 0;
4948-
}
4949-
49504933
static int cache_mod(struct trace_array *tr,
49514934
const char *func, char *module, int enable)
49524935
{

kernel/trace/trace.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9407,6 +9407,10 @@ trace_array_create_systems(const char *name, const char *systems,
94079407
INIT_LIST_HEAD(&tr->hist_vars);
94089408
INIT_LIST_HEAD(&tr->err_log);
94099409

9410+
#ifdef CONFIG_MODULES
9411+
INIT_LIST_HEAD(&tr->mod_events);
9412+
#endif
9413+
94109414
if (allocate_trace_buffers(tr, trace_buf_size) < 0)
94119415
goto out_free_tr;
94129416

@@ -9823,6 +9827,24 @@ late_initcall_sync(trace_eval_sync);
98239827

98249828

98259829
#ifdef CONFIG_MODULES
9830+
9831+
bool module_exists(const char *module)
9832+
{
9833+
/* All modules have the symbol __this_module */
9834+
static const char this_mod[] = "__this_module";
9835+
char modname[MAX_PARAM_PREFIX_LEN + sizeof(this_mod) + 2];
9836+
unsigned long val;
9837+
int n;
9838+
9839+
n = snprintf(modname, sizeof(modname), "%s:%s", module, this_mod);
9840+
9841+
if (n > sizeof(modname) - 1)
9842+
return false;
9843+
9844+
val = module_kallsyms_lookup_name(modname);
9845+
return val != 0;
9846+
}
9847+
98269848
static void trace_module_add_evals(struct module *mod)
98279849
{
98289850
if (!mod->num_trace_evals)
@@ -10535,6 +10557,10 @@ __init static int tracer_alloc_buffers(void)
1053510557
#endif
1053610558
ftrace_init_global_array_ops(&global_trace);
1053710559

10560+
#ifdef CONFIG_MODULES
10561+
INIT_LIST_HEAD(&global_trace.mod_events);
10562+
#endif
10563+
1053810564
init_trace_flags_index(&global_trace);
1053910565

1054010566
register_tracer(&nop_trace);

kernel/trace/trace.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@ struct trace_array {
400400
cpumask_var_t pipe_cpumask;
401401
int ref;
402402
int trace_ref;
403+
#ifdef CONFIG_MODULES
404+
struct list_head mod_events;
405+
#endif
403406
#ifdef CONFIG_FUNCTION_TRACER
404407
struct ftrace_ops *ops;
405408
struct trace_pid_list __rcu *function_pids;
@@ -434,6 +437,15 @@ enum {
434437
TRACE_ARRAY_FL_BOOT = BIT(1),
435438
};
436439

440+
#ifdef CONFIG_MODULES
441+
bool module_exists(const char *module);
442+
#else
443+
static inline bool module_exists(const char *module)
444+
{
445+
return false;
446+
}
447+
#endif
448+
437449
extern struct list_head ftrace_trace_arrays;
438450

439451
extern struct mutex trace_types_lock;

0 commit comments

Comments
 (0)