@@ -858,7 +858,7 @@ int bpf_raw_tracepoint_open(const char *name, int prog_fd)
return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
}
-int bpf_trampoline_batch_attach(int *ifds, int *ofds, int count)
+static int bpf_trampoline_batch(int cmd, int *ifds, int *ofds, int count)
{
union bpf_attr attr;
@@ -867,7 +867,19 @@ int bpf_trampoline_batch_attach(int *ifds, int *ofds, int count)
attr.trampoline_batch.out = ptr_to_u64(ofds);
attr.trampoline_batch.count = count;
- return sys_bpf(BPF_TRAMPOLINE_BATCH_ATTACH, &attr, sizeof(attr));
+ return sys_bpf(cmd, &attr, sizeof(attr));
+}
+
+int bpf_trampoline_batch_attach(int *ifds, int *ofds, int count)
+{
+ return bpf_trampoline_batch(BPF_TRAMPOLINE_BATCH_ATTACH,
+ ifds, ofds, count);
+}
+
+int bpf_trampoline_batch_detach(int *ifds, int *ofds, int count)
+{
+ return bpf_trampoline_batch(BPF_TRAMPOLINE_BATCH_DETACH,
+ ifds, ofds, count);
}
int bpf_load_btf(const void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
@@ -236,6 +236,7 @@ LIBBPF_API int bpf_prog_query(int target_fd, enum bpf_attach_type type,
__u32 *prog_ids, __u32 *prog_cnt);
LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
LIBBPF_API int bpf_trampoline_batch_attach(int *ifds, int *ofds, int count);
+LIBBPF_API int bpf_trampoline_batch_detach(int *ifds, int *ofds, int count);
LIBBPF_API int bpf_load_btf(const void *btf, __u32 btf_size, char *log_buf,
__u32 log_buf_size, bool do_log);
LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
@@ -10874,6 +10874,47 @@ static int attach_trace_batch(struct bpf_object_skeleton *s)
return ret;
}
+static int detach_trace_batch(struct bpf_object_skeleton *s)
+{
+ int *in_fds, *out_fds, cnt;
+ int i, ret = -ENOMEM;
+
+ in_fds = calloc(s->prog_cnt, sizeof(in_fds[0]));
+ out_fds = calloc(s->prog_cnt, sizeof(out_fds[0]));
+ if (!in_fds || !out_fds)
+ goto out_clean;
+
+ for (cnt = 0, i = 0; i < s->prog_cnt; i++) {
+ struct bpf_program *prog = *s->progs[i].prog;
+ struct bpf_link **link = s->progs[i].link;
+
+ if (!is_trampoline(prog))
+ continue;
+ in_fds[cnt++] = (*link)->fd;
+ }
+
+ ret = bpf_trampoline_batch_detach(in_fds, out_fds, cnt);
+ if (ret)
+ goto out_clean;
+
+ for (i = 0; i < s->prog_cnt; i++) {
+ struct bpf_program *prog = *s->progs[i].prog;
+ struct bpf_link **link = s->progs[i].link;
+
+ if (!is_trampoline(prog))
+ continue;
+
+ bpf_link__disconnect(*link);
+ bpf_link__destroy(*link);
+ *link = NULL;
+ }
+
+out_clean:
+ free(in_fds);
+ free(out_fds);
+ return ret;
+}
+
int bpf_object__attach_skeleton(struct bpf_object_skeleton *s)
{
struct bpf_object *obj = *s->obj;
@@ -10914,11 +10955,20 @@ int bpf_object__attach_skeleton(struct bpf_object_skeleton *s)
void bpf_object__detach_skeleton(struct bpf_object_skeleton *s)
{
+ struct bpf_object *obj = *s->obj;
int i;
+ if (obj->trampoline_attach_batch)
+ detach_trace_batch(s);
+
for (i = 0; i < s->prog_cnt; i++) {
+ struct bpf_program *prog = *s->progs[i].prog;
struct bpf_link **link = s->progs[i].link;
+ /* Program was attached via batch mode. */
+ if (obj->trampoline_attach_batch && is_trampoline(prog))
+ continue;
+
bpf_link__destroy(*link);
*link = NULL;
}
@@ -337,4 +337,5 @@ LIBBPF_0.2.0 {
perf_buffer__consume_buffer;
xsk_socket__create_shared;
bpf_trampoline_batch_attach;
+ bpf_trampoline_batch_detach;
} LIBBPF_0.1.0;
Adding trampoline batch attach support so it's possible to use batch mode to load tracing programs. Adding trampoline_attach_batch bool to struct bpf_object_open_opts. When set to true the bpf_object__detach_skeleton will try to detach all tracing programs via batch mode. Signed-off-by: Jiri Olsa <jolsa@kernel.org> --- tools/lib/bpf/bpf.c | 16 +++++++++++-- tools/lib/bpf/bpf.h | 1 + tools/lib/bpf/libbpf.c | 50 ++++++++++++++++++++++++++++++++++++++++ tools/lib/bpf/libbpf.map | 1 + 4 files changed, 66 insertions(+), 2 deletions(-)