bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Jiri Olsa <jolsa@redhat.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>,
	davem@davemloft.net, daniel@iogearbox.net, andrii@kernel.org,
	paulmck@kernel.org, bpf@vger.kernel.org, kernel-team@fb.com
Subject: Re: [PATCH bpf] bpf: Fix fexit trampoline.
Date: Tue, 23 Mar 2021 08:59:00 -0400	[thread overview]
Message-ID: <20210323085900.3bdc0002@gandalf.local.home> (raw)
In-Reply-To: <YFjnlqeqbkST7oPb@krava>

On Mon, 22 Mar 2021 19:53:10 +0100
Jiri Olsa <jolsa@redhat.com> wrote:

> On Mon, Mar 22, 2021 at 05:24:26PM +0100, Jiri Olsa wrote:
> > On Mon, Mar 22, 2021 at 12:32:05AM +0100, Jiri Olsa wrote:  
> > > On Tue, Mar 16, 2021 at 02:00:07PM -0700, Alexei Starovoitov wrote:  
> > > > From: Alexei Starovoitov <ast@kernel.org>
> > > > 
> > > > The fexit/fmod_ret programs can be attached to kernel functions that can sleep.
> > > > The synchronize_rcu_tasks() will not wait for such tasks to complete.
> > > > In such case the trampoline image will be freed and when the task
> > > > wakes up the return IP will point to freed memory causing the crash.
> > > > Solve this by adding percpu_ref_get/put for the duration of trampoline
> > > > and separate trampoline vs its image life times.
> > > > The "half page" optimization has to be removed, since
> > > > first_half->second_half->first_half transition cannot be guaranteed to
> > > > complete in deterministic time. Every trampoline update becomes a new image.
> > > > The image with fmod_ret or fexit progs will be freed via percpu_ref_kill and
> > > > call_rcu_tasks. Together they will wait for the original function and
> > > > trampoline asm to complete. The trampoline is patched from nop to jmp to skip
> > > > fexit progs. They are freed independently from the trampoline. The image with
> > > > fentry progs only will be freed via call_rcu_tasks_trace+call_rcu_tasks which
> > > > will wait for both sleepable and non-sleepable progs to complete.
> > > > 
> > > > Reported-by: Andrii Nakryiko <andrii@kernel.org>
> > > > Fixes: fec56f5890d9 ("bpf: Introduce BPF trampoline")
> > > > Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> > > > Acked-by: Paul E. McKenney <paulmck@kernel.org>  # for RCU
> > > > ---
> > > > Without ftrace fix:
> > > > https://patchwork.kernel.org/project/netdevbpf/patch/20210316195815.34714-1-alexei.starovoitov@gmail.com/
> > > > this patch will trigger warn in ftrace.
> > > > 
> > > >  arch/x86/net/bpf_jit_comp.c |  26 ++++-
> > > >  include/linux/bpf.h         |  24 +++-
> > > >  kernel/bpf/bpf_struct_ops.c |   2 +-
> > > >  kernel/bpf/core.c           |   4 +-
> > > >  kernel/bpf/trampoline.c     | 218 +++++++++++++++++++++++++++---------
> > > >  5 files changed, 213 insertions(+), 61 deletions(-)
> > > >   
> > > 
> > > hi,
> > > I'm on bpf/master and I'm triggering warnings below when running together:
> > > 
> > >   # while :; do ./test_progs -t fentry_test ; done
> > >   # while :; do ./test_progs -t module_attach ; done  
> > 
> > hum, is it possible that we don't take module ref and it can get
> > unloaded even if there's trampoline attach to it..? I can't see
> > that in the code.. ftrace_release_mod can't fail ;-)  
> 
> when I get the module for each module trampoline,
> I can no longer see those warnings (link for Steven):
>   https://lore.kernel.org/bpf/YFfXcqnksPsSe0Bv@krava/
> 
> Steven,
> I might be missing something, but it looks like module
> can be unloaded even if the trampoline (direct function)
> is registered in it.. is that right?
> 

Not with your patch below ;-)

But yes, ftrace does not currently manage module text for direct calls,
it's assumed that whoever attaches to the module text would do that. But
I'm not adverse to the patch below.

-- Steve


> thanks,
> jirka
> 
> 
> ---
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index b7e29db127fa..ab0b2c8df283 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -5059,6 +5059,28 @@ static struct ftrace_direct_func *ftrace_alloc_direct_func(unsigned long addr)
>  	return direct;
>  }
>  
> +static struct module *ftrace_direct_module_get(unsigned long ip)
> +{
> +	struct module *mod;
> +	int err = 0;
> +
> +	preempt_disable();
> +	mod = __module_text_address(ip);
> +	if (mod && !try_module_get(mod))
> +		err = -ENOENT;
> +	preempt_enable();
> +	return err ? ERR_PTR(err) : mod;
> +}
> +
> +static void ftrace_direct_module_put(unsigned long ip)
> +{
> +	struct module *mod;
> +
> +	mod = __module_text_address(ip);
> +	if (mod)
> +		module_put(mod);
> +}
> +
>  /**
>   * register_ftrace_direct - Call a custom trampoline directly
>   * @ip: The address of the nop at the beginning of a function
> @@ -5081,6 +5103,7 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
>  	struct ftrace_direct_func *direct;
>  	struct ftrace_func_entry *entry;
>  	struct ftrace_hash *free_hash = NULL;
> +	struct module *mod = NULL;
>  	struct dyn_ftrace *rec;
>  	int ret = -EBUSY;
>  
> @@ -5095,6 +5118,13 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
>  	if (!rec)
>  		goto out_unlock;
>  
> +	mod = ftrace_direct_module_get(ip);
> +	if (IS_ERR(mod)) {
> +		ret = -ENOENT;
> +		mod = NULL;
> +		goto out_unlock;
> +	}
> +
>  	/*
>  	 * Check if the rec says it has a direct call but we didn't
>  	 * find one earlier?
> @@ -5172,6 +5202,8 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
>   out_unlock:
>  	mutex_unlock(&direct_mutex);
>  
> +	if (ret)
> +		module_put(mod);
>  	if (free_hash) {
>  		synchronize_rcu_tasks();
>  		free_ftrace_hash(free_hash);
> @@ -5242,6 +5274,8 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
>  			ftrace_direct_func_count--;
>  		}
>  	}
> +	ftrace_direct_module_put(ip);
> +
>   out_unlock:
>  	mutex_unlock(&direct_mutex);
>  


  reply	other threads:[~2021-03-23 12:59 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-16 21:00 [PATCH bpf] bpf: Fix fexit trampoline Alexei Starovoitov
2021-03-17 23:30 ` patchwork-bot+netdevbpf
2021-03-21 23:32 ` Jiri Olsa
2021-03-22 16:24   ` Jiri Olsa
2021-03-22 18:53     ` Jiri Olsa
2021-03-23 12:59       ` Steven Rostedt [this message]
2021-03-23 14:50         ` Alexei Starovoitov
2021-03-23 20:59           ` 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=20210323085900.3bdc0002@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=jolsa@redhat.com \
    --cc=kernel-team@fb.com \
    --cc=paulmck@kernel.org \
    /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).