From: Jiri Olsa <jolsa@redhat.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>,
Steven Rostedt <rostedt@goodmis.org>
Cc: 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: Mon, 22 Mar 2021 19:53:10 +0100 [thread overview]
Message-ID: <YFjnlqeqbkST7oPb@krava> (raw)
In-Reply-To: <YFjEt42mrWejbzgJ@krava>
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?
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);
next prev parent reply other threads:[~2021-03-22 18:54 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 [this message]
2021-03-23 12:59 ` Steven Rostedt
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=YFjnlqeqbkST7oPb@krava \
--to=jolsa@redhat.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=kernel-team@fb.com \
--cc=paulmck@kernel.org \
--cc=rostedt@goodmis.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).