]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
perf tp_pmu: Factor existing tracepoint logic to new file
authorIan Rogers <irogers@google.com>
Fri, 25 Jul 2025 18:51:50 +0000 (11:51 -0700)
committerNamhyung Kim <namhyung@kernel.org>
Sat, 26 Jul 2025 23:31:43 +0000 (16:31 -0700)
Start the creation of a tracepoint PMU abstraction. Tracepoint events
don't follow the regular sysfs perf conventions. Eventually the new
PMU abstraction will bridge the gap so tracepoint events look more
like regular perf ones.

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: https://lore.kernel.org/r/20250725185202.68671-5-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/util/Build
tools/perf/util/evsel.c
tools/perf/util/parse-events.c
tools/perf/util/tp_pmu.c [new file with mode: 0644]
tools/perf/util/tp_pmu.h [new file with mode: 0644]

index 12bc01c843b2c57d328ff5e11ccd654ff3e1cd4b..4959e7a990e47f091acec42efd2dddbb3c316bc1 100644 (file)
@@ -88,6 +88,7 @@ perf-util-y += pmu-bison.o
 perf-util-y += drm_pmu.o
 perf-util-y += hwmon_pmu.o
 perf-util-y += tool_pmu.o
+perf-util-y += tp_pmu.o
 perf-util-y += svghelper.o
 perf-util-y += trace-event-info.o
 perf-util-y += trace-event-scripting.o
index 3d27e9bdd66b89fd5ab5a480399fbeb4277d480d..d264c143b59250d15bb90df17e3b82a0ab456adc 100644 (file)
@@ -60,6 +60,7 @@
 #include "drm_pmu.h"
 #include "hwmon_pmu.h"
 #include "tool_pmu.h"
+#include "tp_pmu.h"
 #include "rlimit.h"
 #include "../perf-sys.h"
 #include "util/parse-branch-options.h"
@@ -572,24 +573,6 @@ out_err:
        return NULL;
 }
 
-static int trace_event__id(const char *sys, const char *name)
-{
-       char *tp_dir = get_events_file(sys);
-       char path[PATH_MAX];
-       int id, err;
-
-       if (!tp_dir)
-               return -1;
-
-       scnprintf(path, PATH_MAX, "%s/%s/id", tp_dir, name);
-       put_events_file(tp_dir);
-       err = filename__read_int(path, &id);
-       if (err)
-               return err;
-
-       return id;
-}
-
 /*
  * Returns pointer with encoded error via <linux/err.h> interface.
  */
