linux-trace-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Florent Revest <revest@chromium.org>
Cc: linux-trace-kernel@vger.kernel.org,
	LKML <linux-kernel@vger.kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	bpf <bpf@vger.kernel.org>, Sven Schnelle <svens@linux.ibm.com>,
	Alexei Starovoitov <ast@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Alan Maguire <alan.maguire@oracle.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@linutronix.de>, Guo Ren <guoren@kernel.org>
Subject: [RFC PATCH 04/32] function_graph: Add an array structure that will allow multiple callbacks
Date: Mon,  6 Nov 2023 01:07:18 +0900	[thread overview]
Message-ID: <169920043839.482486.410237912533776158.stgit@devnote2> (raw)
In-Reply-To: <169920038849.482486.15796387219966662967.stgit@devnote2>

From: Steven Rostedt (VMware) <rostedt@goodmis.org>

Add an array structure that will eventually allow the function graph tracer
to have up to 16 simultaneous callbacks attached. It's an array of 16
fgraph_ops pointers, that is assigned when one is registered. On entry of a
function the entry of the first item in the array is called, and if it
returns zero, then the callback returns non zero if it wants the return
callback to be called on exit of the function.

The array will simplify the process of having more than one callback
attached to the same function, as its index into the array can be stored on
the shadow stack. We need to only save the index, because this will allow
the fgraph_ops to be freed before the function returns (which may happen if
the function call schedule for a long time).

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
 kernel/trace/fgraph.c |  115 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 82 insertions(+), 33 deletions(-)

diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
index 837daf929d2a..b34ab7ecd7af 100644
--- a/kernel/trace/fgraph.c
+++ b/kernel/trace/fgraph.c
@@ -39,6 +39,11 @@
 DEFINE_STATIC_KEY_FALSE(kill_ftrace_graph);
 int ftrace_graph_active;
 
+static int fgraph_array_cnt;
+#define FGRAPH_ARRAY_SIZE	16
+
+static struct fgraph_ops *fgraph_array[FGRAPH_ARRAY_SIZE];
+
 /* Both enabled by default (can be cleared by function_graph tracer flags */
 static bool fgraph_sleep_time = true;
 
@@ -62,6 +67,20 @@ int __weak ftrace_disable_ftrace_graph_caller(void)
 }
 #endif
 
+int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
+{
+	return 0;
+}
+
+static void ftrace_graph_ret_stub(struct ftrace_graph_ret *trace)
+{
+}
+
+static struct fgraph_ops fgraph_stub = {
+	.entryfunc = ftrace_graph_entry_stub,
+	.retfunc = ftrace_graph_ret_stub,
+};
+
 /**
  * ftrace_graph_stop - set to permanently disable function graph tracing
  *
@@ -159,7 +178,7 @@ int function_graph_enter(unsigned long ret, unsigned long func,
 		goto out;
 
 	/* Only trace if the calling function expects to */
-	if (!ftrace_graph_entry(&trace))
+	if (!fgraph_array[0]->entryfunc(&trace))
 		goto out_ret;
 
 	return 0;
@@ -274,7 +293,7 @@ static unsigned long __ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs
 	trace.retval = fgraph_ret_regs_return_value(ret_regs);
 #endif
 	trace.rettime = trace_clock_local();
