Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fgraph: Pass ftrace_regs to retfunc

Pass ftrace_regs to the fgraph_ops::retfunc(). If ftrace_regs is not
available, it passes a NULL instead. User callback function can access
some registers (including return address) via this ftrace_regs.

Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Florent Revest <revest@chromium.org>
Cc: Martin KaFai Lau <martin.lau@linux.dev>
Cc: bpf <bpf@vger.kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Alan Maguire <alan.maguire@oracle.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/173518992972.391279.14055405490327765506.stgit@devnote2
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Masami Hiramatsu (Google) and committed by
Steven Rostedt (Google)
2ca8c112 a3ed4157

+27 -14
+2 -1
include/linux/ftrace.h
··· 1075 1075 1076 1076 /* Type of the callback handlers for tracing function graph*/ 1077 1077 typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *, 1078 - struct fgraph_ops *); /* return */ 1078 + struct fgraph_ops *, 1079 + struct ftrace_regs *); /* return */ 1079 1080 typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *, 1080 1081 struct fgraph_ops *, 1081 1082 struct ftrace_regs *); /* entry */
+11 -5
kernel/trace/fgraph.c
··· 299 299 } 300 300 301 301 /* ftrace_graph_return set to this to tell some archs to run function graph */ 302 - static void return_run(struct ftrace_graph_ret *trace, struct fgraph_ops *ops) 302 + static void return_run(struct ftrace_graph_ret *trace, struct fgraph_ops *ops, 303 + struct ftrace_regs *fregs) 303 304 { 304 305 } 305 306 ··· 529 528 } 530 529 531 530 static void ftrace_graph_ret_stub(struct ftrace_graph_ret *trace, 532 - struct fgraph_ops *gops) 531 + struct fgraph_ops *gops, 532 + struct ftrace_regs *fregs) 533 533 { 534 534 } 535 535 ··· 827 825 } 828 826 829 827 trace.rettime = trace_clock_local(); 828 + if (fregs) 829 + ftrace_regs_set_instruction_pointer(fregs, ret); 830 + 830 831 #ifdef CONFIG_FUNCTION_GRAPH_RETVAL 831 832 trace.retval = ftrace_regs_get_return_value(fregs); 832 833 #endif ··· 839 834 #ifdef CONFIG_HAVE_STATIC_CALL 840 835 if (static_branch_likely(&fgraph_do_direct)) { 841 836 if (test_bit(fgraph_direct_gops->idx, &bitmap)) 842 - static_call(fgraph_retfunc)(&trace, fgraph_direct_gops); 837 + static_call(fgraph_retfunc)(&trace, fgraph_direct_gops, fregs); 843 838 } else 844 839 #endif 845 840 { ··· 849 844 if (gops == &fgraph_stub) 850 845 continue; 851 846 852 - gops->retfunc(&trace, gops); 847 + gops->retfunc(&trace, gops, fregs); 853 848 } 854 849 } 855 850 ··· 1021 1016 * Simply points to ftrace_stub, but with the proper protocol. 1022 1017 * Defined by the linker script in linux/vmlinux.lds.h 1023 1018 */ 1024 - void ftrace_stub_graph(struct ftrace_graph_ret *trace, struct fgraph_ops *gops); 1019 + void ftrace_stub_graph(struct ftrace_graph_ret *trace, struct fgraph_ops *gops, 1020 + struct ftrace_regs *fregs); 1025 1021 1026 1022 /* The callbacks that hook a function */ 1027 1023 trace_func_graph_ret_t ftrace_graph_return = ftrace_stub_graph;
+2 -1
kernel/trace/ftrace.c
··· 842 842 } 843 843 844 844 static void profile_graph_return(struct ftrace_graph_ret *trace, 845 - struct fgraph_ops *gops) 845 + struct fgraph_ops *gops, 846 + struct ftrace_regs *fregs) 846 847 { 847 848 struct profile_fgraph_data *profile_data; 848 849 struct ftrace_profile_stat *stat;
+2 -1
kernel/trace/trace.h
··· 693 693 void trace_default_header(struct seq_file *m); 694 694 void print_trace_header(struct seq_file *m, struct trace_iterator *iter); 695 695 696 - void trace_graph_return(struct ftrace_graph_ret *trace, struct fgraph_ops *gops); 696 + void trace_graph_return(struct ftrace_graph_ret *trace, struct fgraph_ops *gops, 697 + struct ftrace_regs *fregs); 697 698 int trace_graph_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops, 698 699 struct ftrace_regs *fregs); 699 700
+4 -3
kernel/trace/trace_functions_graph.c
··· 310 310 } 311 311 312 312 void trace_graph_return(struct ftrace_graph_ret *trace, 313 - struct fgraph_ops *gops) 313 + struct fgraph_ops *gops, struct ftrace_regs *fregs) 314 314 { 315 315 unsigned long *task_var = fgraph_get_task_var(gops); 316 316 struct trace_array *tr = gops->private; ··· 348 348 } 349 349 350 350 static void trace_graph_thresh_return(struct ftrace_graph_ret *trace, 351 - struct fgraph_ops *gops) 351 + struct fgraph_ops *gops, 352 + struct ftrace_regs *fregs) 352 353 { 353 354 struct fgraph_times *ftimes; 354 355 int size; ··· 373 372 (trace->rettime - ftimes->calltime < tracing_thresh)) 374 373 return; 375 374 else 376 - trace_graph_return(trace, gops); 375 + trace_graph_return(trace, gops, fregs); 377 376 } 378 377 379 378 static struct fgraph_ops funcgraph_ops = {
+2 -1
kernel/trace/trace_irqsoff.c
··· 208 208 } 209 209 210 210 static void irqsoff_graph_return(struct ftrace_graph_ret *trace, 211 - struct fgraph_ops *gops) 211 + struct fgraph_ops *gops, 212 + struct ftrace_regs *fregs) 212 213 { 213 214 struct trace_array *tr = irqsoff_trace; 214 215 struct trace_array_cpu *data;
+2 -1
kernel/trace/trace_sched_wakeup.c
··· 144 144 } 145 145 146 146 static void wakeup_graph_return(struct ftrace_graph_ret *trace, 147 - struct fgraph_ops *gops) 147 + struct fgraph_ops *gops, 148 + struct ftrace_regs *fregs) 148 149 { 149 150 struct trace_array *tr = wakeup_trace; 150 151 struct trace_array_cpu *data;
+2 -1
kernel/trace/trace_selftest.c
··· 808 808 } 809 809 810 810 static __init void store_return(struct ftrace_graph_ret *trace, 811 - struct fgraph_ops *gops) 811 + struct fgraph_ops *gops, 812 + struct ftrace_regs *fregs) 812 813 { 813 814 struct fgraph_fixture *fixture = container_of(gops, struct fgraph_fixture, gops); 814 815 const char *type = fixture->store_type_name;