Skip to content

Commit 67e9a9e

Browse files
committed
tracing/fprobe: Support raw tracepoint events on modules
Support raw tracepoint event on module by fprobe events. Since it only uses for_each_kernel_tracepoint() to find a tracepoint, the tracepoints on modules are not handled. Thus if user specified a tracepoint on a module, it shows an error. This adds new for_each_module_tracepoint() API to tracepoint subsystem, and uses it to find tracepoints on modules. Link: https://lore.kernel.org/all/172397779651.286558.15903703620679186867.stgit@devnote2/ Reported-by: don <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/ Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
1 parent d4df54f commit 67e9a9e

File tree

1 file changed

+38
-8
lines changed

1 file changed

+38
-8
lines changed

kernel/trace/trace_fprobe.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
385385
const char *event,
386386
const char *symbol,
387387
struct tracepoint *tpoint,
388+
struct module *mod,
388389
int maxactive,
389390
int nargs, bool is_return)
390391
{
@@ -405,6 +406,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
405406
tf->fp.entry_handler = fentry_dispatcher;
406407

407408
tf->tpoint = tpoint;
409+
tf->mod = mod;
408410
tf->fp.nr_maxactive = maxactive;
409411

410412
ret = trace_probe_init(&tf->tp, event, group, false, nargs);
@@ -895,8 +897,23 @@ static struct notifier_block tracepoint_module_nb = {
895897
struct __find_tracepoint_cb_data {
896898
const char *tp_name;
897899
struct tracepoint *tpoint;
900+
struct module *mod;
898901
};
899902

903+
static void __find_tracepoint_module_cb(struct tracepoint *tp, struct module *mod, void *priv)
904+
{
905+
struct __find_tracepoint_cb_data *data = priv;
906+
907+
if (!data->tpoint && !strcmp(data->tp_name, tp->name)) {
908+
data->tpoint = tp;
909+
data->mod = mod;
910+
if (!try_module_get(data->mod)) {
911+
data->tpoint = NULL;
912+
data->mod = NULL;
913+
}
914+
}
915+
}
916+
900917
static void __find_tracepoint_cb(struct tracepoint *tp, void *priv)
901918
{
902919
struct __find_tracepoint_cb_data *data = priv;
@@ -905,14 +922,28 @@ static void __find_tracepoint_cb(struct tracepoint *tp, void *priv)
905922
data->tpoint = tp;
906923
}
907924

908-
static struct tracepoint *find_tracepoint(const char *tp_name)
925+
/*
926+
* Find a tracepoint from kernel and module. If the tracepoint is in a module,
927+
* this increments the module refcount to prevent unloading until the
928+
* trace_fprobe is registered to the list. After registering the trace_fprobe
929+
* on the trace_fprobe list, the module refcount is decremented because
930+
* tracepoint_probe_module_cb will handle it.
931+
*/
932+
static struct tracepoint *find_tracepoint(const char *tp_name,
933+
struct module **tp_mod)
909934
{
910935
struct __find_tracepoint_cb_data data = {
911936
.tp_name = tp_name,
937+
.mod = NULL,
912938
};
913939

914940
for_each_kernel_tracepoint(__find_tracepoint_cb, &data);
915941

942+
if (!data.tpoint && IS_ENABLED(CONFIG_MODULES)) {
943+
for_each_module_tracepoint(__find_tracepoint_module_cb, &data);
944+
*tp_mod = data.mod;
945+
}
946+
916947
return data.tpoint;
917948
}
918949

@@ -996,6 +1027,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
9961027
char abuf[MAX_BTF_ARGS_LEN];
9971028
char *dbuf = NULL;
9981029
bool is_tracepoint = false;
1030+
struct module *tp_mod = NULL;
9991031
struct tracepoint *tpoint = NULL;
10001032
struct traceprobe_parse_context ctx = {
10011033
.flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE,
@@ -1080,7 +1112,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
10801112

10811113
if (is_tracepoint) {
10821114
ctx.flags |= TPARG_FL_TPOINT;
1083-
tpoint = find_tracepoint(symbol);
1115+
tpoint = find_tracepoint(symbol, &tp_mod);
10841116
if (!tpoint) {
10851117
trace_probe_log_set_index(1);
10861118
trace_probe_log_err(0, NO_TRACEPOINT);
@@ -1110,19 +1142,15 @@ static int __trace_fprobe_create(int argc, const char *argv[])
11101142
goto out;
11111143

11121144
/* setup a probe */
1113-
tf = alloc_trace_fprobe(group, event, symbol, tpoint, maxactive,
1114-
argc, is_return);
1145+
tf = alloc_trace_fprobe(group, event, symbol, tpoint, tp_mod,
1146+
maxactive, argc, is_return);
11151147
if (IS_ERR(tf)) {
11161148
ret = PTR_ERR(tf);
11171149
/* This must return -ENOMEM, else there is a bug */
11181150
WARN_ON_ONCE(ret != -ENOMEM);
11191151
goto out; /* We know tf is not allocated */
11201152
}
11211153

1122-
if (is_tracepoint)
1123-
tf->mod = __module_text_address(
1124-
(unsigned long)tf->tpoint->probestub);
1125-
11261154
/* parse arguments */
11271155
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
11281156
trace_probe_log_set_index(i + 2);
@@ -1155,6 +1183,8 @@ static int __trace_fprobe_create(int argc, const char *argv[])
11551183
}
11561184

11571185
out:
1186+
if (tp_mod)
1187+
module_put(tp_mod);
11581188
traceprobe_finish_parse(&ctx);
11591189
trace_probe_log_clear();
11601190
kfree(new_argv);

0 commit comments

Comments
 (0)