perf btf: Make the sigtrap test helper to find a member by name widely available
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 9 Dec 2024 19:00:39 +0000 (16:00 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 9 Dec 2024 20:52:41 +0000 (17:52 -0300)
By introducing a tools/perf/util/btf.c to collect utilities not yet
available via libbpf, the first being a way to find a member by name
once we get the type_id for the struct.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/tests/sigtrap.c
tools/perf/util/Build
tools/perf/util/btf.c [new file with mode: 0644]
tools/perf/util/btf.h [new file with mode: 0644]

index e6fd934b027a3d0ca36f434135cbdc245acd666d..a67c756f90b8d94837842901b83f34117e9a229b 100644 (file)
@@ -56,6 +56,7 @@ static struct perf_event_attr make_event_attr(void)
 
 #ifdef HAVE_BPF_SKEL
 #include <bpf/btf.h>
+#include <util/btf.h>
 
 static struct btf *btf;
 
@@ -73,21 +74,6 @@ static void btf__exit(void)
        btf = NULL;
 }
 
-static const struct btf_member *__btf_type__find_member_by_name(int type_id, const char *member_name)
-{
-       const struct btf_type *t = btf__type_by_id(btf, type_id);
-       const struct btf_member *m;
-       int i;
-
-       for (i = 0, m = btf_members(t); i < btf_vlen(t); i++, m++) {
-               const char *current_member_name = btf__name_by_offset(btf, m->name_off);
-               if (!strcmp(current_member_name, member_name))
-                       return m;
-       }
-
-       return NULL;
-}
-
 static bool attr_has_sigtrap(void)
 {
        int id;
@@ -101,7 +87,7 @@ static bool attr_has_sigtrap(void)
        if (id < 0)
                return false;
 
-       return __btf_type__find_member_by_name(id, "sigtrap") != NULL;
+       return __btf_type__find_member_by_name(btf, id, "sigtrap") != NULL;
 }
 
 static bool kernel_with_sleepable_spinlocks(void)
@@ -119,7 +105,7 @@ static bool kernel_with_sleepable_spinlocks(void)
                return false;
 
        // Only RT has a "lock" member for "struct spinlock"
-       member = __btf_type__find_member_by_name(id, "lock");
+       member = __btf_type__find_member_by_name(btf, id, "lock");
        if (member == NULL)
                return false;
 
index c06d2ee9024c63fb1d0cf3d25cf56a2b654a5982..be7d3bc7ee0159528f6d7fb0fdb19642414431e0 100644 (file)
@@ -168,6 +168,7 @@ perf-util-$(CONFIG_PERF_BPF_SKEL) += bpf_off_cpu.o
 perf-util-$(CONFIG_PERF_BPF_SKEL) += bpf-filter.o
 perf-util-$(CONFIG_PERF_BPF_SKEL) += bpf-filter-flex.o
 perf-util-$(CONFIG_PERF_BPF_SKEL) += bpf-filter-bison.o
+perf-util-$(CONFIG_PERF_BPF_SKEL) += btf.o
 
 ifeq ($(CONFIG_LIBTRACEEVENT),y)
   perf-util-$(CONFIG_PERF_BPF_SKEL) += bpf_lock_contention.o
diff --git a/tools/perf/util/btf.c b/tools/perf/util/btf.c
new file mode 100644 (file)
index 0000000..bb163fe
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Arnaldo Carvalho de Melo <acme@redhat.com>
+ *
+ * Copyright (C) 2024, Red Hat, Inc
+ */
+
+#include <bpf/btf.h>
+#include <util/btf.h>
+#include <string.h>
+
+const struct btf_member *__btf_type__find_member_by_name(struct btf *btf,
+                                                        int type_id, const char *member_name)
+{
+       const struct btf_type *t = btf__type_by_id(btf, type_id);
+       const struct btf_member *m;
+       int i;
+
+       for (i = 0, m = btf_members(t); i < btf_vlen(t); i++, m++) {
+               const char *current_member_name = btf__name_by_offset(btf, m->name_off);
+
+               if (!strcmp(current_member_name, member_name))
+                       return m;
+       }
+
+       return NULL;
+}
diff --git a/tools/perf/util/btf.h b/tools/perf/util/btf.h
new file mode 100644 (file)
index 0000000..05e6e5b
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PERF_UTIL_BTF
+#define __PERF_UTIL_BTF 1
+
+struct btf;
+struct btf_member;
+
+const struct btf_member *__btf_type__find_member_by_name(struct btf *btf,
+                                                        int type_id, const char *member_name);
+#endif // __PERF_UTIL_BTF