From: Kui-Feng Lee <kuifeng@meta.com>
To: <bpf@vger.kernel.org>, <ast@kernel.org>, <martin.lau@linux.dev>,
<song@kernel.org>, <kernel-team@meta.com>, <andrii@kernel.org>,
<sdf@google.com>
Cc: Kui-Feng Lee <kuifeng@meta.com>
Subject: [PATCH bpf-next v4 5/9] libbpf: Create a bpf_link in bpf_map__attach_struct_ops().
Date: Tue, 7 Mar 2023 15:33:03 -0800 [thread overview]
Message-ID: <20230307233307.3626875-6-kuifeng@meta.com> (raw)
In-Reply-To: <20230307233307.3626875-1-kuifeng@meta.com>
bpf_map__attach_struct_ops() was creating a dummy bpf_link as a
placeholder, but now it is constructing an authentic one by calling
bpf_link_create() if the map has the BPF_F_LINK flag.
You can flag a struct_ops map with BPF_F_LINK by calling
bpf_map__set_map_flags().
Signed-off-by: Kui-Feng Lee <kuifeng@meta.com>
---
tools/lib/bpf/libbpf.c | 84 +++++++++++++++++++++++++++++++-----------
1 file changed, 62 insertions(+), 22 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 35a698eb825d..a67efc3b3763 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -115,6 +115,7 @@ static const char * const attach_type_name[] = {
[BPF_SK_REUSEPORT_SELECT_OR_MIGRATE] = "sk_reuseport_select_or_migrate",
[BPF_PERF_EVENT] = "perf_event",
[BPF_TRACE_KPROBE_MULTI] = "trace_kprobe_multi",
+ [BPF_STRUCT_OPS] = "struct_ops",
};
static const char * const link_type_name[] = {
@@ -7677,6 +7678,26 @@ static int bpf_object__resolve_externs(struct bpf_object *obj,
return 0;
}
+static void bpf_map_prepare_vdata(const struct bpf_map *map)
+{
+ struct bpf_struct_ops *st_ops;
+ __u32 i;
+
+ st_ops = map->st_ops;
+ for (i = 0; i < btf_vlen(st_ops->type); i++) {
+ struct bpf_program *prog = st_ops->progs[i];
+ void *kern_data;
+ int prog_fd;
+
+ if (!prog)
+ continue;
+
+ prog_fd = bpf_program__fd(prog);
+ kern_data = st_ops->kern_vdata + st_ops->kern_func_off[i];
+ *(unsigned long *)kern_data = prog_fd;
+ }
+}
+
static int bpf_object_load(struct bpf_object *obj, int extra_log_level, const char *target_btf_path)
{
int err, i;
@@ -7728,6 +7749,10 @@ static int bpf_object_load(struct bpf_object *obj, int extra_log_level, const ch
btf__free(obj->btf_vmlinux);
obj->btf_vmlinux = NULL;
+ for (i = 0; i < obj->nr_maps; i++)
+ if (bpf_map__is_struct_ops(&obj->maps[i]))
+ bpf_map_prepare_vdata(&obj->maps[i]);
+
obj->loaded = true; /* doesn't matter if successfully or not */
if (err)
@@ -11429,22 +11454,34 @@ struct bpf_link *bpf_program__attach(const struct bpf_program *prog)
return link;
}
+struct bpf_link_struct_ops {
+ struct bpf_link link;
+ int map_fd;
+};
+
static int bpf_link__detach_struct_ops(struct bpf_link *link)
{
+ struct bpf_link_struct_ops *st_link;
__u32 zero = 0;
- if (bpf_map_delete_elem(link->fd, &zero))
- return -errno;
+ st_link = container_of(link, struct bpf_link_struct_ops, link);
- return 0;
+ if (st_link->map_fd < 0) {
+ /* Fake bpf_link */
+ if (bpf_map_delete_elem(link->fd, &zero))
+ return -errno;
+ return 0;
+ }
+
+ /* Doesn't support detaching. */
+ return -EOPNOTSUPP;
}
struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map)
{
- struct bpf_struct_ops *st_ops;
- struct bpf_link *link;
- __u32 i, zero = 0;
- int err;
+ struct bpf_link_struct_ops *link;
+ __u32 zero = 0;
+ int err, fd;
if (!bpf_map__is_struct_ops(map) || map->fd == -1)
return libbpf_err_ptr(-EINVAL);
@@ -11453,31 +11490,34 @@ struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map)
if (!link)
return libbpf_err_ptr(-EINVAL);
- st_ops = map->st_ops;
- for (i = 0; i < btf_vlen(st_ops->type); i++) {
- struct bpf_program *prog = st_ops->progs[i];
- void *kern_data;
- int prog_fd;
+ /* kern_vdata should be prepared during the loading phase. */
+ err = bpf_map_update_elem(map->fd, &zero, map->st_ops->kern_vdata, 0);
+ if (err) {
+ err = -errno;
+ free(link);
+ return libbpf_err_ptr(err);
+ }
- if (!prog)
- continue;
- prog_fd = bpf_program__fd(prog);
- kern_data = st_ops->kern_vdata + st_ops->kern_func_off[i];
- *(unsigned long *)kern_data = prog_fd;
+ if (!(map->def.map_flags & BPF_F_LINK)) {
+ /* Fake bpf_link */
+ link->link.fd = map->fd;
+ link->map_fd = -1;
+ link->link.detach = bpf_link__detach_struct_ops;
+ return &link->link;
}
- err = bpf_map_update_elem(map->fd, &zero, st_ops->kern_vdata, 0);
- if (err) {
+ fd = bpf_link_create(map->fd, -1, BPF_STRUCT_OPS, NULL);
+ if (fd < 0) {
err = -errno;
free(link);
return libbpf_err_ptr(err);
}
- link->detach = bpf_link__detach_struct_ops;
- link->fd = map->fd;
+ link->link.fd = fd;
+ link->map_fd = map->fd;
- return link;
+ return &link->link;
}
typedef enum bpf_perf_event_ret (*bpf_perf_event_print_t)(struct perf_event_header *hdr,
--
2.34.1
next prev parent reply other threads:[~2023-03-07 23:34 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-07 23:32 [PATCH bpf-next v4 0/9] Transit between BPF TCP congestion controls Kui-Feng Lee
2023-03-07 23:32 ` [PATCH bpf-next v4 1/9] bpf: Retire the struct_ops map kvalue->refcnt Kui-Feng Lee
2023-03-07 23:33 ` [PATCH bpf-next v4 2/9] bpf: Create links for BPF struct_ops maps Kui-Feng Lee
2023-03-08 0:37 ` Andrii Nakryiko
2023-03-08 1:11 ` Kui-Feng Lee
2023-03-07 23:33 ` [PATCH bpf-next v4 3/9] net: Update an existing TCP congestion control algorithm Kui-Feng Lee
2023-03-07 23:33 ` [PATCH bpf-next v4 4/9] bpf: Validate kdata of a struct_ops before transiting to READY Kui-Feng Lee
2023-03-07 23:33 ` Kui-Feng Lee [this message]
2023-03-08 0:46 ` [PATCH bpf-next v4 5/9] libbpf: Create a bpf_link in bpf_map__attach_struct_ops() Andrii Nakryiko
2023-03-08 3:33 ` Kui-Feng Lee
2023-03-07 23:33 ` [PATCH bpf-next v4 6/9] bpf: Update the struct_ops of a bpf_link Kui-Feng Lee
2023-03-08 0:49 ` Andrii Nakryiko
2023-03-08 16:27 ` Kui-Feng Lee
2023-03-07 23:33 ` [PATCH bpf-next v4 7/9] libbpf: Update a bpf_link with another struct_ops Kui-Feng Lee
2023-03-08 0:53 ` Andrii Nakryiko
2023-03-08 1:45 ` Kui-Feng Lee
2023-03-07 23:33 ` [PATCH bpf-next v4 8/9] libbpf: Use .struct_ops.link section to indicate a struct_ops with a link Kui-Feng Lee
2023-03-08 1:07 ` Andrii Nakryiko
2023-03-08 4:23 ` Kui-Feng Lee
2023-03-07 23:33 ` [PATCH bpf-next v4 9/9] selftests/bpf: Test switching TCP Congestion Control algorithms Kui-Feng Lee
2023-03-08 1:10 ` Andrii Nakryiko
2023-03-08 15:58 ` Kui-Feng Lee
2023-03-08 17:18 ` Andrii Nakryiko
2023-03-08 18:10 ` Kui-Feng Lee
2023-03-08 18:43 ` 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=20230307233307.3626875-6-kuifeng@meta.com \
--to=kuifeng@meta.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=kernel-team@meta.com \
--cc=martin.lau@linux.dev \
--cc=sdf@google.com \
--cc=song@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