Skip to content

Commit 0a6c61b

Browse files
mhiramatrostedt
authored andcommitted
fgraph: Simplify return address printing in function graph tracer
Simplify return address printing in the function graph tracer by removing fgraph_extras. Since this feature is only used by the function graph tracer and the feature flags can directly accessible from the function graph tracer, fgraph_extras can be removed from the fgraph callback. Cc: Donglin Peng <[email protected]> Link: https://lore.kernel.org/172857234900.270774.15378354017601069781.stgit@devnote2 Signed-off-by: Masami Hiramatsu (Google) <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 474ec3e commit 0a6c61b

File tree

8 files changed

+48
-51
lines changed

8 files changed

+48
-51
lines changed

include/linux/ftrace.h

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,29 +1068,20 @@ struct ftrace_graph_ret {
10681068
unsigned long long rettime;
10691069
} __packed;
10701070

1071-
struct fgraph_extras;
10721071
struct fgraph_ops;
10731072

10741073
/* Type of the callback handlers for tracing function graph*/
10751074
typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *,
10761075
struct fgraph_ops *); /* return */
10771076
typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *,
1078-
struct fgraph_ops *,
1079-
struct fgraph_extras *); /* entry */
1077+
struct fgraph_ops *); /* entry */
10801078

10811079
extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace,
1082-
struct fgraph_ops *gops,
1083-
struct fgraph_extras *extras);
1080+
struct fgraph_ops *gops);
10841081
bool ftrace_pids_enabled(struct ftrace_ops *ops);
10851082

10861083
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
10871084

