diff options
| author | Masami Hiramatsu (Google) <mhiramat@kernel.org> | 2026-08-08 06:44:11 +0900 |
|---|---|---|
| committer | Masami Hiramatsu (Google) <mhiramat@kernel.org> | 2026-08-08 21:20:55 +0900 |
| commit | d093d4524bb12eda49c3654cb04ad4663c2471f8 (patch) | |
| tree | fd6c568a5c1786563568907cd06b5ee62df881f1 /kernel | |
| parent | c13fcd3951dcc19524ce0b3e852844b16cd32b22 (diff) | |
tracing/boot: Add support for eprobe, fprobe, and tprobe events
Boot-time tracing currently supports kprobe-events and synthetic-events
under per-event configuration options.
Extend boot-time tracing to support newly added dynamic probe types:
- event probes (eprobe) under the "eprobes" event group
- function probes (fprobe) under the "fprobes" event group
- tracepoint probes (tprobe) under the "tracepoints" or "tprobes"
event group
To support this cleanly, update dyn_event_create() in trace_dynevent.c
so that passing NULL as the type parameter delegates to
create_dyn_event(), allowing generic creation of any registered
dynamic event type from a raw command string.
Update Documentation/trace/boottime-trace.rst accordingly to describe
the new per-event bootconfig options.
Link: https://lore.kernel.org/all/178613905149.259829.18185480460810689421.stgit@devnote2/
Assisted-by: Antigravity:gemini-3.6-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Changes in v3:
- Check return values of strscpy() and snprintf() in trace_boot_add_probe_event()
to prevent silent buffer truncation when constructing probe event strings.
Changes in v2:
- Fix raw command detection logic for eprobes, fprobes, and tprobes
by requiring ':' or isspace() after type prefix.
- Consolidate duplicate loop logic into trace_boot_add_probe_event()
helper function.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/trace/trace_boot.c | 97 | ||||
| -rw-r--r-- | kernel/trace/trace_dynevent.c | 5 |
2 files changed, 102 insertions, 0 deletions
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c index 2ca2541c8a58..5da0a8bbb110 100644 --- a/kernel/trace/trace_boot.c +++ b/kernel/trace/trace_boot.c @@ -18,6 +18,7 @@ #include <linux/trace_events.h> #include "trace.h" +#include "trace_dynevent.h" #define MAX_BUF_LEN 256 @@ -172,6 +173,93 @@ trace_boot_add_synth_event(struct xbc_node *node, const char *event) } #endif +#if defined(CONFIG_EPROBE_EVENTS) || defined(CONFIG_FPROBE_EVENTS) +static int __init +trace_boot_add_probe_event(struct xbc_node *node, const char *group, + const char *event, char type, const char *type_name) +{ + struct xbc_node *anode; + char buf[MAX_BUF_LEN]; + const char *val; + int ret = 0; + + xbc_node_for_each_array_value(node, "probes", anode, val) { + if (val[0] == type && (val[1] == ':' || isspace(val[1]))) { + ret = strscpy(buf, val, MAX_BUF_LEN); + if (ret < 0) { + pr_err("%s command is too long: %s\n", type_name, val); + break; + } + } else { + ret = snprintf(buf, MAX_BUF_LEN, "%c:%s/%s %s", type, group, event, val); + if (ret >= MAX_BUF_LEN || ret < 0) { + pr_err("%s command is too long: %c:%s/%s %s\n", + type_name, type, group, event, val); + ret = -E2BIG; + break; + } + } + + ret = dyn_event_create(buf, NULL); + if (ret) { + pr_err("Failed to add %s: %s\n", type_name, buf); + break; + } + } + + return ret; +} +#endif + +#ifdef CONFIG_EPROBE_EVENTS +static inline int __init +trace_boot_add_eprobe_event(struct xbc_node *node, const char *group, + const char *event) +{ + return trace_boot_add_probe_event(node, group, event, 'e', "eprobe"); +} +#else +static inline int __init +trace_boot_add_eprobe_event(struct xbc_node *node, const char *group, + const char *event) +{ + pr_err("Event probe is not supported.\n"); + return -EOPNOTSUPP; +} +#endif + +#ifdef CONFIG_FPROBE_EVENTS +static inline int __init +trace_boot_add_fprobe_event(struct xbc_node *node, const char *group, + const char *event) +{ + return trace_boot_add_probe_event(node, group, event, 'f', "fprobe"); +} + +static inline int __init +trace_boot_add_tprobe_event(struct xbc_node *node, const char *group, + const char *event) +{ + return trace_boot_add_probe_event(node, group, event, 't', "tprobe"); +} +#else +static inline int __init +trace_boot_add_fprobe_event(struct xbc_node *node, const char *group, + const char *event) +{ + pr_err("Fprobe event is not supported.\n"); + return -EOPNOTSUPP; +} + +static inline int __init +trace_boot_add_tprobe_event(struct xbc_node *node, const char *group, + const char *event) +{ + pr_err("Tracepoint probe is not supported.\n"); + return -EOPNOTSUPP; +} +#endif + #ifdef CONFIG_HIST_TRIGGERS static int __init __printf(3, 4) append_printf(char **bufp, char *end, const char *fmt, ...) @@ -477,6 +565,15 @@ trace_boot_init_one_event(struct trace_array *tr, struct xbc_node *gnode, if (!strcmp(group, "synthetic")) if (trace_boot_add_synth_event(enode, event) < 0) return; + if (!strcmp(group, "eprobes")) + if (trace_boot_add_eprobe_event(enode, group, event) < 0) + return; + if (!strcmp(group, "fprobes")) + if (trace_boot_add_fprobe_event(enode, group, event) < 0) + return; + if (!strcmp(group, "tracepoints") || !strcmp(group, "tprobes")) + if (trace_boot_add_tprobe_event(enode, group, event) < 0) + return; mutex_lock(&event_mutex); file = find_event_file(tr, group, event); diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c index c4dfbc293bae..6f2e39b797e5 100644 --- a/kernel/trace/trace_dynevent.c +++ b/kernel/trace/trace_dynevent.c @@ -116,6 +116,8 @@ int dyn_event_release(const char *raw_command, struct dyn_event_operations *type return ret; } +static int create_dyn_event(const char *raw_command); + /* * Locked version of event creation. The event creation must be protected by * dyn_event_ops_mutex because of protecting trace_probe_log. @@ -124,6 +126,9 @@ int dyn_event_create(const char *raw_command, struct dyn_event_operations *type) { int ret; + if (!type) + return create_dyn_event(raw_command); + mutex_lock(&dyn_event_ops_mutex); ret = type->create(raw_command); mutex_unlock(&dyn_event_ops_mutex); |
