• Masami Hiramatsu (Google)'s avatar
    ftrace: Fix DIRECT_CALLS to use SAVE_REGS by default · a8b9cf62
    Masami Hiramatsu (Google) authored
    The commit 60c89718 ("ftrace: Make DIRECT_CALLS work WITH_ARGS
    and !WITH_REGS") changed DIRECT_CALLS to use SAVE_ARGS when there
    are multiple ftrace_ops at the same function, but since the x86 only
    support to jump to direct_call from ftrace_regs_caller, when we set
    the function tracer on the same target function on x86, ftrace-direct
    does not work as below (this actually works on arm64.)
    
    At first, insmod ftrace-direct.ko to put a direct_call on
    'wake_up_process()'.
    
     # insmod kernel/samples/ftrace/ftrace-direct.ko
     # less trace
    ...
              <idle>-0       [006] ..s1.   564.686958: my_direct_func: waking up rcu_preempt-17
              <idle>-0       [007] ..s1.   564.687836: my_direct_func: waking up kcompactd0-63
              <idle>-0       [006] ..s1.   564.690926: my_direct_func: waking up rcu_preempt-17
              <idle>-0       [006] ..s1.   564.696872: my_direct_func: waking up rcu_preempt-17
              <idle>-0       [007] ..s1.   565.191982: my_direct_func: waking up kcompactd0-63
    
    Setup a function filter to the 'wake_up_process' too, and enable it.
    
     # cd /sys/kernel/tracing/
     # echo wake_up_process > set_ftrace_filter
     # echo function > current_tracer
     # less trace
    ...
              <idle>-0       [006] ..s3.   686.180972: wake_up_process <-call_timer_fn
              <idle>-0       [006] ..s3.   686.186919: wake_up_process <-call_timer_fn
              <idle>-0       [002] ..s3.   686.264049: wake_up_process <-call_timer_fn
              <idle>-0       [002] d.h6.   686.515216: wake_up_process <-kick_pool
              <idle>-0       [002] d.h6.   686.691386: wake_up_process <-kick_pool
    
    Then, only function tracer is shown on x86.
    But if you enable 'kprobe on ftrace' event (which uses SAVE_REGS flag)
    on the same function, it is shown again.
    
     # echo 'p wake_up_process' >> dynamic_events
     # echo 1 > events/kprobes/p_wake_up_process_0/enable
     # echo > trace
     # less trace
    ...
              <idle>-0       [006] ..s2.  2710.345919: p_wake_up_process_0: (wake_up_process+0x4/0x20)
              <idle>-0       [006] ..s3.  2710.345923: wake_up_process <-call_timer_fn
              <idle>-0       [006] ..s1.  2710.345928: my_direct_func: waking up rcu_preempt-17
              <idle>-0       [006] ..s2.  2710.349931: p_wake_up_process_0: (wake_up_process+0x4/0x20)
              <idle>-0       [006] ..s3.  2710.349934: wake_up_process <-call_timer_fn
              <idle>-0       [006] ..s1.  2710.349937: my_direct_func: waking up rcu_preempt-17
    
    To fix this issue, use SAVE_REGS flag for multiple ftrace_ops flag of
    direct_call by default.
    
    Link: https://lore.kernel.org/linux-trace-kernel/170484558617.178953.1590516949390270842.stgit@devnote2
    
    Fixes: 60c89718 ("ftrace: Make DIRECT_CALLS work WITH_ARGS and !WITH_REGS")
    Cc: stable@vger.kernel.org
    Cc: Florent Revest <revest@chromium.org>
    Signed-off-by: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
    Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
    Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64]
    Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
    Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
    a8b9cf62
ftrace.c 196 KB