Skip to content

Commit

Permalink
Merge tag 'probes-fixes-v6.14-rc6' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/trace/linux-trace

Pull probes fixes from Masami Hiramatsu:

 - Clean up tprobe correctly when module unload

   Tracepoint probes do not set TRACEPOINT_STUB on the 'tpoint' pointer
   when unloading a module, thus they show as a normal 'fprobe' instead
   of 'tprobe' and never come back

 - Fix leakage of tprobe module refcount

   When a tprobe's target module is loaded, it gets the module's
   refcount in the module notifier but forgot to put it after
   registering the probe on it.

   Fix it by getting the refcount only when registering tprobe.

* tag 'probes-fixes-v6.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing: tprobe-events: Fix leakage of module refcount
  tracing: tprobe-events: Fix to clean up tprobe correctly when module unload
  • Loading branch information
Linus Torvalds committed Mar 17, 2025
2 parents 4701f33 + ac91052 commit 47c7efa
Showing 1 changed file with 14 additions and 16 deletions.
30 changes: 14 additions & 16 deletions kernel/trace/trace_fprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,13 +920,8 @@ static void __find_tracepoint_module_cb(struct tracepoint *tp, struct module *mo

if (!data->tpoint && !strcmp(data->tp_name, tp->name)) {
data->tpoint = tp;
if (!data->mod) {
if (!data->mod)
data->mod = mod;
if (!try_module_get(data->mod)) {
data->tpoint = NULL;
data->mod = NULL;
}
}
}
}

Expand All @@ -938,13 +933,7 @@ static void __find_tracepoint_cb(struct tracepoint *tp, void *priv)
data->tpoint = tp;
}

/*
* Find a tracepoint from kernel and module. If the tracepoint is in a module,
* this increments the module refcount to prevent unloading until the
* trace_fprobe is registered to the list. After registering the trace_fprobe
* on the trace_fprobe list, the module refcount is decremented because
* tracepoint_probe_module_cb will handle it.
*/
/* Find a tracepoint from kernel and module. */
static struct tracepoint *find_tracepoint(const char *tp_name,
struct module **tp_mod)
{
Expand Down Expand Up @@ -973,6 +962,7 @@ static void reenable_trace_fprobe(struct trace_fprobe *tf)
}
}

/* Find a tracepoint from specified module. */
static struct tracepoint *find_tracepoint_in_module(struct module *mod,
const char *tp_name)
{
Expand Down Expand Up @@ -1008,10 +998,13 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self,
reenable_trace_fprobe(tf);
}
} else if (val == MODULE_STATE_GOING && tp_mod->mod == tf->mod) {
tracepoint_probe_unregister(tf->tpoint,
unregister_fprobe(&tf->fp);
if (trace_fprobe_is_tracepoint(tf)) {
tracepoint_probe_unregister(tf->tpoint,
tf->tpoint->probestub, NULL);
tf->tpoint = NULL;
tf->mod = NULL;
tf->tpoint = TRACEPOINT_STUB;
tf->mod = NULL;
}
}
}
mutex_unlock(&event_mutex);
Expand Down Expand Up @@ -1176,6 +1169,11 @@ static int trace_fprobe_create_internal(int argc, const char *argv[],
if (is_tracepoint) {
ctx->flags |= TPARG_FL_TPOINT;
tpoint = find_tracepoint(symbol, &tp_mod);
/* lock module until register this tprobe. */
if (tp_mod && !try_module_get(tp_mod)) {
tpoint = NULL;
tp_mod = NULL;
}
if (tpoint) {
ctx->funcname = kallsyms_lookup(
(unsigned long)tpoint->probestub,
Expand Down

0 comments on commit 47c7efa

Please sign in to comment.