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 23/32] function_graph: Add a new exit handler with parent_ip and ftrace_regs
Date: Mon, 6 Nov 2023 01:11:08 +0900 [thread overview]
Message-ID: <169920066851.482486.17730951166172619260.stgit@devnote2> (raw)
In-Reply-To: <169920038849.482486.15796387219966662967.stgit@devnote2>
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Add a new return handler to fgraph_ops as 'retregfunc' which takes
parent_ip and ftrace_regs instead of ftrace_graph_ret. This handler
is available only if the arch support CONFIG_HAVE_FUNCTION_GRAPH_FREGS.
Note that the 'retfunc' and 'reregfunc' are mutual exclusive.
You can set only one of them.
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
arch/x86/include/asm/ftrace.h | 2 +
include/linux/ftrace.h | 10 +++++-
kernel/trace/Kconfig | 5 ++-
kernel/trace/fgraph.c | 74 +++++++++++++++++++++++++++--------------
4 files changed, 63 insertions(+), 28 deletions(-)
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index 897cf02c20b1..74b1d245c38b 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -66,6 +66,8 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs)
override_function_with_return(&(fregs)->regs)
#define ftrace_regs_query_register_offset(name) \
regs_query_register_offset(name)
+#define ftrace_regs_get_frame_pointer(fregs) \
+ frame_pointer(&(fregs)->regs)
struct ftrace_ops;
#define ftrace_graph_func ftrace_graph_func
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index a6fd930d3500..0c036c5d7c12 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -43,7 +43,9 @@ struct dyn_ftrace;
char *arch_ftrace_match_adjust(char *str, const char *search);
-#ifdef CONFIG_HAVE_FUNCTION_GRAPH_RETVAL
+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FREGS
+unsigned long ftrace_return_to_handler(struct ftrace_regs *fregs);
+#elif defined(CONFIG_HAVE_FUNCTION_GRAPH_RETVAL)
struct fgraph_ret_regs;
unsigned long ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs);
#else
@@ -131,6 +133,7 @@ struct ftrace_regs {
#define ftrace_regs_set_instruction_pointer(fregs, ip) do { } while (0)
#endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */
+
static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs)
{
if (!fregs)
@@ -1041,6 +1044,10 @@ typedef int (*trace_func_graph_regs_ent_t)(unsigned long func,
unsigned long parent_ip,
struct ftrace_regs *fregs,
struct fgraph_ops *); /* entry w/ regs */
+typedef void (*trace_func_graph_regs_ret_t)(unsigned long func,
+ unsigned long parent_ip,
+ struct ftrace_regs *,
+ struct fgraph_ops *); /* return w/ regs */
extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace, struct fgraph_ops *gops);
@@ -1050,6 +1057,7 @@ struct fgraph_ops {
trace_func_graph_ent_t entryfunc;
trace_func_graph_ret_t retfunc;
trace_func_graph_regs_ent_t entryregfunc;
+ trace_func_graph_regs_ret_t retregfunc;
struct ftrace_ops ops; /* for the hash lists */
void *private;
int idx;
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 61c541c36596..308b3bec01b1 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -34,6 +34,9 @@ config HAVE_FUNCTION_GRAPH_TRACER
config HAVE_FUNCTION_GRAPH_RETVAL
bool
+config HAVE_FUNCTION_GRAPH_FREGS
+ bool
+
config HAVE_DYNAMIC_FTRACE
bool
help
@@ -232,7 +235,7 @@ config FUNCTION_GRAPH_TRACER
config FUNCTION_GRAPH_RETVAL
bool "Kernel Function Graph Return Value"
- depends on HAVE_FUNCTION_GRAPH_RETVAL
+ depends on HAVE_FUNCTION_GRAPH_RETVAL || HAVE_FUNCTION_GRAPH_FREGS
depends on FUNCTION_GRAPH_TRACER
default n
help
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
index 2623a5987f52..c76fb2f33437 100644
--- a/kernel/trace/fgraph.c
+++ b/kernel/trace/fgraph.c
@@ -624,8 +624,7 @@ int function_graph_enter_regs(unsigned long ret, unsigned long func,
/* Retrieve a function return address to the trace stack on thread info.*/
static struct ftrace_ret_stack *
-ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,
- unsigned long frame_pointer)
+ftrace_pop_return_trace(unsigned long *ret, unsigned long frame_pointer)
{
struct ftrace_ret_stack *ret_stack;
int index;
@@ -670,10 +669,6 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,
#endif
*ret = ret_stack->ret;
- trace->func = ret_stack->func;
- trace->calltime = ret_stack->calltime;
- trace->overrun = atomic_read(¤t->trace_overrun);
- trace->depth = current->curr_ret_depth;
/*
* We still want to trace interrupts coming in if
* max_depth is set to 1. Make sure the decrement is
@@ -712,22 +707,43 @@ static struct notifier_block ftrace_suspend_notifier = {
/* fgraph_ret_regs is not defined without CONFIG_FUNCTION_GRAPH_RETVAL */
struct fgraph_ret_regs;
+static void fgraph_call_retfunc(struct ftrace_regs *fregs,
+ struct fgraph_ret_regs *ret_regs,
+ struct ftrace_ret_stack *ret_stack,
+ struct fgraph_ops *gops)
+{
+ struct ftrace_graph_ret trace;
+
+ trace.func = ret_stack->func;
+ trace.calltime = ret_stack->calltime;
+ trace.overrun = atomic_read(¤t->trace_overrun);
+ trace.depth = current->curr_ret_depth;
+ trace.rettime = trace_clock_local();
+#ifdef CONFIG_FUNCTION_GRAPH_RETVAL
+ if (fregs)
+ trace.retval = ftrace_regs_return_value(fregs);
+ else
+ trace.retval = fgraph_ret_regs_return_value(ret_regs);
+#endif
+ gops->retfunc(&trace, gops);
+}
+
/*
* Send the trace to the ring-buffer.
* @return the original return address.
*/
-static unsigned long __ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs,
+static unsigned long __ftrace_return_to_handler(struct ftrace_regs *fregs,
+ struct fgraph_ret_regs *ret_regs,
unsigned long frame_pointer)
{
struct ftrace_ret_stack *ret_stack;
- struct ftrace_graph_ret trace;
- unsigned long ret;
+ struct fgraph_ops *gops;
int curr_ret_stack;
+ unsigned long ret;
int stop_at;
int index;
- int idx;
- ret_stack = ftrace_pop_return_trace(&trace, &ret, frame_pointer);
+ ret_stack = ftrace_pop_return_trace(&ret, frame_pointer);
if (unlikely(!ret_stack)) {
ftrace_graph_stop();
@@ -736,11 +752,6 @@ static unsigned long __ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs
return (unsigned long)panic;
}
- trace.rettime = trace_clock_local();
-#ifdef CONFIG_FUNCTION_GRAPH_RETVAL
- trace.retval = fgraph_ret_regs_return_value(ret_regs);
-#endif
-
curr_ret_stack = current->curr_ret_stack;
index = get_ret_stack_index(current, curr_ret_stack - 1);
@@ -753,8 +764,11 @@ static unsigned long __ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs
val = current->ret_stack[curr_ret_stack - 1];
switch (__get_type(val)) {
case FGRAPH_TYPE_ARRAY:
- idx = __get_array(val);
- fgraph_array[idx]->retfunc(&trace, fgraph_array[idx]);
+ gops = fgraph_array[__get_array(val)];
+ if (gops->retregfunc)
+ gops->retregfunc(ret_stack->func, ret, fregs, gops);
+ else
+ fgraph_call_retfunc(fregs, ret_regs, ret_stack, gops);
curr_ret_stack -= __get_index(val);
break;
case FGRAPH_TYPE_RESERVED:
@@ -778,20 +792,22 @@ static unsigned long __ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs
return ret;
}
-/*
- * After all architecures have selected HAVE_FUNCTION_GRAPH_RETVAL, we can
- * leave only ftrace_return_to_handler(ret_regs).
- */
-#ifdef CONFIG_HAVE_FUNCTION_GRAPH_RETVAL
+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FREGS
+unsigned long ftrace_return_to_handler(struct ftrace_regs *fregs)
+{
+ return __ftrace_return_to_handler(fregs, NULL,
+ ftrace_regs_get_frame_pointer(fregs));
+}
+#elif defined(CONFIG_HAVE_FUNCTION_GRAPH_RETVAL)
unsigned long ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs)
{
- return __ftrace_return_to_handler(ret_regs,
+ return __ftrace_return_to_handler(NULL, ret_regs,
fgraph_ret_regs_frame_pointer(ret_regs));
}
#else
unsigned long ftrace_return_to_handler(unsigned long frame_pointer)
{
- return __ftrace_return_to_handler(NULL, frame_pointer);
+ return __ftrace_return_to_handler(NULL, NULL, frame_pointer);
}
#endif
@@ -1132,9 +1148,15 @@ int register_ftrace_graph(struct fgraph_ops *gops)
int ret = 0;
int i;
- if (gops->entryfunc && gops->entryregfunc)
+ if ((gops->entryfunc && gops->entryregfunc) ||
+ (gops->retfunc && gops->retregfunc))
return -EINVAL;
+#ifndef CONFIG_HAVE_FUNCTION_GRAPH_FREGS
+ if (gops->retregfunc)
+ return -EOPNOTSUPP;
+#endif
+
mutex_lock(&ftrace_lock);
if (!gops->ops.func) {
next prev parent reply other threads:[~2023-11-05 16:11 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 ` [RFC PATCH 04/32] function_graph: Add an array structure that will allow multiple callbacks Masami Hiramatsu (Google)
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 ` Masami Hiramatsu (Google) [this message]
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=169920066851.482486.17730951166172619260.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.