From patchwork Sun Mar 16 12:21:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 14018425 X-Patchwork-Delegate: rostedt@goodmis.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0390318B47C; Sun, 16 Mar 2025 12:21:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742127688; cv=none; b=s7mSPpv0xGtxRIx/wvo7YRXu1TeES3kA76v8Qb3eQJBOjhwj7j9T2KOGBC/50knfh7dKwIp2RY5Z+FMa415XHJCrssrAojajwWqd35zJ9wvSqt+LQO/wnbxZEsG1uNG6GgdSHRFTOywZmqM6Hv8AYcj1ZRqluQsOTRZjId5BVGQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742127688; c=relaxed/simple; bh=gjmV4gbAkAhF5mQ6J/09/rRmSzsdFAZegE7iBok4gYk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MYTr3Qr6RRP6qy+14Swvr42TODnu6WwCEs6oPoWl6r7eTGQrSGeCXZBBXA+6io2ae9YG7IiWhUiP6jZM+LOPJD2WfWlJ/Z/HEiR7bST4AfI9LkHV6wIUjJ4O7ibRuhYqes94wSltzHleb6Q1vm1naBReXWu0aosrqy+ivIeGCXY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OoC+FfGX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OoC+FfGX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0D4E4C4CEDD; Sun, 16 Mar 2025 12:21:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1742127687; bh=gjmV4gbAkAhF5mQ6J/09/rRmSzsdFAZegE7iBok4gYk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OoC+FfGXp+HTSN2a6ctff0Zp27I1tB0ukHqVXNPo6CZD0UjEE5GU9iiCAirrN9mXR 0X88AzygOEx60oRAemOzkc7dXVUh5BXj+REySR8UFPVXqbn7K2ylXKN/O2vnwAPVSr Mx0tWnUnJAkz5yHX24m1HNDaeYUWEUIw08cTz7p4yJCy7SFaf3JFgC/X/M2uiCaTCN ElGe3HEORFCpmYPWDMJuuduKS47Nv2WG62LEChg49VlQert878r3+eO5Knqg1VnCK9 wglqVU2+LIspduzOa6vwvKU7zvTHmLBcZbWvcYZ7uwJmtVph96DxLcigQ+1da2UYYL /J6cj+uutWcBQ== From: "Masami Hiramatsu (Google)" To: Steven Rostedt Cc: Masami Hiramatsu , Mathieu Desnoyers , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Subject: [PATCH 1/4] tracing: tprobe-events: Remove mod field from tprobe-event Date: Sun, 16 Mar 2025 21:21:21 +0900 Message-ID: <174212768121.348872.11676145343580139357.stgit@devnote2> X-Mailer: git-send-email 2.43.0 In-Reply-To: <174212767109.348872.18231451508464729427.stgit@devnote2> References: <174212767109.348872.18231451508464729427.stgit@devnote2> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Masami Hiramatsu (Google) Remove unneeded 'mod' struct module pointer field from trace_fprobe because we don't need to save this info. Signed-off-by: Masami Hiramatsu (Google) --- kernel/trace/trace_fprobe.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 5d7ca80173ea..08def94f9ca6 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -46,7 +46,6 @@ struct trace_fprobe { struct fprobe fp; const char *symbol; struct tracepoint *tpoint; - struct module *mod; struct trace_probe tp; }; @@ -426,7 +425,6 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group, const char *event, const char *symbol, struct tracepoint *tpoint, - struct module *mod, int nargs, bool is_return) { struct trace_fprobe *tf __free(free_trace_fprobe) = NULL; @@ -446,7 +444,6 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group, tf->fp.entry_handler = fentry_dispatcher; tf->tpoint = tpoint; - tf->mod = mod; ret = trace_probe_init(&tf->tp, event, group, false, nargs); if (ret < 0) @@ -776,7 +773,6 @@ static void __unregister_trace_fprobe(struct trace_fprobe *tf) tracepoint_probe_unregister(tf->tpoint, tf->tpoint->probestub, NULL); tf->tpoint = NULL; - tf->mod = NULL; } } } @@ -992,7 +988,6 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self, tpoint = find_tracepoint_in_module(tp_mod->mod, tf->symbol); if (tpoint) { tf->tpoint = tpoint; - tf->mod = tp_mod->mod; if (!WARN_ON_ONCE(__regsiter_tracepoint_fprobe(tf)) && trace_probe_is_enabled(&tf->tp)) reenable_trace_fprobe(tf); @@ -1003,7 +998,6 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self, tracepoint_probe_unregister(tf->tpoint, tf->tpoint->probestub, NULL); tf->tpoint = TRACEPOINT_STUB; - tf->mod = NULL; } } } @@ -1210,8 +1204,7 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], return ret; /* setup a probe */ - tf = alloc_trace_fprobe(group, event, symbol, tpoint, tp_mod, - argc, is_return); + tf = alloc_trace_fprobe(group, event, symbol, tpoint, argc, is_return); if (IS_ERR(tf)) { ret = PTR_ERR(tf); /* This must return -ENOMEM, else there is a bug */ From patchwork Sun Mar 16 12:21:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 14018426 X-Patchwork-Delegate: rostedt@goodmis.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8872518B47C; Sun, 16 Mar 2025 12:21:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742127697; cv=none; b=HEMIuDESFUyMQdThPfrpjhZ5shbiV+9Cb/s+qEtj6gq0M/pgyl+QJ1xb9xfXXwgx57cWVBHw3VdBIqDoT0PZJ3W5xtE1Zdf0YcRMno/ceOZ4XyVC4kKwvB+q/lkNStSFOX25W0L0l5Do/Bj3HCxQUHUNg8ta1ljVce705TCgilk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742127697; c=relaxed/simple; bh=lp4YDB/hAqNvIoicxsUzWvZXZHDX4oGJ7AOP3B9m0Nw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=juwRL8iOjpad7929F7SreYUm6/jm+NsXbAiXiLh0jnOD7O/iFBVB5t8bUMV9I3WyM3mVLAkQiGh5TgPjoNnk/B5gzFH0usYu7Zpxa9ZDwdGUUpQdZ2F9EowI10ImjQNHdXbUuytawJhfINmGdpvD7mYoq+WfSnnU/c3d0c/ZYfo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f0j/3HMD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="f0j/3HMD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E160BC4CEDD; Sun, 16 Mar 2025 12:21:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1742127697; bh=lp4YDB/hAqNvIoicxsUzWvZXZHDX4oGJ7AOP3B9m0Nw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f0j/3HMDdipVXotHjAVEtEspUV6zGkr5JasnS5aOCNiS8UicSBIsyxUhStx/ra9/E hFPuxRfCzIhE9jCdHMcBk9AvFJDFvaLUTJddTH2AsXjFViXaKc2Tf2k4txXdOMlhhO D8kA6R6iZp2U8vIuzkUdeB6mKqrjmyqdHQU1yloHwHYkjHrs2wPN3NOyVx0Nlr7BhY AHqRkzA9x+xZLyIbtqyK/j/O2ryvC2WyCxuwwKSO6WH4reghWkUyNoOhTy8lvfji82 ml6XzFmj3DAIh1/qX3PjDTYV8pcEgSsZ/JDKOdLdhGdYkXc8dAc+iQYjryT1Hjul/q mXNFGaJLDjsKQ== From: "Masami Hiramatsu (Google)" To: Steven Rostedt Cc: Masami Hiramatsu , Mathieu Desnoyers , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Subject: [PATCH 2/4] tracing: tprobe-events: Support multiple tprobes on the same tracepoint Date: Sun, 16 Mar 2025 21:21:33 +0900 Message-ID: <174212769289.348872.12945848497242748827.stgit@devnote2> X-Mailer: git-send-email 2.43.0 In-Reply-To: <174212767109.348872.18231451508464729427.stgit@devnote2> References: <174212767109.348872.18231451508464729427.stgit@devnote2> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Masami Hiramatsu (Google) Allow user to set multiple tracepoint-probe events on the same tracepoint. After the last tprobe-event is removed, the tracepoint callback is unregistered. Signed-off-by: Masami Hiramatsu (Google) --- include/linux/module.h | 4 + kernel/trace/trace_fprobe.c | 259 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 208 insertions(+), 55 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 30e5b19bafa9..01d5208cf473 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1027,4 +1028,7 @@ static inline unsigned long find_kallsyms_symbol_value(struct module *mod, #endif /* CONFIG_MODULES && CONFIG_KALLSYMS */ +/* Define __free(module_put) macro for struct module *. */ +DEFINE_FREE(module_put, struct module *, if (_T) module_put(_T)) + #endif /* _LINUX_MODULE_H */ diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 08def94f9ca6..863c9343a939 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -21,7 +21,6 @@ #define FPROBE_EVENT_SYSTEM "fprobes" #define TRACEPOINT_EVENT_SYSTEM "tracepoints" #define RETHOOK_MAXACTIVE_MAX 4096 -#define TRACEPOINT_STUB ERR_PTR(-ENOENT) static int trace_fprobe_create(const char *raw_command); static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev); @@ -38,6 +37,89 @@ static struct dyn_event_operations trace_fprobe_ops = { .match = trace_fprobe_match, }; +struct tracepoint_user { + struct tracepoint *tpoint; + unsigned int refcount; +}; + +static bool tracepoint_user_is_registered(struct tracepoint_user *tuser) +{ + return tuser && tuser->tpoint; +} + +static int tracepoint_user_register(struct tracepoint_user *tuser) +{ + struct tracepoint *tpoint = tuser->tpoint; + + if (!tpoint) + return 0; + + return tracepoint_probe_register_prio_may_exist(tpoint, + tpoint->probestub, NULL, 0); +} + +static void tracepoint_user_unregister(struct tracepoint_user *tuser) +{ + if (!tuser->tpoint) + return; + + WARN_ON_ONCE(tracepoint_probe_unregister(tuser->tpoint, tuser->tpoint->probestub, NULL)); + tuser->tpoint = NULL; +} + +static unsigned long tracepoint_user_ip(struct tracepoint_user *tuser) +{ + if (!tuser->tpoint) + return 0UL; + + return (unsigned long)tuser->tpoint->probestub; +} + +static bool tracepoint_user_within_module(struct tracepoint_user *tuser, + struct module *mod) +{ + return within_module(tracepoint_user_ip(tuser), mod); +} + +static struct tracepoint_user *tracepoint_user_allocate(struct tracepoint *tpoint) +{ + struct tracepoint_user *tuser __free(kfree) = NULL; + + tuser = kzalloc(sizeof(*tuser), GFP_KERNEL); + if (!tuser) + return NULL; + tuser->tpoint = tpoint; + tuser->refcount = 1; + + return_ptr(tuser); +} + +/* These must be called with event_mutex */ +static void tracepoint_user_get(struct tracepoint_user *tuser) +{ + tuser->refcount++; +} + +static void tracepoint_user_put(struct tracepoint_user *tuser) +{ + if (--tuser->refcount > 0) + return; + + if (tracepoint_user_is_registered(tuser)) + tracepoint_user_unregister(tuser); + kfree(tuser); +} + +static const char *tracepoint_user_lookup(struct tracepoint_user *tuser, char *buf) +{ + struct tracepoint *tpoint = tuser->tpoint; + + if (!tpoint) + return NULL; + + return kallsyms_lookup((unsigned long)tpoint->probestub, NULL, NULL, NULL, buf); +} + /* * Fprobe event core functions */ @@ -45,7 +127,7 @@ struct trace_fprobe { struct dyn_event devent; struct fprobe fp; const char *symbol; - struct tracepoint *tpoint; + struct tracepoint_user *tuser; struct trace_probe tp; }; @@ -75,7 +157,7 @@ static bool trace_fprobe_is_return(struct trace_fprobe *tf) static bool trace_fprobe_is_tracepoint(struct trace_fprobe *tf) { - return tf->tpoint != NULL; + return tf->tuser != NULL; } static const char *trace_fprobe_symbol(struct trace_fprobe *tf) @@ -125,6 +207,57 @@ static bool trace_fprobe_is_registered(struct trace_fprobe *tf) return fprobe_is_registered(&tf->fp); } +static struct tracepoint *find_tracepoint(const char *tp_name, + struct module **tp_mod); + +/* + * Get tracepoint_user if exist, or allocate new one. If tracepoint is on a + * module, get its refcounter. + */ +static struct tracepoint_user * +trace_fprobe_get_tracepoint_user(const char *name, struct module **pmod) +{ + struct tracepoint_user *tuser __free(kfree) = NULL; + struct tracepoint *tpoint; + struct trace_fprobe *tf; + struct dyn_event *dpos; + struct module *mod __free(module_put) = NULL; + int ret; + + tpoint = find_tracepoint(name, &mod); + if (mod && !try_module_get(mod)) { + mod = NULL; + tpoint = NULL; + } + /* tpoint can be NULL, but we don't care here. */ + + /* Search existing tracepoint_user */ + for_each_trace_fprobe(tf, dpos) { + if (!trace_fprobe_is_tracepoint(tf)) + continue; + if (!strcmp(tf->symbol, name)) { + tracepoint_user_get(tf->tuser); + *pmod = no_free_ptr(mod); + return tf->tuser; + } + } + + /* Not found, allocate and register new tracepoint_user. */ + tuser = tracepoint_user_allocate(tpoint); + if (!tuser) + return NULL; + + if (tpoint) { + /* If the tracepoint is not loaded, tpoint can be NULL. */ + ret = tracepoint_user_register(tuser); + if (ret) + return ERR_PTR(ret); + } + + *pmod = no_free_ptr(mod); + return_ptr(tuser); +} + /* * Note that we don't verify the fetch_insn code, since it does not come * from user space. @@ -410,6 +543,8 @@ static void free_trace_fprobe(struct trace_fprobe *tf) { if (tf) { trace_probe_cleanup(&tf->tp); + if (tf->tuser) + tracepoint_user_put(tf->tuser); kfree(tf->symbol); kfree(tf); } @@ -424,7 +559,7 @@ DEFINE_FREE(free_trace_fprobe, struct trace_fprobe *, if (!IS_ERR_OR_NULL(_T)) f static struct trace_fprobe *alloc_trace_fprobe(const char *group, const char *event, const char *symbol, - struct tracepoint *tpoint, + struct tracepoint_user *tuser, int nargs, bool is_return) { struct trace_fprobe *tf __free(free_trace_fprobe) = NULL; @@ -443,7 +578,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group, else tf->fp.entry_handler = fentry_dispatcher; - tf->tpoint = tpoint; + tf->tuser = tuser; ret = trace_probe_init(&tf->tp, event, group, false, nargs); if (ret < 0) @@ -709,19 +844,11 @@ static int unregister_fprobe_event(struct trace_fprobe *tf) static int __regsiter_tracepoint_fprobe(struct trace_fprobe *tf) { - struct tracepoint *tpoint = tf->tpoint; - unsigned long ip = (unsigned long)tpoint->probestub; - int ret; + unsigned long ip = tracepoint_user_ip(tf->tuser); + + if (!ip) + return -ENOENT; - /* - * Here, we do 2 steps to enable fprobe on a tracepoint. - * At first, put __probestub_##TP function on the tracepoint - * and put a fprobe on the stub function. - */ - ret = tracepoint_probe_register_prio_may_exist(tpoint, - tpoint->probestub, NULL, 0); - if (ret < 0) - return ret; return register_fprobe_ips(&tf->fp, &ip, 1); } @@ -753,7 +880,7 @@ static int __register_trace_fprobe(struct trace_fprobe *tf) if (trace_fprobe_is_tracepoint(tf)) { /* This tracepoint is not loaded yet */ - if (tf->tpoint == TRACEPOINT_STUB) + if (!tracepoint_user_is_registered(tf->tuser)) return 0; return __regsiter_tracepoint_fprobe(tf); @@ -770,9 +897,8 @@ static void __unregister_trace_fprobe(struct trace_fprobe *tf) unregister_fprobe(&tf->fp); memset(&tf->fp, 0, sizeof(tf->fp)); if (trace_fprobe_is_tracepoint(tf)) { - tracepoint_probe_unregister(tf->tpoint, - tf->tpoint->probestub, NULL); - tf->tpoint = NULL; + tracepoint_user_put(tf->tuser); + tf->tuser = NULL; } } } @@ -975,7 +1101,7 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self, unsigned long val, void *data) { struct tp_module *tp_mod = data; - struct tracepoint *tpoint; + struct tracepoint_user *tuser; struct trace_fprobe *tf; struct dyn_event *pos; @@ -984,21 +1110,48 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self, mutex_lock(&event_mutex); for_each_trace_fprobe(tf, pos) { - if (val == MODULE_STATE_COMING && tf->tpoint == TRACEPOINT_STUB) { + if (!trace_fprobe_is_tracepoint(tf)) + continue; + + if (val == MODULE_STATE_COMING) { + /* + * If any tracepoint used by tprobe is in the module, + * register the stub. + */ + struct tracepoint *tpoint; + tpoint = find_tracepoint_in_module(tp_mod->mod, tf->symbol); - if (tpoint) { - tf->tpoint = tpoint; - if (!WARN_ON_ONCE(__regsiter_tracepoint_fprobe(tf)) && - trace_probe_is_enabled(&tf->tp)) - reenable_trace_fprobe(tf); - } - } else if (val == MODULE_STATE_GOING && tp_mod->mod == tf->mod) { - unregister_fprobe(&tf->fp); - if (trace_fprobe_is_tracepoint(tf)) { - tracepoint_probe_unregister(tf->tpoint, - tf->tpoint->probestub, NULL); - tf->tpoint = TRACEPOINT_STUB; + /* This is not a tracepoint in this module. Skip it. */ + if (!tpoint) + continue; + + tuser = tf->tuser; + /* If the tracepoint is no registered yet, register it. */ + if (!tracepoint_user_is_registered(tuser)) { + tuser->tpoint = tpoint; + if (WARN_ON_ONCE(tracepoint_user_register(tuser))) + continue; } + + /* Finally enable fprobe on this module. */ + if (!WARN_ON_ONCE(__regsiter_tracepoint_fprobe(tf)) && + trace_probe_is_enabled(&tf->tp)) + reenable_trace_fprobe(tf); + } else if (val == MODULE_STATE_GOING) { + tuser = tf->tuser; + /* Unregister all tracepoint_user in this module. */ + if (tracepoint_user_is_registered(tuser) && + tracepoint_user_within_module(tuser, tp_mod->mod)) + tracepoint_user_unregister(tuser); + + /* + * Here we need to handle shared tracepoint_user case. + * Such tuser is unregistered, but trace_fprobe itself + * is registered. (Note this only handles tprobes.) + */ + if (!tracepoint_user_is_registered(tuser) && + trace_fprobe_is_registered(tf)) + unregister_fprobe(&tf->fp); } } mutex_unlock(&event_mutex); @@ -1067,7 +1220,9 @@ static int parse_symbol_and_return(int argc, const char *argv[], return 0; } -DEFINE_FREE(module_put, struct module *, if (_T) module_put(_T)) +DEFINE_FREE(tuser_put, struct tracepoint_user *, + if (!IS_ERR_OR_NULL(_T)) + tracepoint_user_put(_T)) static int trace_fprobe_create_internal(int argc, const char *argv[], struct traceprobe_parse_context *ctx) @@ -1097,6 +1252,8 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], * FETCHARG:TYPE : use TYPE instead of unsigned long. */ struct trace_fprobe *tf __free(free_trace_fprobe) = NULL; + struct tracepoint_user *tuser __free(tuser_put) = NULL; + struct module *mod __free(module_put) = NULL; int i, new_argc = 0, ret = 0; bool is_return = false; char *symbol __free(kfree) = NULL; @@ -1108,8 +1265,6 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], char abuf[MAX_BTF_ARGS_LEN]; char *dbuf __free(kfree) = NULL; bool is_tracepoint = false; - struct module *tp_mod __free(module_put) = NULL; - struct tracepoint *tpoint = NULL; if ((argv[0][0] != 'f' && argv[0][0] != 't') || argc < 2) return -ECANCELED; @@ -1162,25 +1317,18 @@ 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, - NULL, NULL, NULL, sbuf); - } else if (IS_ENABLED(CONFIG_MODULES)) { - /* This *may* be loaded afterwards */ - tpoint = TRACEPOINT_STUB; - ctx->funcname = symbol; - } else { + tuser = trace_fprobe_get_tracepoint_user(symbol, &mod); + if (!tuser) + return -ENOMEM; + if (IS_ERR(tuser)) { trace_probe_log_set_index(1); trace_probe_log_err(0, NO_TRACEPOINT); - return -EINVAL; + return PTR_ERR(tuser); } + ctx->funcname = tracepoint_user_lookup(tuser, sbuf); + /* If tracepoint is not loaded yet, use symbol name as funcname. */ + if (!ctx->funcname) + ctx->funcname = symbol; } else ctx->funcname = symbol; @@ -1204,13 +1352,14 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], return ret; /* setup a probe */ - tf = alloc_trace_fprobe(group, event, symbol, tpoint, argc, is_return); + tf = alloc_trace_fprobe(group, event, symbol, tuser, argc, is_return); if (IS_ERR(tf)) { ret = PTR_ERR(tf); /* This must return -ENOMEM, else there is a bug */ WARN_ON_ONCE(ret != -ENOMEM); return ret; } + tuser = NULL; /* Move tuser to tf. */ /* parse arguments */ for (i = 0; i < argc; i++) { From patchwork Sun Mar 16 12:21:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 14018427 X-Patchwork-Delegate: rostedt@goodmis.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A6DA71A3175; Sun, 16 Mar 2025 12:21:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742127707; cv=none; b=JLLhBkJcdwnG5ObUGFrH3G1sionox4Gtwb3SoFebbmGFVsMTHmtwh5wCyr3l3aGXpXyLwZ0WTyG2W/a9ENLNtnYpR1SE72ODe9/MYG0iqVagLPTrrMAQzEzeO0fokUNOaNdEzZrGSRhHuv1NzAhFFl9ey5RtItqYerQ46OhZ1HI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742127707; c=relaxed/simple; bh=bBYHEjoEDIrgh2tzmkSng7ANeEMzqqTfDt0ky2Xlg1s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nJrigUHC7gwjnTjfjxk9uQq3iEJn5Gma0P3/JitcXPllaFI43c995G1Dej/emGNZCOphW1lF/Pnw76StVw6ScLD179LdY+SWv3gC881jKhJqQ2fXCi8CBKe6O8mcvqAoURS4QYi9qbD33Ma0BbAuMtTLRxKC3TiEr/0FqRSqBT8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZuAKH3Vd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZuAKH3Vd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7BC54C4CEDD; Sun, 16 Mar 2025 12:21:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1742127706; bh=bBYHEjoEDIrgh2tzmkSng7ANeEMzqqTfDt0ky2Xlg1s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZuAKH3VdYgKcNealxOivgsaSFEVYxXUhrqy7LSTGBCrTWi+TX1aH0s8GdFZF584Jv Mdg+Zcn6NDhLFIlqC8LKEwzuEjNBIKAhDAmY2GbPNXTWUu0v/5pzSDrlgD97UHkVD1 DJA3Plz8oe27e9gjmxX9IIMdWfOqhybarCitwzV0opapiJKHzJXd+S+qZdQzw+I8F8 q+1r7DlZ/bYBJJZlnZT8L2m2uvdj2acsnPZ5nmX20u0SaTJS9/zoJ3ndw2/C/mC5SF DbGiBcImReIyqUEIQROqHNn13YfC6WQpEKPdZa3VG8JYIsjCzP1bix10RJ3noOKNpG L3ilgPgCFK4Ew== From: "Masami Hiramatsu (Google)" To: Steven Rostedt Cc: Masami Hiramatsu , Mathieu Desnoyers , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Subject: [PATCH 3/4] tracing: fprobe-events: Register fprobe-events only when it is enabled Date: Sun, 16 Mar 2025 21:21:42 +0900 Message-ID: <174212770238.348872.12106623852892827796.stgit@devnote2> X-Mailer: git-send-email 2.43.0 In-Reply-To: <174212767109.348872.18231451508464729427.stgit@devnote2> References: <174212767109.348872.18231451508464729427.stgit@devnote2> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Masami Hiramatsu (Google) Currently fprobe events are registered when it is defined. Thus it will give some overhead even if it is disabled. This changes it to register the fprobe only when it is enabled. Suggested-by: Steven Rostedt Signed-off-by: Masami Hiramatsu (Google) --- include/linux/fprobe.h | 8 + kernel/trace/fprobe.c | 29 +++-- kernel/trace/trace_fprobe.c | 234 +++++++++++++++++++++---------------------- 3 files changed, 140 insertions(+), 131 deletions(-) diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h index 702099f08929..9635a24d5a25 100644 --- a/include/linux/fprobe.h +++ b/include/linux/fprobe.h @@ -94,6 +94,8 @@ int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num); int register_fprobe_syms(struct fprobe *fp, const char **syms, int num); int unregister_fprobe(struct fprobe *fp); bool fprobe_is_registered(struct fprobe *fp); +int fprobe_alloc_ip_list_from_filter(const char *filter, const char *notfilter, + unsigned long **addrs); #else static inline int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter) { @@ -115,6 +117,12 @@ static inline bool fprobe_is_registered(struct fprobe *fp) { return false; } +static inline int fprobe_alloc_ip_list_from_filter(const char *filter, + const char *notfilter, + unsigned long **addrs) +{ + return -EOPNOTSUPP; +} #endif /** diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c index 33082c4e8154..05050f1c2239 100644 --- a/kernel/trace/fprobe.c +++ b/kernel/trace/fprobe.c @@ -486,6 +486,24 @@ static int ip_list_from_filter(const char *filter, const char *notfilter, return match.index ?: -ENOENT; } +#define FPROBE_IPS_MAX INT_MAX + +int fprobe_alloc_ip_list_from_filter(const char *filter, const char *notfilter, + unsigned long **addrs) +{ + int ret; + + /* Count the number of ips from filter. */ + ret = ip_list_from_filter(filter, notfilter, NULL, FPROBE_IPS_MAX); + if (ret < 0) + return ret; + + *addrs = kcalloc(ret, sizeof(unsigned long), GFP_KERNEL); + if (!*addrs) + return -ENOMEM; + return ip_list_from_filter(filter, notfilter, *addrs, ret); +} + static void fprobe_fail_cleanup(struct fprobe *fp) { kfree(fp->hlist_array); @@ -528,8 +546,6 @@ static int fprobe_init(struct fprobe *fp, unsigned long *addrs, int num) return 0; } -#define FPROBE_IPS_MAX INT_MAX - /** * register_fprobe() - Register fprobe to ftrace by pattern. * @fp: A fprobe data structure to be registered. @@ -549,14 +565,7 @@ int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter if (!fp || !filter) return -EINVAL; - ret = ip_list_from_filter(filter, notfilter, NULL, FPROBE_IPS_MAX); - if (ret < 0) - return ret; - - addrs = kcalloc(ret, sizeof(unsigned long), GFP_KERNEL); - if (!addrs) - return -ENOMEM; - ret = ip_list_from_filter(filter, notfilter, addrs, ret); + ret = fprobe_alloc_ip_list_from_filter(filter, notfilter, &addrs); if (ret > 0) ret = register_fprobe_ips(fp, addrs, ret); diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 863c9343a939..ac3b0a34810a 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -601,98 +601,6 @@ static struct trace_fprobe *find_trace_fprobe(const char *event, return NULL; } -static inline int __enable_trace_fprobe(struct trace_fprobe *tf) -{ - if (trace_fprobe_is_registered(tf)) - enable_fprobe(&tf->fp); - - return 0; -} - -static void __disable_trace_fprobe(struct trace_probe *tp) -{ - struct trace_fprobe *tf; - - list_for_each_entry(tf, trace_probe_probe_list(tp), tp.list) { - if (!trace_fprobe_is_registered(tf)) - continue; - disable_fprobe(&tf->fp); - } -} - -/* - * Enable trace_probe - * if the file is NULL, enable "perf" handler, or enable "trace" handler. - */ -static int enable_trace_fprobe(struct trace_event_call *call, - struct trace_event_file *file) -{ - struct trace_probe *tp; - struct trace_fprobe *tf; - bool enabled; - int ret = 0; - - tp = trace_probe_primary_from_call(call); - if (WARN_ON_ONCE(!tp)) - return -ENODEV; - enabled = trace_probe_is_enabled(tp); - - /* This also changes "enabled" state */ - if (file) { - ret = trace_probe_add_file(tp, file); - if (ret) - return ret; - } else - trace_probe_set_flag(tp, TP_FLAG_PROFILE); - - if (!enabled) { - list_for_each_entry(tf, trace_probe_probe_list(tp), tp.list) { - /* TODO: check the fprobe is gone */ - __enable_trace_fprobe(tf); - } - } - - return 0; -} - -/* - * Disable trace_probe - * if the file is NULL, disable "perf" handler, or disable "trace" handler. - */ -static int disable_trace_fprobe(struct trace_event_call *call, - struct trace_event_file *file) -{ - struct trace_probe *tp; - - tp = trace_probe_primary_from_call(call); - if (WARN_ON_ONCE(!tp)) - return -ENODEV; - - if (file) { - if (!trace_probe_get_file_link(tp, file)) - return -ENOENT; - if (!trace_probe_has_single_file(tp)) - goto out; - trace_probe_clear_flag(tp, TP_FLAG_TRACE); - } else - trace_probe_clear_flag(tp, TP_FLAG_PROFILE); - - if (!trace_probe_is_enabled(tp)) - __disable_trace_fprobe(tp); - - out: - if (file) - /* - * Synchronization is done in below function. For perf event, - * file == NULL and perf_trace_event_unreg() calls - * tracepoint_synchronize_unregister() to ensure synchronize - * event. We don't need to care about it. - */ - trace_probe_remove_file(tp, file); - - return 0; -} - /* Event entry printers */ static enum print_line_t print_fentry_event(struct trace_iterator *iter, int flags, @@ -852,6 +760,26 @@ static int __regsiter_tracepoint_fprobe(struct trace_fprobe *tf) return register_fprobe_ips(&tf->fp, &ip, 1); } +/* Returns an error if the target function is not available, or 0 */ +static int trace_fprobe_verify_target(struct trace_fprobe *tf) +{ + unsigned long *addrs __free(kfree) = NULL; + int ret; + + if (trace_fprobe_is_tracepoint(tf)) { + + /* This tracepoint is not loaded yet */ + if (!tracepoint_user_is_registered(tf->tuser)) + return 0; + + /* We assume all stab function is tracable. */ + return tracepoint_user_ip(tf->tuser) ? 0 : -ENOENT; + } + + ret = fprobe_alloc_ip_list_from_filter(tf->symbol, NULL, &addrs); + return (ret < 0) ? ret : 0; +} + /* Internal register function - just handle fprobe and flags */ static int __register_trace_fprobe(struct trace_fprobe *tf) { @@ -871,11 +799,7 @@ static int __register_trace_fprobe(struct trace_fprobe *tf) return ret; } - /* Set/clear disabled flag according to tp->flag */ - if (trace_probe_is_enabled(&tf->tp)) - tf->fp.flags &= ~FPROBE_FL_DISABLED; - else - tf->fp.flags |= FPROBE_FL_DISABLED; + tf->fp.flags &= ~FPROBE_FL_DISABLED; if (trace_fprobe_is_tracepoint(tf)) { @@ -896,10 +820,10 @@ static void __unregister_trace_fprobe(struct trace_fprobe *tf) if (trace_fprobe_is_registered(tf)) { unregister_fprobe(&tf->fp); memset(&tf->fp, 0, sizeof(tf->fp)); - if (trace_fprobe_is_tracepoint(tf)) { - tracepoint_user_put(tf->tuser); - tf->tuser = NULL; - } + } + if (trace_fprobe_is_tracepoint(tf)) { + tracepoint_user_put(tf->tuser); + tf->tuser = NULL; } } @@ -959,7 +883,7 @@ static bool trace_fprobe_has_same_fprobe(struct trace_fprobe *orig, return false; } -static int append_trace_fprobe(struct trace_fprobe *tf, struct trace_fprobe *to) +static int append_trace_fprobe_event(struct trace_fprobe *tf, struct trace_fprobe *to) { int ret; @@ -987,7 +911,7 @@ static int append_trace_fprobe(struct trace_fprobe *tf, struct trace_fprobe *to) if (ret) return ret; - ret = __register_trace_fprobe(tf); + ret = trace_fprobe_verify_target(tf); if (ret) trace_probe_unlink(&tf->tp); else @@ -996,8 +920,8 @@ static int append_trace_fprobe(struct trace_fprobe *tf, struct trace_fprobe *to) return ret; } -/* Register a trace_probe and probe_event */ -static int register_trace_fprobe(struct trace_fprobe *tf) +/* Register a trace_probe and probe_event, and check the fprobe is available. */ +static int register_trace_fprobe_event(struct trace_fprobe *tf) { struct trace_fprobe *old_tf; int ret; @@ -1007,7 +931,7 @@ static int register_trace_fprobe(struct trace_fprobe *tf) old_tf = find_trace_fprobe(trace_probe_name(&tf->tp), trace_probe_group_name(&tf->tp)); if (old_tf) - return append_trace_fprobe(tf, old_tf); + return append_trace_fprobe_event(tf, old_tf); /* Register new event */ ret = register_fprobe_event(tf); @@ -1020,8 +944,8 @@ static int register_trace_fprobe(struct trace_fprobe *tf) return ret; } - /* Register fprobe */ - ret = __register_trace_fprobe(tf); + /* Verify fprobe is sane. */ + ret = trace_fprobe_verify_target(tf); if (ret < 0) unregister_fprobe_event(tf); else @@ -1075,15 +999,6 @@ static struct tracepoint *find_tracepoint(const char *tp_name, } #ifdef CONFIG_MODULES -static void reenable_trace_fprobe(struct trace_fprobe *tf) -{ - struct trace_probe *tp = &tf->tp; - - list_for_each_entry(tf, trace_probe_probe_list(tp), tp.list) { - __enable_trace_fprobe(tf); - } -} - /* Find a tracepoint from specified module. */ static struct tracepoint *find_tracepoint_in_module(struct module *mod, const char *tp_name) @@ -1134,9 +1049,8 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self, } /* Finally enable fprobe on this module. */ - if (!WARN_ON_ONCE(__regsiter_tracepoint_fprobe(tf)) && - trace_probe_is_enabled(&tf->tp)) - reenable_trace_fprobe(tf); + if (trace_probe_is_enabled(&tf->tp) && !trace_fprobe_is_registered(tf)) + WARN_ON_ONCE(__regsiter_tracepoint_fprobe(tf)); } else if (val == MODULE_STATE_GOING) { tuser = tf->tuser; /* Unregister all tracepoint_user in this module. */ @@ -1385,7 +1299,7 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], if (ret < 0) return ret; - ret = register_trace_fprobe(tf); + ret = register_trace_fprobe_event(tf); if (ret) { trace_probe_log_set_index(1); if (ret == -EILSEQ) @@ -1454,6 +1368,84 @@ static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev) return 0; } +/* + * Enable trace_probe + * if the file is NULL, enable "perf" handler, or enable "trace" handler. + */ +static int enable_trace_fprobe(struct trace_event_call *call, + struct trace_event_file *file) +{ + struct trace_probe *tp; + struct trace_fprobe *tf; + bool enabled; + int ret = 0; + + tp = trace_probe_primary_from_call(call); + if (WARN_ON_ONCE(!tp)) + return -ENODEV; + enabled = trace_probe_is_enabled(tp); + + /* This also changes "enabled" state */ + if (file) { + ret = trace_probe_add_file(tp, file); + if (ret) + return ret; + } else + trace_probe_set_flag(tp, TP_FLAG_PROFILE); + + if (!enabled) { + list_for_each_entry(tf, trace_probe_probe_list(tp), tp.list) { + ret = __register_trace_fprobe(tf); + if (ret < 0) + return ret; + } + } + + return 0; +} + +/* + * Disable trace_probe + * if the file is NULL, disable "perf" handler, or disable "trace" handler. + */ +static int disable_trace_fprobe(struct trace_event_call *call, + struct trace_event_file *file) +{ + struct trace_fprobe *tf; + struct trace_probe *tp; + + tp = trace_probe_primary_from_call(call); + if (WARN_ON_ONCE(!tp)) + return -ENODEV; + + if (file) { + if (!trace_probe_get_file_link(tp, file)) + return -ENOENT; + if (!trace_probe_has_single_file(tp)) + goto out; + trace_probe_clear_flag(tp, TP_FLAG_TRACE); + } else + trace_probe_clear_flag(tp, TP_FLAG_PROFILE); + + if (!trace_probe_is_enabled(tp)) { + list_for_each_entry(tf, trace_probe_probe_list(tp), tp.list) { + unregister_fprobe(&tf->fp); + } + } + + out: + if (file) + /* + * Synchronization is done in below function. For perf event, + * file == NULL and perf_trace_event_unreg() calls + * tracepoint_synchronize_unregister() to ensure synchronize + * event. We don't need to care about it. + */ + trace_probe_remove_file(tp, file); + + return 0; +} + /* * called by perf_trace_init() or __ftrace_set_clr_event() under event_mutex. */ From patchwork Sun Mar 16 12:21:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 14018428 X-Patchwork-Delegate: rostedt@goodmis.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7FBD818B47C; Sun, 16 Mar 2025 12:21:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742127717; cv=none; b=aJNZdi7f1FB2sngK8NmWfp0W6jaMeD6EHlIF0b2rZ8HJsN3mWNzrJtVxyq8tzVBSoiN7km+GxETHM6kPkfPpXHr7wlcCHl9zq4TVYQBCB50jUGTgLTWK9r+t8F0710wiUARwn/XF9ghBUrdo3LkBPImXayQH6QvPFonG+uXLIS0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742127717; c=relaxed/simple; bh=y26tfEd3RrwIby+c9q4PmhmcouiauWQ8HV8iy1l4U3M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=mEOfDLUQ4koRgudZSX/BXh+dQjT43OkMAZRkNER4UmxsayWcfAo+UJili18ZBoe5rDzVfflVtYmz4iJLatfoPzhSHJQpWuUUhhQO2w4dq7PnV2RimPXE5uEf8tjihwo4hBckL5+Kc7Rn32Pi5WLycYCA/QucyX3bq6kYyd/U3e8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aZPActpl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aZPActpl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6641EC4CEDD; Sun, 16 Mar 2025 12:21:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1742127717; bh=y26tfEd3RrwIby+c9q4PmhmcouiauWQ8HV8iy1l4U3M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aZPActplDB7iTUEFZYECTRc5twmgJVus7StJps9Bke4kX5VDlfPir5JuriSqc7gNS GWgAd2wz+oKPrho5rgWsNYIUIRxZZOcrfCVyKPHYGsWX+rNzcFKyjGqHzlLoTwhC/C F2UhWrXfod5voQ5hw90+I8rEm4SuLDvTFisUPYZeLzY/MDthNsFfgprdYqAdNHxGvP LPb5/S5yJx12AcOfRNLMzfTXv8Xnj4MGTqMxamnJALlraBYHSbxW6Rd/qyMXeEtUNI bNSyXKQa9Am3AA7Aw23XzdjKMokC6BaRyB7rVlnF7CazvLT0zDfdx9gMlnbL8NDo7k ijXLPyXbg6C6Q== From: "Masami Hiramatsu (Google)" To: Steven Rostedt Cc: Masami Hiramatsu , Mathieu Desnoyers , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Subject: [PATCH 4/4] selftests: tracing: Enable fprobe events before checking enable_functions Date: Sun, 16 Mar 2025 21:21:52 +0900 Message-ID: <174212771234.348872.14455715715729686727.stgit@devnote2> X-Mailer: git-send-email 2.43.0 In-Reply-To: <174212767109.348872.18231451508464729427.stgit@devnote2> References: <174212767109.348872.18231451508464729427.stgit@devnote2> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Masami Hiramatsu (Google) Signed-off-by: Masami Hiramatsu (Google) --- .../ftrace/test.d/dynevent/add_remove_fprobe.tc | 30 +++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc index 449f9d8be746..603dad73e7e8 100644 --- a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc +++ b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc @@ -12,6 +12,18 @@ PLACE3="schedule_timeout" echo "f:myevent1 $PLACE" >> dynamic_events +echo "f:myevent2 $PLACE%return" >> dynamic_events + +# add another event +echo "f:myevent3 $PLACE2" >> dynamic_events + +grep -q myevent1 dynamic_events +grep -q myevent2 dynamic_events +grep -q myevent3 dynamic_events +test -d events/fprobes/myevent1 +test -d events/fprobes/myevent2 + +echo 1 > events/fprobes/myevent1/enable # Make sure the event is attached and is the only one grep -q $PLACE enabled_functions cnt=`cat enabled_functions | wc -l` @@ -19,29 +31,22 @@ if [ $cnt -ne 1 ]; then exit_fail fi -echo "f:myevent2 $PLACE%return" >> dynamic_events - +echo 1 > events/fprobes/myevent2/enable # It should till be the only attached function cnt=`cat enabled_functions | wc -l` if [ $cnt -ne 1 ]; then exit_fail fi -# add another event -echo "f:myevent3 $PLACE2" >> dynamic_events - +echo 1 > events/fprobes/myevent3/enable +# If the function is different, the attached function should be increased grep -q $PLACE2 enabled_functions cnt=`cat enabled_functions | wc -l` if [ $cnt -ne 2 ]; then exit_fail fi -grep -q myevent1 dynamic_events -grep -q myevent2 dynamic_events -grep -q myevent3 dynamic_events -test -d events/fprobes/myevent1 -test -d events/fprobes/myevent2 - +echo 0 > events/fprobes/myevent2/enable echo "-:myevent2" >> dynamic_events grep -q myevent1 dynamic_events @@ -53,6 +58,7 @@ if [ $cnt -ne 2 ]; then exit_fail fi +echo 0 > events/fprobes/enable echo > dynamic_events # Should have none left @@ -63,12 +69,14 @@ fi echo "f:myevent4 $PLACE" >> dynamic_events +echo 1 > events/fprobes/myevent4/enable # Should only have one enabled cnt=`cat enabled_functions | wc -l` if [ $cnt -ne 1 ]; then exit_fail fi +echo 0 > events/fprobes/enable echo > dynamic_events # Should have none left