All of lore.kernel.org
 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 v2 13/31] function_graph: Add "task variables" per task for fgraph_ops
Date: Wed,  8 Nov 2023 23:26:53 +0900	[thread overview]
Message-ID: <169945361301.55307.14643353930499117634.stgit@devnote2> (raw)
In-Reply-To: <169945345785.55307.5003201137843449313.stgit@devnote2>

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

Add a "task variables" array on the tasks shadow ret_stack that is the
size of longs for each possible registered fgraph_ops. That's a total
of 16, taking up 8 * 16 = 128 bytes (out of a page size 4k).

This will allow for fgraph_ops to do specific features on a per task basis
having a way to maintain state for each task.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
 Changes in v2:
  - Make description lines shorter than 76 chars.
---
 include/linux/ftrace.h |    2 +
 kernel/trace/fgraph.c  |   73 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index d30eb8a97a50..3f9f1f48e8fd 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -1071,6 +1071,7 @@ struct fgraph_ops {
 	trace_func_graph_ret_t		retfunc;
 	struct ftrace_ops		ops; /* for the hash lists */
 	void				*private;
+	int				idx;
 };
 
 /*
@@ -1109,6 +1110,7 @@ ftrace_graph_get_ret_stack(struct task_struct *task, int idx);
 
 unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
 				    unsigned long ret, unsigned long *retp);
+unsigned long *fgraph_get_task_var(struct fgraph_ops *gops);
 
 /*
  * Sometimes we don't want to trace a function with the function
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
index 97cf320d20a8..79bdd3c775dd 100644
--- a/kernel/trace/fgraph.c
+++ b/kernel/trace/fgraph.c
@@ -92,10 +92,18 @@ enum {
 #define SHADOW_STACK_SIZE (PAGE_SIZE)
 #define SHADOW_STACK_INDEX (SHADOW_STACK_SIZE / sizeof(long))
 /* Leave on a buffer at the end */
-#define SHADOW_STACK_MAX_INDEX (SHADOW_STACK_INDEX - (FGRAPH_RET_INDEX + 1))
+#define SHADOW_STACK_MAX_INDEX				\
+	(SHADOW_STACK_INDEX - (FGRAPH_RET_INDEX + 1 + FGRAPH_ARRAY_SIZE))
 
 #define RET_STACK(t, index) ((struct ftrace_ret_stack *)(&(t)->ret_stack[index]))
 
+/*
+ * Each fgraph_ops has a reservered unsigned long at the end (top) of the
+ * ret_stack to store task specific state.
+ */
+#define SHADOW_STACK_TASK_VARS(ret_stack) \
+	((unsigned long *)(&(ret_stack)[SHADOW_STACK_INDEX - FGRAPH_ARRAY_SIZE]))
+
 DEFINE_STATIC_KEY_FALSE(kill_ftrace_graph);
 int ftrace_graph_active;
 
@@ -131,6 +139,44 @@ static void return_run(struct ftrace_graph_ret *trace, struct fgraph_ops *ops)
 {
 }
 
+static void ret_stack_set_task_var(struct task_struct *t, int idx, long val)
+{
+	unsigned long *gvals = SHADOW_STACK_TASK_VARS(t->ret_stack);
+
+	gvals[idx] = val;
+}
+
+static unsigned long *
+ret_stack_get_task_var(struct task_struct *t, int idx)
+{
+	unsigned long *gvals = SHADOW_STACK_TASK_VARS(t->ret_stack);
+
+	return &gvals[idx];
+}
+
+static void ret_stack_init_task_vars(unsigned long *ret_stack)
+{
+	unsigned long *gvals = SHADOW_STACK_TASK_VARS(ret_stack);
+
+	memset(gvals, 0, sizeof(*gvals) * FGRAPH_ARRAY_SIZE);
+}
+
+/**
+ * fgraph_get_task_var - retrieve a task specific state variable
+ * @gops: The ftrace_ops that owns the task specific variable
+ *
+ * Every registered fgraph_ops has a task state variable
+ * reserved on the task's ret_stack. This function returns the
+ * address to that variable.
+ *
+ * Returns the address to the fgraph_ops @gops tasks specific
+ * unsigned long variable.
+ */
+unsigned long *fgraph_get_task_var(struct fgraph_ops *gops)
+{
+	return ret_stack_get_task_var(current, gops->idx);
+}
+
 /*
  * @offset: The index into @t->ret_stack to find the ret_stack entry
  * @index: Where to place the index into @t->ret_stack of that entry
@@ -708,6 +754,7 @@ static int alloc_retstack_tasklist(unsigned long **ret_stack_list)
 
 		if (t->ret_stack == NULL) {
 			atomic_set(&t->trace_overrun, 0);
+			ret_stack_init_task_vars(ret_stack_list[start]);
 			t->curr_ret_stack = 0;
 			t->curr_ret_depth = -1;
 			/* Make sure the tasks see the 0 first: */
