]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Add show_fdinfo for perf_event
authorTao Chen <chen.dylane@linux.dev>
Fri, 6 Jun 2025 15:02:58 +0000 (23:02 +0800)
committerAndrii Nakryiko <andrii@kernel.org>
Mon, 9 Jun 2025 23:40:13 +0000 (16:40 -0700)
After commit 1b715e1b0ec5 ("bpf: Support ->fill_link_info for perf_event") add
perf_event info, we can also show the info with the method of cat /proc/[fd]/fdinfo.

kprobe fdinfo:
link_type: perf
link_id: 10
prog_tag: bcf7977d3b93787c
prog_id: 20
name: bpf_fentry_test1
offset: 0x0
missed: 0
addr: 0xffffffffa28a2904
event_type: kprobe
cookie: 3735928559

uprobe fdinfo:
link_type: perf
link_id: 13
prog_tag: bcf7977d3b93787c
prog_id: 21
name: /proc/self/exe
offset: 0x63dce4
ref_ctr_offset: 0x33eee2a
event_type: uprobe
cookie: 3735928559

tracepoint fdinfo:
link_type: perf
link_id: 11
prog_tag: bcf7977d3b93787c
prog_id: 22
tp_name: sched_switch
event_type: tracepoint
cookie: 3735928559

perf_event fdinfo:
link_type: perf
link_id: 12
prog_tag: bcf7977d3b93787c
prog_id: 23
type: 1
config: 2
event_type: event
cookie: 3735928559

Signed-off-by: Tao Chen <chen.dylane@linux.dev>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20250606150258.3385166-1-chen.dylane@linux.dev
kernel/bpf/syscall.c

index 97ad57ffc4041d22dd9485e9c0efcbd9bf530a6d..0c267f37775b31963d0eb8f52c7697cc6903c63d 100644 (file)
@@ -3795,6 +3795,32 @@ static int bpf_perf_link_fill_kprobe(const struct perf_event *event,
        info->perf_event.kprobe.cookie = event->bpf_cookie;
        return 0;
 }
+
+static void bpf_perf_link_fdinfo_kprobe(const struct perf_event *event,
+                                       struct seq_file *seq)
+{
+       const char *name;
+       int err;
+       u32 prog_id, type;
+       u64 offset, addr;
+       unsigned long missed;
+
+       err = bpf_get_perf_event_info(event, &prog_id, &type, &name,
+                                     &offset, &addr, &missed);
+       if (err)
+               return;
+
+       seq_printf(seq,
+                  "name:\t%s\n"
+                  "offset:\t%#llx\n"
+                  "missed:\t%lu\n"
+                  "addr:\t%#llx\n"
+                  "event_type:\t%s\n"
+                  "cookie:\t%llu\n",
+                  name, offset, missed, addr,
+                  type == BPF_FD_TYPE_KRETPROBE ?  "kretprobe" : "kprobe",
+                  event->bpf_cookie);
+}
 #endif
 
 #ifdef CONFIG_UPROBE_EVENTS
@@ -3823,6 +3849,31 @@ static int bpf_perf_link_fill_uprobe(const struct perf_event *event,
        info->perf_event.uprobe.ref_ctr_offset = ref_ctr_offset;
        return 0;
 }
+
+static void bpf_perf_link_fdinfo_uprobe(const struct perf_event *event,
+                                       struct seq_file *seq)
+{
+       const char *name;
+       int err;
+       u32 prog_id, type;
+       u64 offset, ref_ctr_offset;
+       unsigned long missed;
+
+       err = bpf_get_perf_event_info(event, &prog_id, &type, &name,
+                                     &offset, &ref_ctr_offset, &missed);
+       if (err)
+               return;
+
+       seq_printf(seq,
+                  "name:\t%s\n"
+                  "offset:\t%#llx\n"
+                  "ref_ctr_offset:\t%#llx\n"
+                  "event_type:\t%s\n"
+                  "cookie:\t%llu\n",
+                  name, offset, ref_ctr_offset,
+                  type == BPF_FD_TYPE_URETPROBE ?  "uretprobe" : "uprobe",
+                  event->bpf_cookie);
+}
 #endif
 
 static int bpf_perf_link_fill_probe(const struct perf_event *event,
@@ -3891,10 +3942,79 @@ static int bpf_perf_link_fill_link_info(const struct bpf_link *link,
        }
 }
 
+static void bpf_perf_event_link_show_fdinfo(const struct perf_event *event,
+                                           struct seq_file *seq)
+{
+       seq_printf(seq,
+                  "type:\t%u\n"
+                  "config:\t%llu\n"
+                  "event_type:\t%s\n"
+                  "cookie:\t%llu\n",
+                  event->attr.type, event->attr.config,
+                  "event", event->bpf_cookie);
+}
+
+static void bpf_tracepoint_link_show_fdinfo(const struct perf_event *event,
+                                           struct seq_file *seq)
+{
+       int err;
+       const char *name;
+       u32 prog_id;
+
+       err = bpf_get_perf_event_info(event, &prog_id, NULL, &name, NULL,
+                                     NULL, NULL);
+       if (err)
+               return;
+
+       seq_printf(seq,
+                  "tp_name:\t%s\n"
+                  "event_type:\t%s\n"
+                  "cookie:\t%llu\n",
+                  name, "tracepoint", event->bpf_cookie);
+}
+
+static void bpf_probe_link_show_fdinfo(const struct perf_event *event,
+                                      struct seq_file *seq)
+{
+#ifdef CONFIG_KPROBE_EVENTS
+       if (event->tp_event->flags & TRACE_EVENT_FL_KPROBE)
+               return bpf_perf_link_fdinfo_kprobe(event, seq);
+#endif
+
+#ifdef CONFIG_UPROBE_EVENTS
+       if (event->tp_event->flags & TRACE_EVENT_FL_UPROBE)
+               return bpf_perf_link_fdinfo_uprobe(event, seq);
+#endif
+}
+
+static void bpf_perf_link_show_fdinfo(const struct bpf_link *link,
+                                     struct seq_file *seq)
+{
+       struct bpf_perf_link *perf_link;
+       const struct perf_event *event;
+
+       perf_link = container_of(link, struct bpf_perf_link, link);
+       event = perf_get_event(perf_link->perf_file);
+       if (IS_ERR(event))
+               return;
+
+       switch (event->prog->type) {
+       case BPF_PROG_TYPE_PERF_EVENT:
+               return bpf_perf_event_link_show_fdinfo(event, seq);
+       case BPF_PROG_TYPE_TRACEPOINT:
+               return bpf_tracepoint_link_show_fdinfo(event, seq);
+       case BPF_PROG_TYPE_KPROBE:
+               return bpf_probe_link_show_fdinfo(event, seq);
+       default:
+               return;
+       }
+}
+
 static const struct bpf_link_ops bpf_perf_link_lops = {
        .release = bpf_perf_link_release,
        .dealloc = bpf_perf_link_dealloc,
        .fill_link_info = bpf_perf_link_fill_link_info,
+       .show_fdinfo = bpf_perf_link_show_fdinfo,
 };
 
 static int bpf_perf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)