@@ -176,6 +176,27 @@ static void function_trace_start(struct trace_array *tr)
176176 tracing_reset_online_cpus (& tr -> array_buffer );
177177}
178178
179+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
180+ static __always_inline unsigned long
181+ function_get_true_parent_ip (unsigned long parent_ip , struct ftrace_regs * fregs )
182+ {
183+ unsigned long true_parent_ip ;
184+ int idx = 0 ;
185+
186+ true_parent_ip = parent_ip ;
187+ if (unlikely (parent_ip == (unsigned long )& return_to_handler ) && fregs )
188+ true_parent_ip = ftrace_graph_ret_addr (current , & idx , parent_ip ,
189+ (unsigned long * )ftrace_regs_get_stack_pointer (fregs ));
190+ return true_parent_ip ;
191+ }
192+ #else
193+ static __always_inline unsigned long
194+ function_get_true_parent_ip (unsigned long parent_ip , struct ftrace_regs * fregs )
195+ {
196+ return parent_ip ;
197+ }
198+ #endif
199+
179200static void
180201function_trace_call (unsigned long ip , unsigned long parent_ip ,
181202 struct ftrace_ops * op , struct ftrace_regs * fregs )
@@ -192,6 +213,8 @@ function_trace_call(unsigned long ip, unsigned long parent_ip,
192213 if (bit < 0 )
193214 return ;
194215
216+ parent_ip = function_get_true_parent_ip (parent_ip , fregs );
217+
195218 trace_ctx = tracing_gen_ctx ();
196219
197220 data = this_cpu_ptr (tr -> array_buffer .data );
@@ -239,6 +262,7 @@ function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
239262 * recursive protection is performed.
240263 */
241264 local_irq_save (flags );
265+ parent_ip = function_get_true_parent_ip (parent_ip , fregs );
242266 cpu = raw_smp_processor_id ();
243267 data = per_cpu_ptr (tr -> array_buffer .data , cpu );
244268 disabled = atomic_inc_return (& data -> disabled );
@@ -306,6 +330,7 @@ function_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip,
306330 if (bit < 0 )
307331 return ;
308332
333+ parent_ip = function_get_true_parent_ip (parent_ip , fregs );
309334 data = this_cpu_ptr (tr -> array_buffer .data );
310335 if (atomic_read (& data -> disabled ))
311336 goto out ;
@@ -352,6 +377,7 @@ function_stack_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip,
352377 * recursive protection is performed.
353378 */
354379 local_irq_save (flags );
380+ parent_ip = function_get_true_parent_ip (parent_ip , fregs );
355381 cpu = raw_smp_processor_id ();
356382 data = per_cpu_ptr (tr -> array_buffer .data , cpu );
357383 disabled = atomic_inc_return (& data -> disabled );
0 commit comments