@@ -768,6 +815,7 @@ static void
 graph_init_task(struct task_struct *t, unsigned long *ret_stack)
 {
 	atomic_set(&t->trace_overrun, 0);
+	ret_stack_init_task_vars(ret_stack);
 	t->ftrace_timestamp = 0;
 	t->curr_ret_stack = 0;
 	t->curr_ret_depth = -1;
@@ -866,6 +914,24 @@ static int start_graph_tracing(void)
 	return ret;
 }
 
+static void init_task_vars(int idx)
+{
+	struct task_struct *g, *t;
+	int cpu;
+
+	for_each_online_cpu(cpu) {
+		if (idle_task(cpu)->ret_stack)
+			ret_stack_set_task_var(idle_task(cpu), idx, 0);
+	}
+
+	read_lock(&tasklist_lock);
+	for_each_process_thread(g, t) {
+		if (t->ret_stack)
+			ret_stack_set_task_var(t, idx, 0);
+	}
+	read_unlock(&tasklist_lock);
+}
+
 int register_ftrace_graph(struct fgraph_ops *gops)
 {
 	int command = 0;
@@ -901,6 +967,7 @@ int register_ftrace_graph(struct fgraph_ops *gops)
 	fgraph_array[i] = gops;
 	if (i + 1 > fgraph_array_cnt)
 		fgraph_array_cnt = i + 1;
+	gops->idx = i;
 
 	ftrace_graph_active++;
 
@@ -918,6 +985,8 @@ int register_ftrace_graph(struct fgraph_ops *gops)
 		ftrace_graph_return = return_run;
 		ftrace_graph_entry = entry_run;
 		command = FTRACE_START_FUNC_RET;
+	} else {
+		init_task_vars(gops->idx);
 	}
 
 	ret = ftrace_startup(&gops->ops, command);
@@ -942,6 +1011,8 @@ void unregister_ftrace_graph(struct fgraph_ops *gops)
 	if (i >= fgraph_array_cnt)
 		goto out;
 