@@ -623,7 +606,7 @@ struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx, bool
        event_attr_init(&attr);
 
        if (format) {
-               id = trace_event__id(sys, name);
+               id = tp_pmu__id(sys, name);
                if (id < 0) {
                        err = id;
                        goto out_free;
index 74e0822ad82d2540216fc4eea16674727bf016a3..8282ddf68b983246995b53c7af0847ae308a13e5 100644 (file)
 #include "string2.h"
 #include "strbuf.h"
 #include "debug.h"
-#include <api/fs/tracing_path.h>
-#include <api/io_dir.h>
 #include <perf/cpumap.h>
 #include <util/parse-events-bison.h>
 #include <util/parse-events-flex.h>
 #include "pmu.h"
 #include "pmus.h"
+#include "tp_pmu.h"
 #include "asm/bug.h"
 #include "ui/ui.h"
 #include "util/parse-branch-options.h"
@@ -33,6 +32,7 @@
 #include "util/stat.h"
 #include "util/util.h"
 #include "tracepoint.h"
+#include <api/fs/tracing_path.h>
 
 #define MAX_NAME_LEN 100
 
@@ -599,105 +599,82 @@ static int add_tracepoint(struct parse_events_state *parse_state,
        return 0;
 }
 
-static int add_tracepoint_multi_event(struct parse_events_state *parse_state,
-                                     struct list_head *list,
-                                     const char *sys_name, const char *evt_name,
-                                     struct parse_events_error *err,
-                                     struct parse_events_terms *head_config, YYLTYPE *loc)
-{
-       char *evt_path;
-       struct io_dirent64 *evt_ent;
-       struct io_dir evt_dir;
-       int ret = 0, found = 0;
-
-       evt_path = get_events_file(sys_name);
-       if (!evt_path) {
-               tracepoint_error(err, errno, sys_name, evt_name, loc->first_column);
-               return -1;
-       }
-       io_dir__init(&evt_dir, open(evt_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
-       if (evt_dir.dirfd < 0) {
-               put_events_file(evt_path);
-               tracepoint_error(err, errno, sys_name, evt_name, loc->first_column);
-               return -1;
-       }
+struct add_tracepoint_multi_args {
+       struct parse_events_state *parse_state;
+       struct list_head *list;
+       const char *sys_glob;
+       const char *evt_glob;
+       struct parse_events_error *err;
+       struct parse_events_terms *head_config;
+       YYLTYPE *loc;
+       int found;
+};
 
-       while (!ret && (evt_ent = io_dir__readdir(&evt_dir))) {
-               if (!strcmp(evt_ent->d_name, ".")
-                   || !strcmp(evt_ent->d_name, "..")
-                   || !strcmp(evt_ent->d_name, "enable")
-                   || !strcmp(evt_ent->d_name, "filter"))
-                       continue;
+static int add_tracepoint_multi_event_cb(void *state, const char *sys_name, const char *evt_name)
+{
+       struct add_tracepoint_multi_args *args = state;
+       int ret;
 
-               if (!strglobmatch(evt_ent->d_name, evt_name))
-                       continue;
+       if (!strglobmatch(evt_name, args->evt_glob))
+               return 0;
 
-               found++;
+       args->found++;
+       ret = add_tracepoint(args->parse_state, args->list, sys_name, evt_name,
+                            args->err, args->head_config, args->loc);
 
-               ret = add_tracepoint(parse_state, list, sys_name, evt_ent->d_name,
-                                    err, head_config, loc);
-       }
+       return ret;
+}
 
-       if (!found) {
-               tracepoint_error(err, ENOENT, sys_name, evt_name, loc->first_column);
-               ret = -1;
+static int add_tracepoint_multi_event(struct add_tracepoint_multi_args *args, const char *sys_name)
+{
+       if (strpbrk(args->evt_glob, "*?") == NULL) {
+               /* Not a glob. */
+               args->found++;
+               return add_tracepoint(args->parse_state, args->list, sys_name, args->evt_glob,
+                                     args->err, args->head_config, args->loc);
        }
 
-       put_events_file(evt_path);
-       close(evt_dir.dirfd);
-       return ret;
+       return tp_pmu__for_each_tp_event(sys_name, args, add_tracepoint_multi_event_cb);
 }
 
-static int add_tracepoint_event(struct parse_events_state *parse_state,
-                               struct list_head *list,
-                               const char *sys_name, const char *evt_name,
-                               struct parse_events_error *err,
-                               struct parse_events_terms *head_config, YYLTYPE *loc)
+static int add_tracepoint_multi_sys_cb(void *state, const char *sys_name)
 {
-       return strpbrk(evt_name, "*?") ?
-               add_tracepoint_multi_event(parse_state, list, sys_name, evt_name,
-                                          err, head_config, loc) :
-               add_tracepoint(parse_state, list, sys_name, evt_name,
-                              err, head_config, loc);
+       struct add_tracepoint_multi_args *args = state;
+
+       if (!strglobmatch(sys_name, args->sys_glob))
+               return 0;
+
+       return add_tracepoint_multi_event(args, sys_name);
 }
 
 static int add_tracepoint_multi_sys(struct parse_events_state *parse_state,
                                    struct list_head *list,
-                                   const char *sys_name, const char *evt_name,
+                                   const char *sys_glob, const char *evt_glob,
                                    struct parse_events_error *err,
                                    struct parse_events_terms *head_config, YYLTYPE *loc)
 {
-       struct io_dirent64 *events_ent;
-       struct io_dir events_dir;
-       int ret = 0;
-       char *events_dir_path = get_tracing_file("events");
+       struct add_tracepoint_multi_args args = {
+               .parse_state = parse_state,
+               .list = list,
+               .sys_glob = sys_glob,
+               .evt_glob = evt_glob,
+               .err = err,
+               .head_config = head_config,
+               .loc = loc,
+               .found = 0,
+       };
+       int ret;
 
-       if (!events_dir_path) {
-               tracepoint_error(err, errno, sys_name, evt_name, loc->first_column);
-               return -1;
+       if (strpbrk(sys_glob, "*?") == NULL) {
+               /* Not a glob. */
+               ret = add_tracepoint_multi_event(&args, sys_glob);
+       } else {
+               ret = tp_pmu__for_each_tp_sys(&args, add_tracepoint_multi_sys_cb);
        }
-       io_dir__init(&events_dir, open(events_dir_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
-       put_events_file(events_dir_path);
-       if (events_dir.dirfd < 0) {
-               tracepoint_error(err, errno, sys_name, evt_name, loc->first_column);
-               return -1;
+       if (args.found == 0) {
+               tracepoint_error(err, ENOENT, sys_glob, evt_glob, loc->first_column);
+               return -ENOENT;
        }
-
-       while (!ret && (events_ent = io_dir__readdir(&events_dir))) {
-               if (!strcmp(events_ent->d_name, ".")
-                   || !strcmp(events_ent->d_name, "..")
-                   || !strcmp(events_ent->d_name, "enable")
-                   || !strcmp(events_ent->d_name, "header_event")
-                   || !strcmp(events_ent->d_name, "header_page"))
-                       continue;
-
-               if (!strglobmatch(events_ent->d_name, sys_name))
-                       continue;
-
-               ret = add_tracepoint_event(parse_state, list, events_ent->d_name,
-                                          evt_name, err, head_config, loc);
-       }
-       close(events_dir.dirfd);
        return ret;
 }
 
@@ -1406,12 +1383,8 @@ int parse_events_add_tracepoint(struct parse_events_state *parse_state,
                        return -EINVAL;
        }
 
-       if (strpbrk(sys, "*?"))
-               return add_tracepoint_multi_sys(parse_state, list, sys, event,
-                                               err, head_config, loc);
-       else
-               return add_tracepoint_event(parse_state, list, sys, event,
-                                           err, head_config, loc);
+       return add_tracepoint_multi_sys(parse_state, list, sys, event,
+                                       err, head_config, loc);
 }
 
 static int __parse_events_add_numeric(struct parse_events_state *parse_state,
diff --git a/tools/perf/util/tp_pmu.c b/tools/perf/util/tp_pmu.c
new file mode 100644 (file)
index 0000000..42bd967
--- /dev/null
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+#include "tp_pmu.h"
+#include <api/fs/fs.h>
+#include <api/fs/tracing_path.h>
+#include <api/io_dir.h>
+#include <linux/kernel.h>
+#include <errno.h>
+#include <string.h>
+
+int tp_pmu__id(const char *sys, const char *name)
+{
+       char *tp_dir = get_events_file(sys);
+       char path[PATH_MAX];
+       int id, err;
+
+       if (!tp_dir)
+               return -1;
+
+       scnprintf(path, PATH_MAX, "%s/%s/id", tp_dir, name);
+       put_events_file(tp_dir);
+       err = filename__read_int(path, &id);
+       if (err)
+               return err;
+
+       return id;
+}
+
+
+int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callback cb)
+{
+       char *evt_path;
+       struct io_dirent64 *evt_ent;
+       struct io_dir evt_dir;
+       int ret = 0;
+
+       evt_path = get_events_file(sys);
+       if (!evt_path)
+               return -errno;
+
+       io_dir__init(&evt_dir, open(evt_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
+       if (evt_dir.dirfd < 0) {
+               ret = -errno;
+               put_events_file(evt_path);
+               return ret;
+       }
+       put_events_file(evt_path);
+
+       while (!ret && (evt_ent = io_dir__readdir(&evt_dir))) {
+               if (!strcmp(evt_ent->d_name, ".")
+                   || !strcmp(evt_ent->d_name, "..")
+                   || !strcmp(evt_ent->d_name, "enable")
+                   || !strcmp(evt_ent->d_name, "filter"))
+                       continue;
+
+               ret = cb(state, sys, evt_ent->d_name);
+               if (ret)
+                       break;
+       }
+       close(evt_dir.dirfd);
+       return ret;
+}
+
+int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb)
+{
+       struct io_dirent64 *events_ent;
+       struct io_dir events_dir;
+       int ret = 0;
+       char *events_dir_path = get_tracing_file("events");
+
+       if (!events_dir_path)
+               return -errno;
+
+       io_dir__init(&events_dir, open(events_dir_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
+       if (events_dir.dirfd < 0) {
+               ret = -errno;
+               put_events_file(events_dir_path);
+               return ret;
+       }
+       put_events_file(events_dir_path);
+
+       while (!ret && (events_ent = io_dir__readdir(&events_dir))) {
+               if (!strcmp(events_ent->d_name, ".") ||
+                   !strcmp(events_ent->d_name, "..") ||
+                   !strcmp(events_ent->d_name, "enable") ||
+                   !strcmp(events_ent->d_name, "header_event") ||
+                   !strcmp(events_ent->d_name, "header_page"))
+                       continue;
+
+               ret = cb(state, events_ent->d_name);
+               if (ret)
+                       break;
+       }
+       close(events_dir.dirfd);
+       return ret;
+}
diff --git a/tools/perf/util/tp_pmu.h b/tools/perf/util/tp_pmu.h
new file mode 100644 (file)
index 0000000..4953730
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
+#ifndef __TP_PMU_H
+#define __TP_PMU_H
+
+typedef int (*tp_sys_callback)(void *state, const char *sys_name);
+typedef int (*tp_event_callback)(void *state, const char *sys_name, const char *evt_name);
+
+int tp_pmu__id(const char *sys, const char *name);
+int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callback cb);
+int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb);
+
+#endif /* __TP_PMU_H */