perf parse-events: Add new 'fake_tp' parameter for tests
authorDominique Martinet <asmadeus@codewreck.org>
Thu, 9 May 2024 22:24:31 +0000 (07:24 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 10 May 2024 13:49:26 +0000 (10:49 -0300)
The next commit will allow tracepoints starting with digits, but most
systems do not have any available by default so tests should skip the
actual "check if it exists in /sys/kernel/debug/tracing" step.

In order to do that, add a new boolean flag specifying if we should
actually "format" the probe or not.

Originally-by: Jiri Olsa <jolsa@kernel.org>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240510-perf_digit-v4-2-db1553f3233b@codewreck.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/tests/parse-events.c
tools/perf/tests/pmu-events.c
tools/perf/util/evlist.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/metricgroup.c
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h

index 993e482f094c2d20a471757b40ac0d0108f68365..c3b77570bb57a35a86b2cd5f3a8676f643a9f47d 100644 (file)
@@ -2493,7 +2493,8 @@ static int test_event(const struct evlist_test *e)
                return TEST_FAIL;
        }
        parse_events_error__init(&err);
-       ret = parse_events(evlist, e->name, &err);
+       ret = __parse_events(evlist, e->name, /*pmu_filter=*/NULL, &err, /*fake_pmu=*/NULL,
+                            /*warn_if_reordered=*/true, /*fake_tp=*/true);
        if (ret) {
                pr_debug("failed to parse event '%s', err %d\n", e->name, ret);
                parse_events_error__print(&err, e->name);
@@ -2521,7 +2522,8 @@ static int test_event_fake_pmu(const char *str)
 
        parse_events_error__init(&err);
        ret = __parse_events(evlist, str, /*pmu_filter=*/NULL, &err,
-                            &perf_pmu__fake, /*warn_if_reordered=*/true);
+                            &perf_pmu__fake, /*warn_if_reordered=*/true,
+                            /*fake_tp=*/true);
        if (ret) {
                pr_debug("failed to parse event '%s', err %d\n",
                         str, ret);
index f39aadacd7a65cbbce71190fd624ddf69bdb2ba4..ff3e7bc0a77f73e7849ad3e555f17368c1678c2e 100644 (file)
@@ -842,7 +842,7 @@ static int check_parse_id(const char *id, struct parse_events_error *error,
                *cur = '/';
 
        ret = __parse_events(evlist, dup, /*pmu_filter=*/NULL, error, fake_pmu,
-                            /*warn_if_reordered=*/true);
+                            /*warn_if_reordered=*/true, /*fake_tp=*/false);
        free(dup);
 
        evlist__delete(evlist);
index 55a300a0977b416e60e90819ad1a9feefcdcbc84..3a719edafc7ad263f0d5226184f47050de29a945 100644 (file)
@@ -298,7 +298,8 @@ struct evsel *evlist__add_aux_dummy(struct evlist *evlist, bool system_wide)
 #ifdef HAVE_LIBTRACEEVENT
 struct evsel *evlist__add_sched_switch(struct evlist *evlist, bool system_wide)
 {
-       struct evsel *evsel = evsel__newtp_idx("sched", "sched_switch", 0);
+       struct evsel *evsel = evsel__newtp_idx("sched", "sched_switch", 0,
+                                              /*format=*/true);
 
        if (IS_ERR(evsel))
                return evsel;
index 3536404e9447bf65228b944c940eed8a9b127799..4f818ab6b6625d50e28ce30c7383cf50265d0b04 100644 (file)
@@ -452,7 +452,7 @@ out_err:
  * Returns pointer with encoded error via <linux/err.h> interface.
  */
 #ifdef HAVE_LIBTRACEEVENT
-struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx)
+struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx, bool format)
 {
        struct evsel *evsel = zalloc(perf_evsel__object.size);
        int err = -ENOMEM;
@@ -469,14 +469,20 @@ struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx)
                if (asprintf(&evsel->name, "%s:%s", sys, name) < 0)
                        goto out_free;
 
-               evsel->tp_format = trace_event__tp_format(sys, name);
-               if (IS_ERR(evsel->tp_format)) {
-                       err = PTR_ERR(evsel->tp_format);
-                       goto out_free;
+               event_attr_init(&attr);
+
+               if (format) {
+                       evsel->tp_format = trace_event__tp_format(sys, name);
+                       if (IS_ERR(evsel->tp_format)) {
+                               err = PTR_ERR(evsel->tp_format);
+                               goto out_free;
+                       }
+                       attr.config = evsel->tp_format->id;
+               } else {
+                       attr.config = (__u64) -1;
                }
 
-               event_attr_init(&attr);
-               attr.config = evsel->tp_format->id;
+
                attr.sample_period = 1;
                evsel__init(evsel, &attr, idx);
        }