+	WARN_ON_ONCE(gops->idx != i);
+
 	fgraph_array[i] = &fgraph_stub;
 	if (i + 1 == fgraph_array_cnt) {
 		for (; i >= 0; i--)


  parent reply	other threads:[~2023-11-08 14:26 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-08 14:24 [RFC PATCH v2 00/31] tracing: fprobe: function_graph: Multi-function graph and fprobe on fgraph Masami Hiramatsu (Google)
2023-11-08 14:24 ` [RFC PATCH v2 01/31] tracing: Add a comment about ftrace_regs definition Masami Hiramatsu (Google)
2023-11-08 23:14   ` Masami Hiramatsu
2023-11-10 11:11     ` Mark Rutland
2023-11-11  2:24       ` Masami Hiramatsu
2023-11-08 14:24 ` [RFC PATCH v2 02/31] x86: tracing: Add ftrace_regs definition in the header Masami Hiramatsu (Google)
2023-11-08 14:24 ` [RFC PATCH v2 03/31] seq_buf: Export seq_buf_puts() Masami Hiramatsu (Google)
2023-11-08 14:25 ` [RFC PATCH v2 04/31] function_graph: Convert ret_stack to a series of longs Masami Hiramatsu (Google)
2023-11-08 14:25 ` [RFC PATCH v2 05/31] fgraph: Use BUILD_BUG_ON() to make sure we have structures divisible by long Masami Hiramatsu (Google)
2023-11-08 14:25 ` [RFC PATCH v2 06/31] function_graph: Add an array structure that will allow multiple callbacks Masami Hiramatsu (Google)
2023-11-08 14:25 ` [RFC PATCH v2 07/31] function_graph: Allow multiple users to attach to function graph Masami Hiramatsu (Google)
2023-11-08 14:25 ` [RFC PATCH v2 08/31] function_graph: Remove logic around ftrace_graph_entry and return Masami Hiramatsu (Google)
2023-11-08 14:26 ` [RFC PATCH v2 09/31] ftrace/function_graph: Pass fgraph_ops to function graph callbacks Masami Hiramatsu (Google)
2023-11-08 14:26 ` [RFC PATCH v2 10/31] ftrace: Allow function_graph tracer to be enabled in instances Masami Hiramatsu (Google)
2023-11-08 14:26 ` [RFC PATCH v2 11/31] ftrace: Allow ftrace startup flags exist without dynamic ftrace Masami Hiramatsu (Google)
2023-11-08 14:26 ` [RFC PATCH v2 12/31] function_graph: Have the instances use their own ftrace_ops for filtering Masami Hiramatsu (Google)
2023-11-10  1:51   ` Masami Hiramatsu
2023-11-10  2:18     ` Steven Rostedt
2023-11-10  3:09       ` Masami Hiramatsu
2023-11-08 14:26 ` Masami Hiramatsu (Google) [this message]
2023-11-08 14:27 ` [RFC PATCH v2 14/31] function_graph: Move set_graph_function tests to shadow stack global var Masami Hiramatsu (Google)
2023-11-08 14:27 ` [RFC PATCH v2 15/31] function_graph: Move graph depth stored data " Masami Hiramatsu (Google)
2023-11-08 14:27 ` [RFC PATCH v2 16/31] function_graph: Move graph notrace bit " Masami Hiramatsu (Google)
2023-11-08 14:27 ` [RFC PATCH v2 17/31] function_graph: Implement fgraph_reserve_data() and fgraph_retrieve_data() Masami Hiramatsu (Google)
2023-11-08 14:27 ` [RFC PATCH v2 18/31] function_graph: Add selftest for passing local variables Masami Hiramatsu (Google)
2023-11-08 14:28 ` [RFC PATCH v2 19/31] function_graph: Add a new entry handler with parent_ip and ftrace_regs Masami Hiramatsu (Google)
2023-11-08 14:28 ` [RFC PATCH v2 20/31] function_graph: Add a new exit " Masami Hiramatsu (Google)
2023-11-08 23:17   ` Masami Hiramatsu
2023-11-08 14:28 ` [RFC PATCH v2 21/31] x86/ftrace: Enable HAVE_FUNCTION_GRAPH_FREGS Masami Hiramatsu (Google)
2023-11-08 14:28 ` [RFC PATCH v2 22/31] fprobe: Use ftrace_regs in fprobe entry handler Masami Hiramatsu (Google)
2023-11-08 14:28 ` [RFC PATCH v2 23/31] fprobe: Use ftrace_regs in fprobe exit handler Masami Hiramatsu (Google)
2023-11-08 14:28 ` [RFC PATCH v2 24/31] tracing: Add ftrace_partial_regs() for converting ftrace_regs to pt_regs Masami Hiramatsu (Google)
2023-11-08 14:29 ` [RFC PATCH v2 25/31] tracing: Add ftrace_fill_perf_regs() for perf event Masami Hiramatsu (Google)
2023-11-08 14:29 ` [RFC PATCH v2 26/31] fprobe: Rewrite fprobe on function-graph tracer Masami Hiramatsu (Google)
2023-11-10  7:17   ` Masami Hiramatsu
2023-11-11  1:44     ` Steven Rostedt
2023-11-11  3:01       ` Masami Hiramatsu
2023-11-08 14:29 ` [RFC PATCH v2 27/31] tracing/fprobe: Remove nr_maxactive from fprobe Masami Hiramatsu (Google)
2023-11-08 14:29 ` [RFC PATCH v2 28/31] tracing/fprobe: Enable fprobe events with CONFIG_DYNAMIC_FTRACE_WITH_ARGS Masami Hiramatsu (Google)
2023-11-08 14:29 ` [RFC PATCH v2 29/31] bpf: Enable kprobe_multi feature if CONFIG_FPROBE is enabled Masami Hiramatsu (Google)
2023-11-08 14:30 ` [RFC PATCH v2 30/31] selftests: ftrace: Remove obsolate maxactive syntax check Masami Hiramatsu (Google)
2023-11-08 14:30 ` [RFC PATCH v2 31/31] 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=169945361301.55307.14643353930499117634.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.