netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrii Nakryiko <andrii.nakryiko@gmail.com>
To: Jiri Olsa <jolsa@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andriin@fb.com>,
	"Steven Rostedt (VMware)" <rostedt@goodmis.org>,
	Networking <netdev@vger.kernel.org>, bpf <bpf@vger.kernel.org>,
	Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
	Yonghong Song <yhs@fb.com>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@chromium.org>, Daniel Xu <dxu@dxuuu.xyz>,
	Viktor Malik <vmalik@redhat.com>
Subject: Re: [PATCH 03/19] x86/ftrace: Make function graph use ftrace directly
Date: Tue, 8 Jun 2021 11:35:58 -0700	[thread overview]
Message-ID: <CAEf4BzY5ngJz_=e2wnqG7yB996xdQAPCBfz3_4mB9P2N-1RoCw@mail.gmail.com> (raw)
In-Reply-To: <20210605111034.1810858-4-jolsa@kernel.org>

On Sat, Jun 5, 2021 at 4:12 AM Jiri Olsa <jolsa@kernel.org> wrote:
>
> From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
>
> We don't need special hook for graph tracer entry point,
> but instead we can use graph_ops::func function to install
> the return_hooker.
>
> This moves the graph tracing setup _before_ the direct
> trampoline prepares the stack, so the return_hooker will
> be called when the direct trampoline is finished.
>
> This simplifies the code, because we don't need to take into
> account the direct trampoline setup when preparing the graph
> tracer hooker and we can allow function graph tracer on entries
> registered with direct trampoline.
>
> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  arch/x86/include/asm/ftrace.h |  9 +++++++--
>  arch/x86/kernel/ftrace.c      | 37 ++++++++++++++++++++++++++++++++---
>  arch/x86/kernel/ftrace_64.S   | 29 +--------------------------
>  include/linux/ftrace.h        |  6 ++++++
>  kernel/trace/fgraph.c         |  8 +++++---
>  5 files changed, 53 insertions(+), 36 deletions(-)
>
> diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
> index 9f3130f40807..024d9797646e 100644
> --- a/arch/x86/include/asm/ftrace.h
> +++ b/arch/x86/include/asm/ftrace.h
> @@ -57,6 +57,13 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs)
>
>  #define ftrace_instruction_pointer_set(fregs, _ip)     \
>         do { (fregs)->regs.ip = (_ip); } while (0)
> +
> +struct ftrace_ops;
> +#define ftrace_graph_func ftrace_graph_func
> +void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
> +                      struct ftrace_ops *op, struct ftrace_regs *fregs);
> +#else
> +#define FTRACE_GRAPH_TRAMP_ADDR FTRACE_GRAPH_ADDR
>  #endif
>
>  #ifdef CONFIG_DYNAMIC_FTRACE
> @@ -65,8 +72,6 @@ struct dyn_arch_ftrace {
>         /* No extra data needed for x86 */
>  };
>
> -#define FTRACE_GRAPH_TRAMP_ADDR FTRACE_GRAPH_ADDR
> -
>  #endif /*  CONFIG_DYNAMIC_FTRACE */
>  #endif /* __ASSEMBLY__ */
>  #endif /* CONFIG_FUNCTION_TRACER */
> diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
> index c555624da989..804fcc6ef2c7 100644
> --- a/arch/x86/kernel/ftrace.c
> +++ b/arch/x86/kernel/ftrace.c
> @@ -527,7 +527,7 @@ static void *addr_from_call(void *ptr)
>         return ptr + CALL_INSN_SIZE + call.disp;
>  }
>
> -void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
> +void prepare_ftrace_return(unsigned long ip, unsigned long *parent,
>                            unsigned long frame_pointer);
>
>  /*
> @@ -541,7 +541,8 @@ static void *static_tramp_func(struct ftrace_ops *ops, struct dyn_ftrace *rec)
>         void *ptr;
>
>         if (ops && ops->trampoline) {
> -#ifdef CONFIG_FUNCTION_GRAPH_TRACER
> +#if !defined(CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS) && \
> +       defined(CONFIG_FUNCTION_GRAPH_TRACER)
>                 /*
>                  * We only know about function graph tracer setting as static
>                  * trampoline.
> @@ -589,8 +590,9 @@ void arch_ftrace_trampoline_free(struct ftrace_ops *ops)
>  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
>
>  #ifdef CONFIG_DYNAMIC_FTRACE
> -extern void ftrace_graph_call(void);
>
> +#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
> +extern void ftrace_graph_call(void);
>  static const char *ftrace_jmp_replace(unsigned long ip, unsigned long addr)
>  {
>         return text_gen_insn(JMP32_INSN_OPCODE, (void *)ip, (void *)addr);
> @@ -618,7 +620,17 @@ int ftrace_disable_ftrace_graph_caller(void)
>
>         return ftrace_mod_jmp(ip, &ftrace_stub);
>  }
> +#else /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */
> +int ftrace_enable_ftrace_graph_caller(void)
> +{
> +       return 0;
> +}
>
> +int ftrace_disable_ftrace_graph_caller(void)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */
>  #endif /* !CONFIG_DYNAMIC_FTRACE */
>
>  /*
> @@ -629,6 +641,7 @@ void prepare_ftrace_return(unsigned long ip, unsigned long *parent,
>                            unsigned long frame_pointer)
>  {
>         unsigned long return_hooker = (unsigned long)&return_to_handler;
> +       int bit;
>
>         /*
>          * When resuming from suspend-to-ram, this function can be indirectly
> @@ -648,7 +661,25 @@ void prepare_ftrace_return(unsigned long ip, unsigned long *parent,
>         if (unlikely(atomic_read(&current->tracing_graph_pause)))
>                 return;
>
> +       bit = ftrace_test_recursion_trylock(ip, *parent);
> +       if (bit < 0)
> +               return;
> +
>         if (!function_graph_enter(*parent, ip, frame_pointer, parent))
>                 *parent = return_hooker;
> +
> +       ftrace_test_recursion_unlock(bit);
> +}
> +
> +#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
> +void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
> +                      struct ftrace_ops *op, struct ftrace_regs *fregs)
> +{
> +       struct pt_regs *regs = &fregs->regs;
> +       unsigned long *stack = (unsigned long *)kernel_stack_pointer(regs);
> +
> +       prepare_ftrace_return(ip, (unsigned long *)stack, 0);
>  }
> +#endif
> +
>  #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
> diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S
> index a8eb084a7a9a..7a879901f103 100644
> --- a/arch/x86/kernel/ftrace_64.S
> +++ b/arch/x86/kernel/ftrace_64.S
> @@ -174,11 +174,6 @@ SYM_INNER_LABEL(ftrace_caller_end, SYM_L_GLOBAL)
>  SYM_FUNC_END(ftrace_caller);
>
>  SYM_FUNC_START(ftrace_epilogue)
> -#ifdef CONFIG_FUNCTION_GRAPH_TRACER
> -SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
> -       jmp ftrace_stub
> -#endif
> -
>  /*
>   * This is weak to keep gas from relaxing the jumps.
>   * It is also used to copy the retq for trampolines.
> @@ -288,15 +283,6 @@ SYM_FUNC_START(__fentry__)
>         cmpq $ftrace_stub, ftrace_trace_function
>         jnz trace
>
> -fgraph_trace:
> -#ifdef CONFIG_FUNCTION_GRAPH_TRACER
> -       cmpq $ftrace_stub, ftrace_graph_return
> -       jnz ftrace_graph_caller
> -
> -       cmpq $ftrace_graph_entry_stub, ftrace_graph_entry
> -       jnz ftrace_graph_caller
> -#endif
> -
>  SYM_INNER_LABEL(ftrace_stub, SYM_L_GLOBAL)
>         retq
>
> @@ -314,25 +300,12 @@ trace:
>         CALL_NOSPEC r8
>         restore_mcount_regs
>
> -       jmp fgraph_trace
> +       jmp ftrace_stub
>  SYM_FUNC_END(__fentry__)
>  EXPORT_SYMBOL(__fentry__)
>  #endif /* CONFIG_DYNAMIC_FTRACE */
>
>  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
> -SYM_FUNC_START(ftrace_graph_caller)
> -       /* Saves rbp into %rdx and fills first parameter  */
> -       save_mcount_regs
> -
> -       leaq MCOUNT_REG_SIZE+8(%rsp), %rsi
> -       movq $0, %rdx   /* No framepointers needed */
> -       call    prepare_ftrace_return
> -
> -       restore_mcount_regs
> -
> -       retq
> -SYM_FUNC_END(ftrace_graph_caller)
> -
>  SYM_FUNC_START(return_to_handler)
>         subq  $24, %rsp
>
> diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> index a69f363b61bf..40b493908f09 100644
> --- a/include/linux/ftrace.h
> +++ b/include/linux/ftrace.h
> @@ -614,6 +614,12 @@ void ftrace_modify_all_code(int command);
>  extern void ftrace_graph_caller(void);
>  extern int ftrace_enable_ftrace_graph_caller(void);
>  extern int ftrace_disable_ftrace_graph_caller(void);
> +#ifndef ftrace_graph_func
> +#define ftrace_graph_func ftrace_stub
> +#define FTRACE_OPS_GRAPH_STUB | FTRACE_OPS_FL_STUB
> +#else
> +#define FTRACE_OPS_GRAPH_STUB
> +#endif
>  #else
>  static inline int ftrace_enable_ftrace_graph_caller(void) { return 0; }
>  static inline int ftrace_disable_ftrace_graph_caller(void) { return 0; }
> diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
> index b8a0d1d564fb..58e96b45e9da 100644
> --- a/kernel/trace/fgraph.c
> +++ b/kernel/trace/fgraph.c
> @@ -115,6 +115,7 @@ int function_graph_enter(unsigned long ret, unsigned long func,
>  {
>         struct ftrace_graph_ent trace;
>
> +#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
>         /*
>          * Skip graph tracing if the return location is served by direct trampoline,
>          * since call sequence and return addresses are unpredictable anyway.
> @@ -124,6 +125,7 @@ int function_graph_enter(unsigned long ret, unsigned long func,
>         if (ftrace_direct_func_count &&
>             ftrace_find_rec_direct(ret - MCOUNT_INSN_SIZE))
>                 return -EBUSY;
> +#endif
>         trace.func = func;
>         trace.depth = ++current->curr_ret_depth;
>
> @@ -333,10 +335,10 @@ unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
>  #endif /* HAVE_FUNCTION_GRAPH_RET_ADDR_PTR */
>
>  static struct ftrace_ops graph_ops = {
> -       .func                   = ftrace_stub,
> +       .func                   = ftrace_graph_func,
>         .flags                  = FTRACE_OPS_FL_INITIALIZED |
> -                                  FTRACE_OPS_FL_PID |
> -                                  FTRACE_OPS_FL_STUB,
> +                                  FTRACE_OPS_FL_PID
> +                                  FTRACE_OPS_GRAPH_STUB,

nit: this looks so weird... Why not define FTRACE_OPS_GRAPH_STUB as
zero in case of #ifdef ftrace_graph_func? Then it will be natural and
correctly looking | FTRACE_OPS_GRAPH_STUB?

>  #ifdef FTRACE_GRAPH_TRAMP_ADDR
>         .trampoline             = FTRACE_GRAPH_TRAMP_ADDR,
>         /* trampoline_size is only needed for dynamically allocated tramps */
> --
> 2.31.1
>

  reply	other threads:[~2021-06-08 18:38 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-05 11:10 [RFCv3 00/19] x86/ftrace/bpf: Add batch support for direct/tracing attach Jiri Olsa
2021-06-05 11:10 ` [PATCH 01/19] x86/ftrace: Remove extra orig rax move Jiri Olsa
2021-06-05 11:10 ` [PATCH 02/19] x86/ftrace: Remove fault protection code in prepare_ftrace_return Jiri Olsa
2021-06-05 11:10 ` [PATCH 03/19] x86/ftrace: Make function graph use ftrace directly Jiri Olsa
2021-06-08 18:35   ` Andrii Nakryiko [this message]
2021-06-08 18:51     ` Jiri Olsa
2021-06-08 19:11       ` Steven Rostedt
2021-06-05 11:10 ` [PATCH 04/19] tracing: Add trampoline/graph selftest Jiri Olsa
2021-06-05 11:10 ` [PATCH 05/19] ftrace: Add ftrace_add_rec_direct function Jiri Olsa
2021-06-05 11:10 ` [PATCH 06/19] ftrace: Add multi direct register/unregister interface Jiri Olsa
2021-06-05 11:10 ` [PATCH 07/19] ftrace: Add multi direct modify interface Jiri Olsa
2021-06-05 11:10 ` [PATCH 08/19] ftrace/samples: Add multi direct interface test module Jiri Olsa
2021-06-05 11:10 ` [PATCH 09/19] bpf, x64: Allow to use caller address from stack Jiri Olsa
2021-06-07  3:07   ` Yonghong Song
2021-06-07 18:13     ` Jiri Olsa
2021-06-05 11:10 ` [PATCH 10/19] bpf: Allow to store caller's ip as argument Jiri Olsa
2021-06-07  3:21   ` Yonghong Song
2021-06-07 18:15     ` Jiri Olsa
2021-06-08 18:49   ` Andrii Nakryiko
2021-06-08 20:58     ` Jiri Olsa
2021-06-08 21:02       ` Andrii Nakryiko
2021-06-08 21:11         ` Jiri Olsa
2021-06-05 11:10 ` [PATCH 11/19] bpf: Add support to load multi func tracing program Jiri Olsa
2021-06-07  3:56   ` Yonghong Song
2021-06-07 18:18     ` Jiri Olsa
2021-06-07 19:35       ` Yonghong Song
2021-06-05 11:10 ` [PATCH 12/19] bpf: Add bpf_trampoline_alloc function Jiri Olsa
2021-06-05 11:10 ` [PATCH 13/19] bpf: Add support to link multi func tracing program Jiri Olsa
2021-06-07  5:36   ` Yonghong Song
2021-06-07 18:25     ` Jiri Olsa
2021-06-07 19:39       ` Yonghong Song
2021-06-08 15:42   ` Alexei Starovoitov
2021-06-08 18:17     ` Jiri Olsa
2021-06-08 18:49       ` Alexei Starovoitov
2021-06-08 21:07         ` Jiri Olsa
2021-06-08 23:05           ` Alexei Starovoitov
2021-06-09  5:08             ` Andrii Nakryiko
2021-06-09 13:42               ` Jiri Olsa
2021-06-09 13:33             ` Jiri Olsa
2021-06-09  5:18   ` Andrii Nakryiko
2021-06-09 13:53     ` Jiri Olsa
2021-06-05 11:10 ` [PATCH 14/19] libbpf: Add btf__find_by_pattern_kind function Jiri Olsa
2021-06-09  5:29   ` Andrii Nakryiko
2021-06-09 13:59     ` Jiri Olsa
2021-06-09 14:19       ` Jiri Olsa
2021-06-05 11:10 ` [PATCH 15/19] libbpf: Add support to link multi func tracing program Jiri Olsa
2021-06-07  5:49   ` Yonghong Song
2021-06-07 18:28     ` Jiri Olsa
2021-06-07 19:42       ` Yonghong Song
2021-06-07 20:11         ` Jiri Olsa
2021-06-09  5:34   ` Andrii Nakryiko
2021-06-09 14:17     ` Jiri Olsa
2021-06-10 17:05       ` Andrii Nakryiko
2021-06-10 20:35         ` Jiri Olsa
2021-06-05 11:10 ` [PATCH 16/19] selftests/bpf: Add fentry multi func test Jiri Olsa
2021-06-07  6:06   ` Yonghong Song
2021-06-07 18:42     ` Jiri Olsa
2021-06-09  5:40   ` Andrii Nakryiko
2021-06-09 14:29     ` Jiri Olsa
2021-06-10 17:00       ` Andrii Nakryiko
2021-06-10 20:28         ` Jiri Olsa
2021-06-05 11:10 ` [PATCH 17/19] selftests/bpf: Add fexit " Jiri Olsa
2021-06-05 11:10 ` [PATCH 18/19] selftests/bpf: Add fentry/fexit " Jiri Olsa
2021-06-09  5:41   ` Andrii Nakryiko
2021-06-09 14:29     ` Jiri Olsa
2021-06-05 11:10 ` [PATCH 19/19] selftests/bpf: Temporary fix for fentry_fexit_multi_test Jiri Olsa
2021-06-17 20:29 ` [RFCv3 00/19] x86/ftrace/bpf: Add batch support for direct/tracing attach Andrii Nakryiko
2021-06-19  8:33   ` Jiri Olsa
2021-06-19 16:19     ` Yonghong Song
2021-06-19 17:09       ` Jiri Olsa
2021-06-20 16:56         ` Yonghong Song
2021-06-20 17:47           ` Alexei Starovoitov
2021-06-21  6:46             ` Andrii Nakryiko
2021-06-21  6:50     ` Andrii Nakryiko
2021-07-06 20:26       ` Andrii Nakryiko
2021-07-07 15:19         ` Jiri Olsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAEf4BzY5ngJz_=e2wnqG7yB996xdQAPCBfz3_4mB9P2N-1RoCw@mail.gmail.com' \
    --to=andrii.nakryiko@gmail.com \
    --cc=andriin@fb.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dxu@dxuuu.xyz \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kafai@fb.com \
    --cc=kpsingh@chromium.org \
    --cc=netdev@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=songliubraving@fb.com \
    --cc=vmalik@redhat.com \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).