-	ftrace_graph_return(&trace);
+	fgraph_array[0]->retfunc(&trace);
 	/*
 	 * The ftrace_graph_return() may still access the current
 	 * ret_stack structure, we need to make sure the update of
@@ -410,11 +429,6 @@ void ftrace_graph_sleep_time_control(bool enable)
 	fgraph_sleep_time = enable;
 }
 
-int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
-{
-	return 0;
-}
-
 /*
  * Simply points to ftrace_stub, but with the proper protocol.
  * Defined by the linker script in linux/vmlinux.lds.h
@@ -652,37 +666,55 @@ static int start_graph_tracing(void)
 int register_ftrace_graph(struct fgraph_ops *gops)
 {
 	int ret = 0;
+	int i;
 
 	mutex_lock(&ftrace_lock);
 
-	/* we currently allow only one tracer registered at a time */
-	if (ftrace_graph_active) {
+	if (!fgraph_array[0]) {
+		/* The array must always have real data on it */
+		for (i = 0; i < FGRAPH_ARRAY_SIZE; i++) {
+			fgraph_array[i] = &fgraph_stub;
+		}
+	}
+
+	/* Look for an available spot */
+	for (i = 0; i < FGRAPH_ARRAY_SIZE; i++) {
+		if (fgraph_array[i] == &fgraph_stub)
+			break;
+	}
+	if (i >= FGRAPH_ARRAY_SIZE) {
 		ret = -EBUSY;
 		goto out;
 	}
 
-	register_pm_notifier(&ftrace_suspend_notifier);
+	fgraph_array[i] = gops;
+	if (i + 1 > fgraph_array_cnt)
+		fgraph_array_cnt = i + 1;
 
 	ftrace_graph_active++;
-	ret = start_graph_tracing();
-	if (ret) {
-		ftrace_graph_active--;
-		goto out;
-	}
 
-	ftrace_graph_return = gops->retfunc;
+	if (ftrace_graph_active == 1) {
+		register_pm_notifier(&ftrace_suspend_notifier);
+		ret = start_graph_tracing();
+		if (ret) {
+			ftrace_graph_active--;
+			goto out;
+		}
 
-	/*
-	 * Update the indirect function to the entryfunc, and the
-	 * function that gets called to the entry_test first. Then
-	 * call the update fgraph entry function to determine if
-	 * the entryfunc should be called directly or not.
-	 */
-	__ftrace_graph_entry = gops->entryfunc;
-	ftrace_graph_entry = ftrace_graph_entry_test;
-	update_function_graph_func();
+		ftrace_graph_return = gops->retfunc;
+
+		/*
+		 * Update the indirect function to the entryfunc, and the
+		 * function that gets called to the entry_test first. Then
+		 * call the update fgraph entry function to determine if
+		 * the entryfunc should be called directly or not.
+		 */
+		__ftrace_graph_entry = gops->entryfunc;
+		ftrace_graph_entry = ftrace_graph_entry_test;
+		update_function_graph_func();
 
-	ret = ftrace_startup(&graph_ops, FTRACE_START_FUNC_RET);
+		ret = ftrace_startup(&graph_ops, FTRACE_START_FUNC_RET);
+	}
 out:
 	mutex_unlock(&ftrace_lock);
 	return ret;
@@ -690,19 +722,36 @@ int register_ftrace_graph(struct fgraph_ops *gops)
 
 void unregister_ftrace_graph(struct fgraph_ops *gops)
 {
+	int i;
+
 	mutex_lock(&ftrace_lock);
 
 	if (unlikely(!ftrace_graph_active))
 		goto out;
 
-	ftrace_graph_active--;
-	ftrace_graph_return = ftrace_stub_graph;
-	ftrace_graph_entry = ftrace_graph_entry_stub;
-	__ftrace_graph_entry = ftrace_graph_entry_stub;
-	ftrace_shutdown(&graph_ops, FTRACE_STOP_FUNC_RET);
-	unregister_pm_notifier(&ftrace_suspend_notifier);
-	unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
+	for (i = 0; i < fgraph_array_cnt; i++)
+		if (gops == fgraph_array[i])
+			break;
+	if (i >= fgraph_array_cnt)
+		goto out;
+
+	fgraph_array[i] = &fgraph_stub;
+	if (i + 1 == fgraph_array_cnt) {
+		for (; i >= 0; i--)
+			if (fgraph_array[i] != &fgraph_stub)
+				break;
+		fgraph_array_cnt = i + 1;
+	}
 
+	ftrace_graph_active--;
+	if (!ftrace_graph_active) {
+		ftrace_graph_return = ftrace_stub_graph;
+		ftrace_graph_entry = ftrace_graph_entry_stub;
+		__ftrace_graph_entry = ftrace_graph_entry_stub;
+		ftrace_shutdown(&graph_ops, FTRACE_STOP_FUNC_RET);
+		unregister_pm_notifier(&ftrace_suspend_notifier);
+		unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
+	}
  out:
 	mutex_unlock(&ftrace_lock);
 }


  parent reply	other threads:[~2023-11-05 16:07 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-05 16:06 [RFC PATCH 00/32] tracing: fprobe: function_graph: Multi-function graph and fprobe on fgraph Masami Hiramatsu (Google)
2023-11-05 16:06 ` [RFC PATCH 01/32] seq_buf: Export seq_buf_puts() Masami Hiramatsu (Google)
2023-11-05 16:06 ` [RFC PATCH 02/32] function_graph: Convert ret_stack to a series of longs Masami Hiramatsu (Google)
2023-11-05 16:07 ` [RFC PATCH 03/32] fgraph: Use BUILD_BUG_ON() to make sure we have structures divisible by long Masami Hiramatsu (Google)
2023-11-05 16:07 ` Masami Hiramatsu (Google) [this message]
2023-11-05 16:07 ` [RFC PATCH 05/32] function_graph: Allow multiple users to attach to function graph Masami Hiramatsu (Google)
2023-11-05 16:07 ` [RFC PATCH 06/32] function_graph: Remove logic around ftrace_graph_entry and return Masami Hiramatsu (Google)
2023-11-05 16:07 ` [RFC PATCH 07/32] ftrace/function_graph: Pass fgraph_ops to function graph callbacks Masami Hiramatsu (Google)
2023-11-05 16:08 ` [RFC PATCH 08/32] ftrace: Allow function_graph tracer to be enabled in instances Masami Hiramatsu (Google)
2023-11-05 16:08 ` [RFC PATCH 09/32] ftrace: Allow ftrace startup flags exist without dynamic ftrace Masami Hiramatsu (Google)
2023-11-05 16:08 ` [RFC PATCH 10/32] function_graph: Have the instances use their own ftrace_ops for filtering Masami Hiramatsu (Google)
2023-11-07  1:47   ` Masami Hiramatsu
2023-11-05 16:08 ` [RFC PATCH 11/32] function_graph: Add "task variables" per task for fgraph_ops Masami Hiramatsu (Google)
2023-11-05 16:08 ` [RFC PATCH 12/32] function_graph: Move set_graph_function tests to shadow stack global var Masami Hiramatsu (Google)
2023-11-05 16:09 ` [RFC PATCH 13/32] function_graph: Move graph depth stored data " Masami Hiramatsu (Google)
2023-11-05 16:09 ` [RFC PATCH 14/32] function_graph: Move graph notrace bit " Masami Hiramatsu (Google)
2023-11-05 16:09 ` [RFC PATCH 15/32] function_graph: Implement fgraph_reserve_data() and fgraph_retrieve_data() Masami Hiramatsu (Google)
2023-11-05 16:09 ` [RFC PATCH 16/32] function_graph: Add selftest for passing local variables Masami Hiramatsu (Google)
2023-11-05 16:09 ` [RFC PATCH 17/32] function_graph: Fix to update curr_ret_stack with ARRAY entry size Masami Hiramatsu (Google)
2023-11-05 16:10 ` [RFC PATCH 18/32] function_graph: Fix to initalize ftrace_ops for fgraph with ftrace_graph_func Masami Hiramatsu (Google)
2023-11-06 10:04   ` Masami Hiramatsu
2023-11-07  1:49     ` Masami Hiramatsu
2023-11-07  3:07       ` Steven Rostedt
2023-11-05 16:10 ` [RFC PATCH 19/32] function_graph: Fix to check the return value of ftrace_pop_return_trace() Masami Hiramatsu (Google)
2023-11-05 16:10 ` [RFC PATCH 20/32] function_graph: Pass the size of reserved data when retrieving it Masami Hiramatsu (Google)
2023-11-05 16:10 ` [RFC PATCH 21/32] function_graph: Expand the max reserved data size Masami Hiramatsu (Google)
2023-11-05 16:10 ` [RFC PATCH 22/32] function_graph: Add a new entry handler with parent_ip and ftrace_regs Masami Hiramatsu (Google)
2023-11-05 16:11 ` [RFC PATCH 23/32] function_graph: Add a new exit " Masami Hiramatsu (Google)
2023-11-05 16:11 ` [RFC PATCH 24/32] x86/ftrace: Enable HAVE_FUNCTION_GRAPH_FREGS Masami Hiramatsu (Google)
2023-11-05 17:25   ` Peter Zijlstra
2023-11-05 19:11     ` Steven Rostedt
2023-11-05 21:28       ` Steven Rostedt
2023-11-05 23:17       ` Peter Zijlstra
2023-11-05 23:33         ` Steven Rostedt
2023-11-05 23:34           ` Steven Rostedt
2023-11-06  0:38             ` Masami Hiramatsu
2023-11-06 10:19               ` Peter Zijlstra
2023-11-06 12:47                 ` Masami Hiramatsu
2023-11-06 12:52                   ` Peter Zijlstra
2023-11-06  1:05           ` Masami Hiramatsu
2023-11-06 16:37             ` Steven Rostedt
2023-11-07  0:42               ` Masami Hiramatsu
2023-11-07  3:06                 ` Steven Rostedt
2023-11-07  5:43                   ` Masami Hiramatsu
2023-11-07 13:48                     ` Steven Rostedt
2023-11-07 14:09                       ` Steven Rostedt
2023-11-05 16:11 ` [RFC PATCH 25/32] fprobe: Use ftrace_regs in fprobe entry handler Masami Hiramatsu (Google)
2023-11-05 16:11 ` [RFC PATCH 26/32] fprobe: Use ftrace_regs in fprobe exit handler Masami Hiramatsu (Google)
2023-11-05 16:11 ` [RFC PATCH 27/32] tracing: Add ftrace_partial_regs() for converting ftrace_regs to pt_regs Masami Hiramatsu (Google)
2023-11-05 16:12 ` [RFC PATCH 28/32] tracing: Add ftrace_fill_perf_regs() for perf event Masami Hiramatsu (Google)
2023-11-05 16:12 ` [RFC PATCH 29/32] fprobe: Rewrite fprobe on function-graph tracer Masami Hiramatsu (Google)
2023-11-05 16:12 ` [RFC PATCH 30/32] tracing/fprobe: Enable fprobe events with CONFIG_DYNAMIC_FTRACE_WITH_ARGS Masami Hiramatsu (Google)
2023-11-05 16:12 ` [RFC PATCH 31/32] bpf: Enable kprobe_multi feature if CONFIG_FPROBE is enabled Masami Hiramatsu (Google)
2023-11-05 16:12 ` [RFC PATCH 32/32] Documentation: probes: Update fprobe on function-graph tracer Masami Hiramatsu (Google)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=169920043839.482486.410237912533776158.stgit@devnote2 \
    --to=mhiramat@kernel.org \
    --cc=acme@kernel.org \
    --cc=alan.maguire@oracle.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=guoren@kernel.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=martin.lau@linux.dev \
    --cc=peterz@infradead.org \
    --cc=revest@chromium.org \
    --cc=rostedt@goodmis.org \
    --cc=svens@linux.ibm.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).