From: "Toke Høiland-Jørgensen" <toke@redhat.com>
To: Andrii Nakryiko <andriin@fb.com>,
bpf@vger.kernel.org, netdev@vger.kernel.org, ast@fb.com,
daniel@iogearbox.net
Cc: andrii.nakryiko@gmail.com, kernel-team@fb.com,
Andrii Nakryiko <andriin@fb.com>
Subject: Re: [PATCH bpf-next 1/3] bpf: introduce pinnable bpf_link abstraction
Date: Mon, 02 Mar 2020 11:13:17 +0100 [thread overview]
Message-ID: <87k143t682.fsf@toke.dk> (raw)
In-Reply-To: <20200228223948.360936-2-andriin@fb.com>
Andrii Nakryiko <andriin@fb.com> writes:
> Introduce bpf_link abstraction, representing an attachment of BPF program to
> a BPF hook point (e.g., tracepoint, perf event, etc). bpf_link encapsulates
> ownership of attached BPF program, reference counting of a link itself, when
> reference from multiple anonymous inodes, as well as ensures that release
> callback will be called from a process context, so that users can safely take
> mutex locks and sleep.
>
> Additionally, with a new abstraction it's now possible to generalize pinning
> of a link object in BPF FS, allowing to explicitly prevent BPF program
> detachment on process exit by pinning it in a BPF FS and let it open from
> independent other process to keep working with it.
>
> Convert two existing bpf_link-like objects (raw tracepoint and tracing BPF
> program attachments) into utilizing bpf_link framework, making them pinnable
> in BPF FS. More FD-based bpf_links will be added in follow up patches.
>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> ---
> include/linux/bpf.h | 13 +++
> kernel/bpf/inode.c | 42 ++++++++-
> kernel/bpf/syscall.c | 209 ++++++++++++++++++++++++++++++++++++-------
> 3 files changed, 226 insertions(+), 38 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 6015a4daf118..f13c78c6f29d 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1056,6 +1056,19 @@ extern int sysctl_unprivileged_bpf_disabled;
> int bpf_map_new_fd(struct bpf_map *map, int flags);
> int bpf_prog_new_fd(struct bpf_prog *prog);
>
> +struct bpf_link;
> +
> +struct bpf_link_ops {
> + void (*release)(struct bpf_link *link);
> +};
> +
> +void bpf_link_init(struct bpf_link *link, const struct bpf_link_ops *ops,
> + struct bpf_prog *prog);
> +void bpf_link_inc(struct bpf_link *link);
> +void bpf_link_put(struct bpf_link *link);
> +int bpf_link_new_fd(struct bpf_link *link);
> +struct bpf_link *bpf_link_get_from_fd(u32 ufd);
> +
> int bpf_obj_pin_user(u32 ufd, const char __user *pathname);
> int bpf_obj_get_user(const char __user *pathname, int flags);
>
> diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
> index 5e40e7fccc21..95087d9f4ed3 100644
> --- a/kernel/bpf/inode.c
> +++ b/kernel/bpf/inode.c
> @@ -25,6 +25,7 @@ enum bpf_type {
> BPF_TYPE_UNSPEC = 0,
> BPF_TYPE_PROG,
> BPF_TYPE_MAP,
> + BPF_TYPE_LINK,
> };
>
> static void *bpf_any_get(void *raw, enum bpf_type type)
> @@ -36,6 +37,9 @@ static void *bpf_any_get(void *raw, enum bpf_type type)
> case BPF_TYPE_MAP:
> bpf_map_inc_with_uref(raw);
> break;
> + case BPF_TYPE_LINK:
> + bpf_link_inc(raw);
> + break;
> default:
> WARN_ON_ONCE(1);
> break;
> @@ -53,6 +57,9 @@ static void bpf_any_put(void *raw, enum bpf_type type)
> case BPF_TYPE_MAP:
> bpf_map_put_with_uref(raw);
> break;
> + case BPF_TYPE_LINK:
> + bpf_link_put(raw);
> + break;
> default:
> WARN_ON_ONCE(1);
> break;
> @@ -63,20 +70,32 @@ static void *bpf_fd_probe_obj(u32 ufd, enum bpf_type *type)
> {
> void *raw;
>
> - *type = BPF_TYPE_MAP;
> raw = bpf_map_get_with_uref(ufd);
> - if (IS_ERR(raw)) {
> + if (!IS_ERR(raw)) {
> + *type = BPF_TYPE_MAP;
> + return raw;
> + }
> +
> + raw = bpf_prog_get(ufd);
> + if (!IS_ERR(raw)) {
> *type = BPF_TYPE_PROG;
> - raw = bpf_prog_get(ufd);
> + return raw;
> }
>
> - return raw;
> + raw = bpf_link_get_from_fd(ufd);
> + if (!IS_ERR(raw)) {
> + *type = BPF_TYPE_LINK;
> + return raw;
> + }
> +
> + return ERR_PTR(-EINVAL);
> }
>
> static const struct inode_operations bpf_dir_iops;
>
> static const struct inode_operations bpf_prog_iops = { };
> static const struct inode_operations bpf_map_iops = { };
> +static const struct inode_operations bpf_link_iops = { };
>
> static struct inode *bpf_get_inode(struct super_block *sb,
> const struct inode *dir,
> @@ -114,6 +133,8 @@ static int bpf_inode_type(const struct inode *inode, enum bpf_type *type)
> *type = BPF_TYPE_PROG;
> else if (inode->i_op == &bpf_map_iops)
> *type = BPF_TYPE_MAP;
> + else if (inode->i_op == &bpf_link_iops)
> + *type = BPF_TYPE_LINK;
> else
> return -EACCES;
>
> @@ -335,6 +356,12 @@ static int bpf_mkmap(struct dentry *dentry, umode_t mode, void *arg)
> &bpffs_map_fops : &bpffs_obj_fops);
> }
>
> +static int bpf_mklink(struct dentry *dentry, umode_t mode, void *arg)
> +{
> + return bpf_mkobj_ops(dentry, mode, arg, &bpf_link_iops,
> + &bpffs_obj_fops);
> +}
> +
> static struct dentry *
> bpf_lookup(struct inode *dir, struct dentry *dentry, unsigned flags)
> {
> @@ -411,6 +438,9 @@ static int bpf_obj_do_pin(const char __user *pathname, void *raw,
> case BPF_TYPE_MAP:
> ret = vfs_mkobj(dentry, mode, bpf_mkmap, raw);
> break;
> + case BPF_TYPE_LINK:
> + ret = vfs_mkobj(dentry, mode, bpf_mklink, raw);
> + break;
> default:
> ret = -EPERM;
> }
> @@ -487,6 +517,8 @@ int bpf_obj_get_user(const char __user *pathname, int flags)
> ret = bpf_prog_new_fd(raw);
> else if (type == BPF_TYPE_MAP)
> ret = bpf_map_new_fd(raw, f_flags);
> + else if (type == BPF_TYPE_LINK)
> + ret = bpf_link_new_fd(raw);
> else
> return -ENOENT;
>
> @@ -504,6 +536,8 @@ static struct bpf_prog *__get_prog_inode(struct inode *inode, enum bpf_prog_type
>
> if (inode->i_op == &bpf_map_iops)
> return ERR_PTR(-EINVAL);
> + if (inode->i_op == &bpf_link_iops)
> + return ERR_PTR(-EINVAL);
> if (inode->i_op != &bpf_prog_iops)
> return ERR_PTR(-EACCES);
>
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index c536c65256ad..fca8de7e7872 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -2173,23 +2173,153 @@ static int bpf_obj_get(const union bpf_attr *attr)
> attr->file_flags);
> }
>
> -static int bpf_tracing_prog_release(struct inode *inode, struct file *filp)
> +struct bpf_link {
> + atomic64_t refcnt;
refcount_t ?
-Toke
next prev parent reply other threads:[~2020-03-02 10:13 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-28 22:39 [PATCH bpf-next 0/3] Introduce pinnable bpf_link kernel abstraction Andrii Nakryiko
2020-02-28 22:39 ` [PATCH bpf-next 1/3] bpf: introduce pinnable bpf_link abstraction Andrii Nakryiko
2020-03-02 10:13 ` Toke Høiland-Jørgensen [this message]
2020-03-02 18:06 ` Andrii Nakryiko
2020-03-02 21:40 ` Toke Høiland-Jørgensen
2020-03-02 23:37 ` Andrii Nakryiko
2020-03-03 2:50 ` Alexei Starovoitov
2020-03-03 4:18 ` Andrii Nakryiko
2020-02-28 22:39 ` [PATCH bpf-next 2/3] libbpf: add bpf_link pinning/unpinning Andrii Nakryiko
2020-03-02 10:16 ` Toke Høiland-Jørgensen
2020-03-02 18:09 ` Andrii Nakryiko
2020-03-02 21:45 ` Toke Høiland-Jørgensen
2020-02-28 22:39 ` [PATCH bpf-next 3/3] selftests/bpf: add link pinning selftests Andrii Nakryiko
2020-03-02 10:11 ` [PATCH bpf-next 0/3] Introduce pinnable bpf_link kernel abstraction Toke Høiland-Jørgensen
2020-03-02 18:05 ` Andrii Nakryiko
2020-03-02 22:24 ` Toke Høiland-Jørgensen
2020-03-02 23:35 ` Andrii Nakryiko
2020-03-03 8:12 ` Toke Høiland-Jørgensen
2020-03-03 8:12 ` Daniel Borkmann
2020-03-03 15:46 ` Alexei Starovoitov
2020-03-03 19:23 ` Daniel Borkmann
2020-03-03 19:46 ` Andrii Nakryiko
2020-03-03 20:24 ` Toke Høiland-Jørgensen
2020-03-03 20:53 ` Daniel Borkmann
2020-03-03 22:01 ` Alexei Starovoitov
2020-03-03 22:27 ` Toke Høiland-Jørgensen
2020-03-04 4:36 ` Alexei Starovoitov
2020-03-04 7:47 ` Toke Høiland-Jørgensen
2020-03-04 15:47 ` Alexei Starovoitov
2020-03-05 10:37 ` Toke Høiland-Jørgensen
2020-03-05 16:34 ` Alexei Starovoitov
2020-03-05 22:34 ` Daniel Borkmann
2020-03-05 22:50 ` Alexei Starovoitov
2020-03-05 23:42 ` Daniel Borkmann
2020-03-06 8:31 ` Toke Høiland-Jørgensen
2020-03-06 10:25 ` Daniel Borkmann
2020-03-06 10:42 ` Toke Høiland-Jørgensen
2020-03-06 18:09 ` David Ahern
2020-03-04 19:41 ` Jakub Kicinski
2020-03-04 20:45 ` Alexei Starovoitov
2020-03-04 21:24 ` Jakub Kicinski
2020-03-05 1:07 ` Alexei Starovoitov
2020-03-05 8:16 ` Jakub Kicinski
2020-03-05 11:05 ` Toke Høiland-Jørgensen
2020-03-05 18:13 ` Jakub Kicinski
2020-03-09 11:41 ` Toke Høiland-Jørgensen
2020-03-09 18:50 ` Jakub Kicinski
2020-03-10 12:22 ` Toke Høiland-Jørgensen
2020-03-05 16:39 ` Alexei Starovoitov
2020-03-03 22:40 ` Jakub Kicinski
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=87k143t682.fsf@toke.dk \
--to=toke@redhat.com \
--cc=andrii.nakryiko@gmail.com \
--cc=andriin@fb.com \
--cc=ast@fb.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=netdev@vger.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 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.