aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2024-09-14 17:48:08 -0400
committerSteven Rostedt (Google) <rostedt@goodmis.org>2024-09-30 11:12:46 -0400
commitf1f36e22bee967db5e812a65e24389e54c46f3c2 (patch)
tree6ca6497a81dbf3437901f77881c513443b8ba0f4 /kernel/trace/ftrace.c
parentftrace: Use a running sleeptime instead of saving on shadow stack (diff)
downloadlinux-rng-f1f36e22bee967db5e812a65e24389e54c46f3c2.tar.xz
linux-rng-f1f36e22bee967db5e812a65e24389e54c46f3c2.zip
ftrace: Have calltime be saved in the fgraph storage
The calltime field in the shadow stack frame is only used by the function graph tracer and profiler. But now that there's other users of the function graph infrastructure, this adds overhead and wastes space on the shadow stack. Move the calltime to the fgraph data storage, where the function graph and profiler entry functions will save it in its own graph storage and retrieve it in its exit functions. Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jiri Olsa <olsajiri@gmail.com> Link: https://lore.kernel.org/20240914214827.096968730@goodmis.org Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 90b3975d5315..cae388122ca8 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -821,6 +821,7 @@ void ftrace_graph_graph_time_control(bool enable)
}
struct profile_fgraph_data {
+ unsigned long long calltime;
unsigned long long subtime;
unsigned long long sleeptime;
};
@@ -842,6 +843,7 @@ static int profile_graph_entry(struct ftrace_graph_ent *trace,
profile_data->subtime = 0;
profile_data->sleeptime = current->ftrace_sleeptime;
+ profile_data->calltime = trace_clock_local();
return 1;
}
@@ -850,9 +852,9 @@ static void profile_graph_return(struct ftrace_graph_ret *trace,
struct fgraph_ops *gops)
{
struct profile_fgraph_data *profile_data;
- struct profile_fgraph_data *parent_data;
struct ftrace_profile_stat *stat;
unsigned long long calltime;
+ unsigned long long rettime = trace_clock_local();
struct ftrace_profile *rec;
unsigned long flags;
int size;
@@ -862,29 +864,28 @@ static void profile_graph_return(struct ftrace_graph_ret *trace,
if (!stat->hash || !ftrace_profile_enabled)
goto out;
+ profile_data = fgraph_retrieve_data(gops->idx, &size);
+
/* If the calltime was zero'd ignore it */
- if (!trace->calltime)
+ if (!profile_data || !profile_data->calltime)
goto out;
- calltime = trace->rettime - trace->calltime;
+ calltime = rettime - profile_data->calltime;
if (!fgraph_sleep_time) {
- profile_data = fgraph_retrieve_data(gops->idx, &size);
- if (profile_data && current->ftrace_sleeptime)
+ if (current->ftrace_sleeptime)
calltime -= current->ftrace_sleeptime - profile_data->sleeptime;
}
if (!fgraph_graph_time) {
+ struct profile_fgraph_data *parent_data;
/* Append this call time to the parent time to subtract */
parent_data = fgraph_retrieve_parent_data(gops->idx, &size, 1);
if (parent_data)
parent_data->subtime += calltime;
- if (!profile_data)
- profile_data = fgraph_retrieve_data(gops->idx, &size);
-
- if (profile_data && profile_data->subtime && profile_data->subtime < calltime)
+ if (profile_data->subtime && profile_data->subtime < calltime)
calltime -= profile_data->subtime;
else
calltime = 0;