1088-
/* Used to convey some extra datas when creating a graph entry */
1089-
struct fgraph_extras {
1090-
u32 flags;
1091-
unsigned long retaddr;
1092-
};
1093-
10941085
struct fgraph_ops {
10951086
trace_func_graph_ent_t entryfunc;
10961087
trace_func_graph_ret_t retfunc;
@@ -1131,13 +1122,12 @@ function_graph_enter(unsigned long ret, unsigned long func,
11311122

11321123
struct ftrace_ret_stack *
11331124
ftrace_graph_get_ret_stack(struct task_struct *task, int skip);
1125+
unsigned long ftrace_graph_top_ret_addr(struct task_struct *task);
11341126

11351127
unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
11361128
unsigned long ret, unsigned long *retp);
11371129
unsigned long *fgraph_get_task_var(struct fgraph_ops *gops);
11381130

1139-
u32 graph_tracer_flags_get(u32 flags);
1140-
11411131
/*
11421132
* Sometimes we don't want to trace a function with the function
11431133
* graph tracer but we want them to keep traced by the usual function

kernel/trace/fgraph.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,7 @@ static inline unsigned long make_data_type_val(int idx, int size, int offset)
290290
}
291291

292292
/* ftrace_graph_entry set to this to tell some archs to run function graph */
293-
static int entry_run(struct ftrace_graph_ent *trace, struct fgraph_ops *ops,
294-
struct fgraph_extras *extras)
293+
static int entry_run(struct ftrace_graph_ent *trace, struct fgraph_ops *ops)
295294
{
296295
return 0;
297296
}
@@ -519,8 +518,7 @@ int __weak ftrace_disable_ftrace_graph_caller(void)
519518
#endif
520519

521520
int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace,
522-
struct fgraph_ops *gops,
523-
struct fgraph_extras *extras)
521+
struct fgraph_ops *gops)
524522
{
525523
return 0;
526524
}
@@ -648,20 +646,13 @@ int function_graph_enter(unsigned long ret, unsigned long func,
648646
unsigned long frame_pointer, unsigned long *retp)
649647
{
650648
struct ftrace_graph_ent trace;
651-
struct fgraph_extras extras;
652649
unsigned long bitmap = 0;
653650
int offset;
654651
int i;
655-
int idx = 0;
656652

657653
trace.func = func;
658654
trace.depth = ++current->curr_ret_depth;
659655

660-
extras.flags = graph_tracer_flags_get(TRACE_GRAPH_PRINT_RETADDR);
661-
if (IS_ENABLED(CONFIG_FUNCTION_GRAPH_RETADDR)
662-
&& extras.flags & TRACE_GRAPH_PRINT_RETADDR)
663-
extras.retaddr = ftrace_graph_ret_addr(current, &idx, ret, retp);
664-
665656
offset = ftrace_push_return_trace(ret, func, frame_pointer, retp, 0);
666657
if (offset < 0)
667658
goto out;
@@ -670,7 +661,7 @@ int function_graph_enter(unsigned long ret, unsigned long func,
670661
if (static_branch_likely(&fgraph_do_direct)) {
671662
int save_curr_ret_stack = current->curr_ret_stack;
672663

673-
if (static_call(fgraph_func)(&trace, fgraph_direct_gops, &extras))
664+
if (static_call(fgraph_func)(&trace, fgraph_direct_gops))
674665
bitmap |= BIT(fgraph_direct_gops->idx);
675666
else
676667
/* Clear out any saved storage */
@@ -688,7 +679,7 @@ int function_graph_enter(unsigned long ret, unsigned long func,
688679

689680
save_curr_ret_stack = current->curr_ret_stack;
690681
if (ftrace_ops_test(&gops->ops, func, NULL) &&
691-
gops->entryfunc(&trace, gops, &extras))
682+
gops->entryfunc(&trace, gops))
692683
bitmap |= BIT(i);
693684
else
694685
/* Clear out any saved storage */
@@ -905,6 +896,29 @@ ftrace_graph_get_ret_stack(struct task_struct *task, int idx)
905896
return ret_stack;
906897
}
907898

899+
/**
900+
* ftrace_graph_top_ret_addr - return the top return address in the shadow stack
901+
* @task: The task to read the shadow stack from.
902+
*
903+
* Return the first return address on the shadow stack of the @task, which is
904+
* not the fgraph's return_to_handler.
905+
*/
906+
unsigned long ftrace_graph_top_ret_addr(struct task_struct *task)
907+
{
908+
unsigned long return_handler = (unsigned long)dereference_kernel_function_descriptor(return_to_handler);
909+
struct ftrace_ret_stack *ret_stack = NULL;
910+
int offset = task->curr_ret_stack;
911+
912+
if (offset < 0)
913+
return 0;
914+
915+
do {
916+
ret_stack = get_ret_stack(task, offset, &offset);
917+
} while (ret_stack && ret_stack->ret == return_handler);
918+
919+
return ret_stack ? ret_stack->ret : 0;
920+
}
921+
908922
/**
909923
* ftrace_graph_ret_addr - return the original value of the return address
910924
* @task: The task the unwinder is being executed on
@@ -1145,8 +1159,7 @@ void ftrace_graph_exit_task(struct task_struct *t)
11451159

11461160
#ifdef CONFIG_DYNAMIC_FTRACE
11471161
static int fgraph_pid_func(struct ftrace_graph_ent *trace,
1148-
struct fgraph_ops *gops,
1149-
struct fgraph_extras *extras)
1162+
struct fgraph_ops *gops)
11501163
{
11511164
struct trace_array *tr = gops->ops.private;
11521165
int pid;
@@ -1160,7 +1173,7 @@ static int fgraph_pid_func(struct ftrace_graph_ent *trace,
11601173
return 0;
11611174
}
11621175

1163-
return gops->saved_func(trace, gops, NULL);
1176+
return gops->saved_func(trace, gops);
11641177
}
11651178

11661179
void fgraph_update_pid_func(void)

kernel/trace/ftrace.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,8 +827,7 @@ struct profile_fgraph_data {
827827
};
828828

829829
static int profile_graph_entry(struct ftrace_graph_ent *trace,
830-
struct fgraph_ops *gops,
831-
struct fgraph_extras *extras)
830+
struct fgraph_ops *gops)
832831
{
833832
struct profile_fgraph_data *profile_data;
834833

kernel/trace/trace.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -695,8 +695,7 @@ void trace_default_header(struct seq_file *m);
695695
void print_trace_header(struct seq_file *m, struct trace_iterator *iter);
696696

697697
void trace_graph_return(struct ftrace_graph_ret *trace, struct fgraph_ops *gops);
698-
int trace_graph_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
699-
struct fgraph_extras *extras);
698+
int trace_graph_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops);
700699

701700
void tracing_start_cmdline_record(void);
702701
void tracing_stop_cmdline_record(void);

kernel/trace/trace_functions_graph.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ static struct tracer_flags tracer_flags = {
9090
.opts = trace_opts
9191
};
9292

93-
u32 graph_tracer_flags_get(u32 flags)
93+
static bool tracer_flags_is_set(u32 flags)
9494
{
95-
return tracer_flags.val & flags;
95+
return (tracer_flags.val & flags) == flags;
9696
}
9797

9898
/*
@@ -179,8 +179,7 @@ struct fgraph_times {
179179
};
180180

181181
int trace_graph_entry(struct ftrace_graph_ent *trace,
182-
struct fgraph_ops *gops,
183-
struct fgraph_extras *extras)
182+
struct fgraph_ops *gops)
184183
{
185184
unsigned long *task_var = fgraph_get_task_var(gops);
186185
struct trace_array *tr = gops->private;
@@ -246,11 +245,12 @@ int trace_graph_entry(struct ftrace_graph_ent *trace,
246245
disabled = atomic_inc_return(&data->disabled);
247246
if (likely(disabled == 1)) {
248247
trace_ctx = tracing_gen_ctx_flags(flags);
249-
if (unlikely(IS_ENABLED(CONFIG_FUNCTION_GRAPH_RETADDR) && extras
250-
&& (extras->flags & TRACE_GRAPH_PRINT_RETADDR)))
251-
ret = __trace_graph_retaddr_entry(tr, trace, trace_ctx,
252-
extras->retaddr);
253-
else
248+
if (unlikely(IS_ENABLED(CONFIG_FUNCTION_GRAPH_RETADDR) &&
249+
tracer_flags_is_set(TRACE_GRAPH_PRINT_RETADDR))) {
250+
unsigned long retaddr = ftrace_graph_top_ret_addr(current);
251+
252+
ret = __trace_graph_retaddr_entry(tr, trace, trace_ctx, retaddr);
253+
} else
254254
ret = __trace_graph_entry(tr, trace, trace_ctx);
255255
} else {
256256
ret = 0;

kernel/trace/trace_irqsoff.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ static int irqsoff_display_graph(struct trace_array *tr, int set)
176176
}
177177

178178
static int irqsoff_graph_entry(struct ftrace_graph_ent *trace,
179-
struct fgraph_ops *gops,
180-
struct fgraph_extras *extras)
179+
struct fgraph_ops *gops)
181180
{
182181
struct trace_array *tr = irqsoff_trace;
183182
struct trace_array_cpu *data;

kernel/trace/trace_sched_wakeup.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ static int wakeup_display_graph(struct trace_array *tr, int set)
113113
}
114114

115115
static int wakeup_graph_entry(struct ftrace_graph_ent *trace,
116-
struct fgraph_ops *gops,
117-
struct fgraph_extras *extras)
116+
struct fgraph_ops *gops)
118117
{
119118
struct trace_array *tr = wakeup_trace;
120119
struct trace_array_cpu *data;

kernel/trace/trace_selftest.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -774,8 +774,7 @@ struct fgraph_fixture {
774774
};
775775

776776
static __init int store_entry(struct ftrace_graph_ent *trace,
777-
struct fgraph_ops *gops,
778-
struct fgraph_extras *extras)
777+
struct fgraph_ops *gops)
779778
{
780779
struct fgraph_fixture *fixture = container_of(gops, struct fgraph_fixture, gops);
781780
const char *type = fixture->store_type_name;
@@ -1026,8 +1025,7 @@ static unsigned int graph_hang_thresh;
10261025

10271026
/* Wrap the real function entry probe to avoid possible hanging */
10281027
static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace,
1029-
struct fgraph_ops *gops,
1030-
struct fgraph_extras *extras)
1028+
struct fgraph_ops *gops)
10311029
{
10321030
/* This is harmlessly racy, we want to approximately detect a hang */
10331031
if (unlikely(++graph_hang_thresh > GRAPH_MAX_FUNC_TEST)) {
@@ -1041,7 +1039,7 @@ static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace,
10411039
return 0;
10421040
}
10431041

1044-
return trace_graph_entry(trace, gops, NULL);
1042+
return trace_graph_entry(trace, gops);
10451043
}
10461044

10471045
static struct fgraph_ops fgraph_ops __initdata = {

0 commit comments

Comments
 (0)