index 517cff431de2002eee9cc4f279a9f3f0578cf7da..375a38e15cd99a38f72c877044af2e2a785e97a3 100644 (file)
@@ -234,14 +234,14 @@ void free_config_terms(struct list_head *config_terms);
 
 
 #ifdef HAVE_LIBTRACEEVENT
-struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx);
+struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx, bool format);
 
 /*
  * Returns pointer with encoded error via <linux/err.h> interface.
  */
 static inline struct evsel *evsel__newtp(const char *sys, const char *name)
 {
-       return evsel__newtp_idx(sys, name, 0);
+       return evsel__newtp_idx(sys, name, 0, true);
 }
 #endif
 
index 9be40652461792b5ca25e534e6778948c9bfb568..69f6a46402c3d6ef0eaebdb6dd6eb47b52c4a4a1 100644 (file)
@@ -1502,7 +1502,8 @@ static int parse_ids(bool metric_no_merge, struct perf_pmu *fake_pmu,
        pr_debug("Parsing metric events '%s'\n", events.buf);
        parse_events_error__init(&parse_error);
        ret = __parse_events(parsed_evlist, events.buf, /*pmu_filter=*/NULL,
-                            &parse_error, fake_pmu, /*warn_if_reordered=*/false);
+                            &parse_error, fake_pmu, /*warn_if_reordered=*/false,
+                            /*fake_tp=*/false);
        if (ret) {
                parse_events_error__print(&parse_error, events.buf);
                goto err_out;
index e6a2a80b02dffc6040885a93bc66087d74f40509..30f9580690761232e063798fa781b9173866bc6f 100644 (file)
@@ -550,7 +550,8 @@ static int add_tracepoint(struct parse_events_state *parse_state,
                          struct parse_events_terms *head_config, void *loc_)
 {
        YYLTYPE *loc = loc_;
-       struct evsel *evsel = evsel__newtp_idx(sys_name, evt_name, parse_state->idx++);
+       struct evsel *evsel = evsel__newtp_idx(sys_name, evt_name, parse_state->idx++,
+                                              !parse_state->fake_tp);
 
        if (IS_ERR(evsel)) {
                tracepoint_error(err, PTR_ERR(evsel), sys_name, evt_name, loc->first_column);
@@ -2135,7 +2136,7 @@ static int parse_events__sort_events_and_fix_groups(struct list_head *list)
 
 int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filter,
                   struct parse_events_error *err, struct perf_pmu *fake_pmu,
-                  bool warn_if_reordered)
+                  bool warn_if_reordered, bool fake_tp)
 {
        struct parse_events_state parse_state = {
                .list     = LIST_HEAD_INIT(parse_state.list),
@@ -2143,6 +2144,7 @@ int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filte
                .error    = err,
                .stoken   = PE_START_EVENTS,
                .fake_pmu = fake_pmu,
+               .fake_tp  = fake_tp,
                .pmu_filter = pmu_filter,
                .match_legacy_cache_terms = true,
        };
@@ -2352,7 +2354,8 @@ int parse_events_option(const struct option *opt, const char *str,
 
        parse_events_error__init(&err);
        ret = __parse_events(*args->evlistp, str, args->pmu_filter, &err,
-                            /*fake_pmu=*/NULL, /*warn_if_reordered=*/true);
+                            /*fake_pmu=*/NULL, /*warn_if_reordered=*/true,
+                            /*fake_tp=*/false);
 
        if (ret) {
                parse_events_error__print(&err, str);
index c06984bd3af8394c6b2f6a0b031b1d5ac011a9a0..f2baa69fff982ddf8d17e92bb8d04e0e5f58b713 100644 (file)
@@ -32,14 +32,14 @@ int parse_events_option_new_evlist(const struct option *opt, const char *str, in
 __attribute__((nonnull(1, 2, 4)))
 int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filter,
                   struct parse_events_error *error, struct perf_pmu *fake_pmu,
-                  bool warn_if_reordered);
+                  bool warn_if_reordered, bool fake_tp);
 
 __attribute__((nonnull(1, 2, 3)))
 static inline int parse_events(struct evlist *evlist, const char *str,
                               struct parse_events_error *err)
 {
        return __parse_events(evlist, str, /*pmu_filter=*/NULL, err, /*fake_pmu=*/NULL,
-                             /*warn_if_reordered=*/true);
+                             /*warn_if_reordered=*/true, /*fake_tp=*/false);
 }
 
 int parse_event(struct evlist *evlist, const char *str);
@@ -152,6 +152,8 @@ struct parse_events_state {
        int                        stoken;
        /* Special fake PMU marker for testing. */
        struct perf_pmu           *fake_pmu;
+       /* Skip actual tracepoint processing for testing. */
+       bool                       fake_tp;
        /* If non-null, when wildcard matching only match the given PMU. */
        const char                *pmu_filter;
        /* Should PE_LEGACY_NAME tokens be generated for config terms? */