From: Jiri Olsa <jolsa@redhat.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Networking <netdev@vger.kernel.org>, bpf <bpf@vger.kernel.org>,
lkml <linux-kernel@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>,
Steven Rostedt <rostedt@goodmis.org>,
Jiri Olsa <olsajiri@gmail.com>
Subject: Re: [PATCH 3/8] bpf: Add bpf_cookie support to fprobe
Date: Tue, 8 Feb 2022 10:07:39 +0100 [thread overview]
Message-ID: <YgIy2yCzbNmKPoxv@krava> (raw)
In-Reply-To: <CAEf4BzbPeQbURZOD93TgPudOk3JD4odsZ9uwriNkrphes9V4dg@mail.gmail.com>
On Mon, Feb 07, 2022 at 10:59:21AM -0800, Andrii Nakryiko wrote:
> On Wed, Feb 2, 2022 at 5:54 AM Jiri Olsa <jolsa@redhat.com> wrote:
> >
> > Adding support to call bpf_get_attach_cookie helper from
> > kprobe program attached by fprobe link.
> >
> > The bpf_cookie is provided by array of u64 values, where
> > each value is paired with provided function address with
> > the same array index.
> >
> > Suggested-by: Andrii Nakryiko <andrii@kernel.org>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> > include/linux/bpf.h | 2 +
> > include/uapi/linux/bpf.h | 1 +
> > kernel/bpf/syscall.c | 83 +++++++++++++++++++++++++++++++++-
> > kernel/trace/bpf_trace.c | 16 ++++++-
> > tools/include/uapi/linux/bpf.h | 1 +
> > 5 files changed, 100 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> > index 6eb0b180d33b..7b65f05c0487 100644
> > --- a/include/linux/bpf.h
> > +++ b/include/linux/bpf.h
> > @@ -1301,6 +1301,8 @@ static inline void bpf_reset_run_ctx(struct bpf_run_ctx *old_ctx)
> > #endif
> > }
> >
> > +u64 bpf_fprobe_cookie(struct bpf_run_ctx *ctx, u64 ip);
> > +
> > /* BPF program asks to bypass CAP_NET_BIND_SERVICE in bind. */
> > #define BPF_RET_BIND_NO_CAP_NET_BIND_SERVICE (1 << 0)
> > /* BPF program asks to set CN on the packet. */
> > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> > index c0912f0a3dfe..0dc6aa4f9683 100644
> > --- a/include/uapi/linux/bpf.h
> > +++ b/include/uapi/linux/bpf.h
> > @@ -1484,6 +1484,7 @@ union bpf_attr {
> > __aligned_u64 addrs;
> > __u32 cnt;
> > __u32 flags;
> > + __aligned_u64 bpf_cookies;
>
> maybe put it right after addrs, they are closely related and cnt
> describes all of syms/addrs/cookies.
ok
>
> > } fprobe;
> > };
> > } link_create;
> > diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> > index 0cfbb112c8e1..6c5e74bc43b6 100644
> > --- a/kernel/bpf/syscall.c
> > +++ b/kernel/bpf/syscall.c
> > @@ -33,6 +33,8 @@
> > #include <linux/rcupdate_trace.h>
> > #include <linux/memcontrol.h>
> > #include <linux/fprobe.h>
> > +#include <linux/bsearch.h>
> > +#include <linux/sort.h>
> >
> > #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
> > (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
> > @@ -3025,10 +3027,18 @@ static int bpf_perf_link_attach(const union bpf_attr *attr, struct bpf_prog *pro
> >
> > #ifdef CONFIG_FPROBE
> >
> > +struct bpf_fprobe_cookie {
> > + unsigned long addr;
> > + u64 bpf_cookie;
> > +};
> > +
> > struct bpf_fprobe_link {
> > struct bpf_link link;
> > struct fprobe fp;
> > unsigned long *addrs;
> > + struct bpf_run_ctx run_ctx;
> > + struct bpf_fprobe_cookie *bpf_cookies;
>
> you already have all the addrs above, why keeping a second copy of
> each addrs in bpf_fprobe_cookie. Let's have two arrays: addrs
> (unsigned long) and cookies (u64) and make sure that they are sorted
> together. Then lookup addrs, calculate index, use that index to fetch
> cookie.
>
> Seems like sort_r() provides exactly the interface you'd need to do
> this very easily. Having addrs separate from cookies also a bit
> advantageous in terms of TLB misses (if you need any more persuasion
> ;)
no persuation needed, I actually tried that but it turned out sort_r
is not ready yet ;-)
because you can't pass priv pointer to the swap callback, so we can't
swap the other array.. I did a change to allow that, but it's not trivial
and will need some bigger testing/review because the original sort
calls sort_r, and of course there are many 'sort' users ;-)
>
> > + u32 cnt;
> > };
> >
> > static void bpf_fprobe_link_release(struct bpf_link *link)
> > @@ -3045,6 +3055,7 @@ static void bpf_fprobe_link_dealloc(struct bpf_link *link)
> >
> > fprobe_link = container_of(link, struct bpf_fprobe_link, link);
> > kfree(fprobe_link->addrs);
> > + kfree(fprobe_link->bpf_cookies);
> > kfree(fprobe_link);
> > }
> >
> > @@ -3053,9 +3064,37 @@ static const struct bpf_link_ops bpf_fprobe_link_lops = {
> > .dealloc = bpf_fprobe_link_dealloc,
> > };
> >
> > +static int bpf_fprobe_cookie_cmp(const void *_a, const void *_b)
> > +{
> > + const struct bpf_fprobe_cookie *a = _a;
> > + const struct bpf_fprobe_cookie *b = _b;
> > +
> > + if (a->addr == b->addr)
> > + return 0;
> > + return a->addr < b->addr ? -1 : 1;
> > +}
> > +
> > +u64 bpf_fprobe_cookie(struct bpf_run_ctx *ctx, u64 ip)
> > +{
> > + struct bpf_fprobe_link *fprobe_link;
> > + struct bpf_fprobe_cookie *val, key = {
> > + .addr = (unsigned long) ip,
> > + };
> > +
> > + if (!ctx)
> > + return 0;
>
> is it allowed to have ctx == NULL?
nope, I was also thinking this is more 'WARN_ON[_ONCE]' check
>
> > + fprobe_link = container_of(ctx, struct bpf_fprobe_link, run_ctx);
> > + if (!fprobe_link->bpf_cookies)
> > + return 0;
> > + val = bsearch(&key, fprobe_link->bpf_cookies, fprobe_link->cnt,
> > + sizeof(key), bpf_fprobe_cookie_cmp);
> > + return val ? val->bpf_cookie : 0;
> > +}
> > +
> > static int fprobe_link_prog_run(struct bpf_fprobe_link *fprobe_link,
> > struct pt_regs *regs)
> > {
> > + struct bpf_run_ctx *old_run_ctx;
> > int err;
> >
> > if (unlikely(__this_cpu_inc_return(bpf_prog_active) != 1)) {
> > @@ -3063,12 +3102,16 @@ static int fprobe_link_prog_run(struct bpf_fprobe_link *fprobe_link,
> > goto out;
> > }
> >
> > + old_run_ctx = bpf_set_run_ctx(&fprobe_link->run_ctx);
> > +
> > rcu_read_lock();
> > migrate_disable();
> > err = bpf_prog_run(fprobe_link->link.prog, regs);
> > migrate_enable();
> > rcu_read_unlock();
> >
> > + bpf_reset_run_ctx(old_run_ctx);
> > +
> > out:
> > __this_cpu_dec(bpf_prog_active);
> > return err;
> > @@ -3161,10 +3204,12 @@ static int fprobe_resolve_syms(const void *usyms, u32 cnt,
> >
> > static int bpf_fprobe_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
> > {
> > + struct bpf_fprobe_cookie *bpf_cookies = NULL;
> > struct bpf_fprobe_link *link = NULL;
> > struct bpf_link_primer link_primer;
> > + void __user *ubpf_cookies;
> > + u32 flags, cnt, i, size;
> > unsigned long *addrs;
> > - u32 flags, cnt, size;
> > void __user *uaddrs;
> > void __user *usyms;
> > int err;
> > @@ -3205,6 +3250,37 @@ static int bpf_fprobe_link_attach(const union bpf_attr *attr, struct bpf_prog *p
> > goto error;
> > }
> >
> > + ubpf_cookies = u64_to_user_ptr(attr->link_create.fprobe.bpf_cookies);
>
> nit: let's call all this "cookies", this bpf_ prefix feels a bit
> redundant (I know about perf_event.bpf_cookie, but still).
ok
>
> > + if (ubpf_cookies) {
> > + u64 *tmp;
> > +
> > + err = -ENOMEM;
> > + tmp = kzalloc(size, GFP_KERNEL);
>
> kvmalloc?
ok
thanks,
jirka
next prev parent reply other threads:[~2022-02-08 9:07 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-02 13:53 [PATCH 0/8] bpf: Add fprobe link Jiri Olsa
2022-02-02 13:53 ` [PATCH 1/8] bpf: Add support to attach kprobe program with fprobe Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 8:56 ` Jiri Olsa
2022-02-02 13:53 ` [PATCH 2/8] bpf: Add bpf_get_func_ip kprobe helper for fprobe link Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-07 21:01 ` Alexei Starovoitov
2022-02-09 15:01 ` Jiri Olsa
2022-02-09 16:05 ` Andrii Nakryiko
2022-02-09 19:14 ` Jiri Olsa
2022-02-02 13:53 ` [PATCH 3/8] bpf: Add bpf_cookie support to fprobe Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 9:07 ` Jiri Olsa [this message]
2022-02-08 23:35 ` Andrii Nakryiko
2022-02-08 23:46 ` Jiri Olsa
2022-02-08 23:53 ` Andrii Nakryiko
2022-02-02 13:53 ` [PATCH 4/8] libbpf: Add libbpf__kallsyms_parse function Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 9:08 ` Jiri Olsa
2022-02-02 13:53 ` [PATCH 5/8] libbpf: Add bpf_link_create support for multi kprobes Jiri Olsa
2022-02-02 13:53 ` [PATCH 6/8] libbpf: Add bpf_program__attach_kprobe_opts " Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 9:12 ` Jiri Olsa
2022-02-02 13:53 ` [PATCH 7/8] selftest/bpf: Add fprobe attach test Jiri Olsa
2022-02-02 13:53 ` [PATCH 8/8] selftest/bpf: Add fprobe test for bpf_cookie values Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 9:15 ` Jiri Olsa
2022-02-08 23:24 ` Andrii Nakryiko
2022-02-02 17:09 ` [PATCH 0/8] bpf: Add fprobe link Alexei Starovoitov
2022-02-02 17:24 ` Jiri Olsa
2022-02-02 17:30 ` Alexei Starovoitov
2022-02-03 15:06 ` Jiri Olsa
2022-02-04 0:46 ` Masami Hiramatsu
2022-02-04 1:34 ` Alexei Starovoitov
2022-02-04 2:07 ` Masami Hiramatsu
2022-02-04 2:12 ` Alexei Starovoitov
2022-02-04 2:19 ` Steven Rostedt
2022-02-04 2:42 ` Alexei Starovoitov
2022-02-04 3:17 ` Masami Hiramatsu
2022-02-04 3:59 ` Masami Hiramatsu
2022-02-15 13:21 ` Jiri Olsa
2022-02-16 18:27 ` Andrii Nakryiko
2022-02-17 14:03 ` Masami Hiramatsu
2022-02-17 22:01 ` Andrii Nakryiko
2022-02-18 4:07 ` Masami Hiramatsu
2022-02-18 19:46 ` Andrii Nakryiko
2022-02-19 2:10 ` Alexei Starovoitov
2022-02-21 7:18 ` Masami Hiramatsu
2022-02-22 12:42 ` Jiri Olsa
2022-02-04 3:14 ` Masami Hiramatsu
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=YgIy2yCzbNmKPoxv@krava \
--to=jolsa@redhat.com \
--cc=andrii.nakryiko@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=john.fastabend@gmail.com \
--cc=kafai@fb.com \
--cc=kpsingh@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=olsajiri@gmail.com \
--cc=rostedt@goodmis.org \
--cc=songliubraving@fb.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.