From: Andrii Nakryiko <andrii.nakryiko@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>,
Daniel Borkmann <daniel@iogearbox.net>, bpf <bpf@vger.kernel.org>,
Kernel Team <kernel-team@fb.com>
Subject: Re: [PATCH v2 bpf-next 3/7] bpf: Add per-program recursion prevention mechanism
Date: Mon, 8 Feb 2021 12:51:14 -0800 [thread overview]
Message-ID: <CAEf4Bzb1D9AzOU2Zn2DkZrP+VYOPuJ-7xFcEF1unTr6SutMSWg@mail.gmail.com> (raw)
In-Reply-To: <20210206170344.78399-4-alexei.starovoitov@gmail.com>
On Sat, Feb 6, 2021 at 9:05 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> From: Alexei Starovoitov <ast@kernel.org>
>
> Since both sleepable and non-sleepable programs execute under migrate_disable
> add recursion prevention mechanism to both types of programs when they're
> executed via bpf trampoline.
>
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> ---
> arch/x86/net/bpf_jit_comp.c | 15 +++++++++++++
> include/linux/bpf.h | 6 ++---
> include/linux/filter.h | 1 +
> kernel/bpf/core.c | 8 +++++++
> kernel/bpf/trampoline.c | 22 ++++++++++++++-----
> .../selftests/bpf/prog_tests/fexit_stress.c | 2 +-
> .../bpf/prog_tests/trampoline_count.c | 4 ++--
> 7 files changed, 47 insertions(+), 11 deletions(-)
>
[...]
> diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> index b1f567514b7e..226f613ab289 100644
> --- a/kernel/bpf/trampoline.c
> +++ b/kernel/bpf/trampoline.c
> @@ -388,16 +388,21 @@ void bpf_trampoline_put(struct bpf_trampoline *tr)
> * call prog->bpf_func
> * call __bpf_prog_exit
> */
> -#define NO_START_TIME 0
> -u64 notrace __bpf_prog_enter(void)
> +#define NO_START_TIME 1
> +u64 notrace __bpf_prog_enter(struct bpf_prog *prog)
> __acquires(RCU)
> {
> u64 start = NO_START_TIME;
>
> rcu_read_lock();
> migrate_disable();
> - if (static_branch_unlikely(&bpf_stats_enabled_key))
> + if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1))
> + return 0;
> + if (static_branch_unlikely(&bpf_stats_enabled_key)) {
> start = sched_clock();
> + if (unlikely(!start))
> + start = NO_START_TIME;
> + }
> return start;
> }
>
> @@ -425,25 +430,32 @@ void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start)
> __releases(RCU)
> {
> update_prog_stats(prog, start);
> + __this_cpu_dec(*(prog->active));
> migrate_enable();
> rcu_read_unlock();
> }
>
> -u64 notrace __bpf_prog_enter_sleepable(void)
> +u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog)
> {
> u64 start = NO_START_TIME;
>
> rcu_read_lock_trace();
> migrate_disable();
> might_fault();
> - if (static_branch_unlikely(&bpf_stats_enabled_key))
> + if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1))
> + return 0;
> + if (static_branch_unlikely(&bpf_stats_enabled_key)) {
> start = sched_clock();
> + if (unlikely(!start))
> + start = NO_START_TIME;
> + }
> return start;
maybe extract this piece into a function, so that enter functions
would look like:
...
if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1))
return 0;
return bpf_prog_start_time();
no need for u64 start initialization, more linear code, and no
duplication of logic?
Oh, and actually, given you have `start > NO_START_TIME` condition in
exit function, you don't need this `if (unlikely(!start))` bit at all,
because you are going to ignore both 0 and 1. So maybe no need for a
new function, but no need for extra if as well.
> }
>
> void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start)
> {
> update_prog_stats(prog, start);
> + __this_cpu_dec(*(prog->active));
> migrate_enable();
> rcu_read_unlock_trace();
> }
> diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_stress.c b/tools/testing/selftests/bpf/prog_tests/fexit_stress.c
> index 3b9dbf7433f0..4698b0d2de36 100644
> --- a/tools/testing/selftests/bpf/prog_tests/fexit_stress.c
> +++ b/tools/testing/selftests/bpf/prog_tests/fexit_stress.c
> @@ -3,7 +3,7 @@
> #include <test_progs.h>
>
> /* x86-64 fits 55 JITed and 43 interpreted progs into half page */
Probably the comment is a bit outdated now forcing you to decrease CNT?
> -#define CNT 40
> +#define CNT 38
>
> void test_fexit_stress(void)
> {
> diff --git a/tools/testing/selftests/bpf/prog_tests/trampoline_count.c b/tools/testing/selftests/bpf/prog_tests/trampoline_count.c
> index 781c8d11604b..f3022d934e2d 100644
> --- a/tools/testing/selftests/bpf/prog_tests/trampoline_count.c
> +++ b/tools/testing/selftests/bpf/prog_tests/trampoline_count.c
> @@ -4,7 +4,7 @@
> #include <sys/prctl.h>
> #include <test_progs.h>
>
> -#define MAX_TRAMP_PROGS 40
> +#define MAX_TRAMP_PROGS 38
>
> struct inst {
> struct bpf_object *obj;
> @@ -52,7 +52,7 @@ void test_trampoline_count(void)
> struct bpf_link *link;
> char comm[16] = {};
>
> - /* attach 'allowed' 40 trampoline programs */
> + /* attach 'allowed' trampoline programs */
> for (i = 0; i < MAX_TRAMP_PROGS; i++) {
> obj = bpf_object__open_file(object, NULL);
> if (CHECK(IS_ERR(obj), "obj_open_file", "err %ld\n", PTR_ERR(obj))) {
> --
> 2.24.1
>
next prev parent reply other threads:[~2021-02-08 20:55 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-06 17:03 [PATCH v2 bpf-next 0/7] bpf: Misc improvements Alexei Starovoitov
2021-02-06 17:03 ` [PATCH v2 bpf-next 1/7] bpf: Optimize program stats Alexei Starovoitov
2021-02-08 18:57 ` Andrii Nakryiko
2021-02-08 21:28 ` Daniel Borkmann
2021-02-08 23:13 ` Alexei Starovoitov
2021-02-09 0:53 ` Daniel Borkmann
2021-02-06 17:03 ` [PATCH v2 bpf-next 2/7] bpf: Compute program stats for sleepable programs Alexei Starovoitov
2021-02-08 20:35 ` Andrii Nakryiko
2021-02-06 17:03 ` [PATCH v2 bpf-next 3/7] bpf: Add per-program recursion prevention mechanism Alexei Starovoitov
2021-02-08 20:51 ` Andrii Nakryiko [this message]
2021-02-09 19:06 ` Alexei Starovoitov
2021-02-09 19:15 ` Andrii Nakryiko
2021-02-06 17:03 ` [PATCH v2 bpf-next 4/7] selftest/bpf: Add a recursion test Alexei Starovoitov
2021-02-08 20:54 ` Andrii Nakryiko
2021-02-06 17:03 ` [PATCH v2 bpf-next 5/7] bpf: Count the number of times recursion was prevented Alexei Starovoitov
2021-02-08 20:58 ` Andrii Nakryiko
2021-02-06 17:03 ` [PATCH v2 bpf-next 6/7] bpf: Allows per-cpu maps and map-in-map in sleepable programs Alexei Starovoitov
2021-02-08 21:00 ` Andrii Nakryiko
2021-02-08 21:01 ` Andrii Nakryiko
2021-02-08 23:20 ` Alexei Starovoitov
2021-02-06 17:03 ` [PATCH v2 bpf-next 7/7] selftests/bpf: Add a test for map-in-map and per-cpu maps in sleepable progs Alexei Starovoitov
2021-02-08 21:04 ` Andrii Nakryiko
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=CAEf4Bzb1D9AzOU2Zn2DkZrP+VYOPuJ-7xFcEF1unTr6SutMSWg@mail.gmail.com \
--to=andrii.nakryiko@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=kernel-team@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).