[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAP-5=fUx5oyCBtp2NO-h1mTC+ANt=uTOp9tS3rVN=CQFuXo00g@mail.gmail.com>
Date: Tue, 16 Sep 2025 08:49:48 -0700
From: Ian Rogers <irogers@...gle.com>
To: Mark Rutland <mark.rutland@....com>
Cc: Peter Zijlstra <peterz@...radead.org>, Ingo Molnar <mingo@...hat.com>,
Arnaldo Carvalho de Melo <acme@...nel.org>, Namhyung Kim <namhyung@...nel.org>,
Alexander Shishkin <alexander.shishkin@...ux.intel.com>, Jiri Olsa <jolsa@...nel.org>,
Adrian Hunter <adrian.hunter@...el.com>, Kan Liang <kan.liang@...ux.intel.com>,
James Clark <james.clark@...aro.org>, Xu Yang <xu.yang_2@....com>,
Thomas Falcon <thomas.falcon@...el.com>, Andi Kleen <ak@...ux.intel.com>,
linux-kernel@...r.kernel.org, linux-perf-users@...r.kernel.org,
bpf@...r.kernel.org, Atish Patra <atishp@...osinc.com>,
Beeman Strong <beeman@...osinc.com>, Leo Yan <leo.yan@....com>,
Vince Weaver <vincent.weaver@...ne.edu>
Subject: Re: [PATCH v4 20/21] perf parse-events: Add HW_CYCLES_STR as default
cycles event string
On Tue, Sep 16, 2025 at 6:18 AM Mark Rutland <mark.rutland@....com> wrote:
>
> On Sun, Sep 14, 2025 at 11:11:20AM -0700, Ian Rogers wrote:
> > ARM managed to significantly overload the meaning of the "cycles"
> > event in their PMU kernel drivers through sysfs.
>
> Ian, please stop phrasing this as if Arm have done something wrong here.
>
> It's true that some system PMU drivers have events named 'cycles'.
>
> It's not true that this is "overloading" the meaning of 'cycles'; those
> PMU-specific events were never intended to be conflated with the
> PERF_TYPE_HARDWARE events which have the same name.
>
> This was never a problem until the perf tool was changed to handle
> events such that it blindly assumed all events were in the same
> namespace. I have repeatedly explained that this was a bad idea.
>
> There is no reason that this should be handled in an ARM-specific way;
> if you want the bare 'cycles' event (withj no explcit PMU) to mean
> PERF_TYPE_HARDWARE:PERF_COUNT_HW_CPU_CYCLES, then *don't* match that
> with other PMU types. We cna specifically identify CPU PMUs which
> support that with the extended type ID if necessary.
Is the "cycles" event meaning uncore events a problem on anything
other than ARM, no.
Is having more than one event of the same name overloading the name,
by my definition yes.
Am I implying ARM has done something wrong? Well other than in fixing
a problem created by ARM's drivers..
Firstly, let's not pretend ARM has always elegantly supported the
legacy cycles event. When BIG.little came out, as you explained to me,
the legacy events would be opened on the first PMU registered with the
kernel. You would get legacy events on some fraction of the CPU cores.
ARM was reliant on a lot of seemingly correct behavior by having its
core PMU drivers appear as uncore ones. I am very much still in the
process of trying to clean up the tech debt and mess that falls out
from BIG.little and Intel's hybrid.
The behavior of legacy events with extended types and wildcarding.
This was introduced by Intel. The right moment to complain would have
been when Intel added the extended type and wildcarding support in the
kernel and perf tool. I wasn't even a reviewer on those patches.
Do ARM do things in their drivers that seem unthought through? Yes,
when hex suffixes of physical addresses were added to uncore PMU
drivers it was missed that a53 and a57 would also match this wildcard
suffix as ARM has unconventional core PMU names and the suffix on
those match as hex. We've worked around the issue by saying a hex
suffix must be longer than 3 characters but when ARM bumps up its CPU
names that will be broken. It seems there is some ambition to reinvent
rules when ARM drivers do things and the fallout has all too often had
to be fixed and addressed by me, with emails like this for thanks.
I'm sorry that you think I'm targeting ARM by fixing the issues your
drivers have introduced. It would have been better if ARM's drivers
didn't keep introducing issues. I'd repeat my call here that ARM add
support for the parse-events test for their PMUs. I don't understand
your last paragraph, in the context of the patch series it makes
little to no sense as the patch series is very much doing this.
Finally, doing things this way was prompted by James Clark's concerns
and I posted about this exact patch here:
https://lore.kernel.org/lkml/CAP-5=fUsZCz8Li1noKMODKXTLYFH9FsDCpXqCUxfu1h+s4c6Vw@mail.gmail.com/
ie I only added this patch at someone from Linaro's request and
received 0 feedback that doing so would be wrong. I don't think it is
and recommend this patch series for review.
Thanks,
Ian
> Mark.
>
> > In the tool use
> > "cpu-cycles" on ARM to avoid wildcard matching on different PMUS. This
> > is most commonly done in test code.
> >
> > Signed-off-by: Ian Rogers <irogers@...gle.com>
> > ---
> > tools/perf/builtin-stat.c | 4 +-
> > tools/perf/tests/code-reading.c | 4 +-
> > tools/perf/tests/keep-tracking.c | 2 +-
> > tools/perf/tests/parse-events.c | 100 ++++++++++++++--------------
> > tools/perf/tests/perf-time-to-tsc.c | 2 +-
> > tools/perf/tests/switch-tracking.c | 2 +-
> > tools/perf/util/evlist.c | 2 +-
> > tools/perf/util/parse-events.h | 10 +++
> > tools/perf/util/perf_api_probe.c | 4 +-
> > 9 files changed, 71 insertions(+), 59 deletions(-)
> >
> > diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> > index 2c38dd98f6ca..9f522b787ad5 100644
> > --- a/tools/perf/builtin-stat.c
> > +++ b/tools/perf/builtin-stat.c
> > @@ -1957,7 +1957,7 @@ static int add_default_events(void)
> > "cpu-migrations,"
> > "page-faults,"
> > "instructions,"
> > - "cycles,"
> > + HW_CYCLES_STR ","
> > "stalled-cycles-frontend,"
> > "stalled-cycles-backend,"
> > "branches,"
> > @@ -2043,7 +2043,7 @@ static int add_default_events(void)
> > * Make at least one event non-skippable so fatal errors are visible.
> > * 'cycles' always used to be default and non-skippable, so use that.
> > */
> > - if (strcmp("cycles", evsel__name(evsel)))
> > + if (strcmp(HW_CYCLES_STR, evsel__name(evsel)))
> > evsel->skippable = true;
> > }
> > }
> > diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
> > index 9c2091310191..baa44918f555 100644
> > --- a/tools/perf/tests/code-reading.c
> > +++ b/tools/perf/tests/code-reading.c
> > @@ -649,7 +649,9 @@ static int do_test_code_reading(bool try_kcore)
> > struct map *map;
> > bool have_vmlinux, have_kcore;
> > struct dso *dso;
> > - const char *events[] = { "cycles", "cycles:u", "cpu-clock", "cpu-clock:u", NULL };
> > + const char *events[] = {
> > + HW_CYCLES_STR, HW_CYCLES_STR ":u", "cpu-clock", "cpu-clock:u", NULL
> > + };
> > int evidx = 0;
> > struct perf_env host_env;
> >
> > diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
> > index eafb49eb0b56..d54ddb4db47b 100644
> > --- a/tools/perf/tests/keep-tracking.c
> > +++ b/tools/perf/tests/keep-tracking.c
> > @@ -90,7 +90,7 @@ static int test__keep_tracking(struct test_suite *test __maybe_unused, int subte
> > perf_evlist__set_maps(&evlist->core, cpus, threads);
> >
> > CHECK__(parse_event(evlist, "dummy:u"));
> > - CHECK__(parse_event(evlist, "cycles:u"));
> > + CHECK__(parse_event(evlist, HW_CYCLES_STR ":u"));
> >
> > evlist__config(evlist, &opts, NULL);
> >
> > diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
> > index 4e55b0d295bd..7d59648a0591 100644
> > --- a/tools/perf/tests/parse-events.c
> > +++ b/tools/perf/tests/parse-events.c
> > @@ -198,7 +198,7 @@ static int test__checkevent_symbolic_name_config(struct evlist *evlist)
> > TEST_ASSERT_VAL("wrong number of entries", 0 != evlist->core.nr_entries);
> >
> > perf_evlist__for_each_evsel(&evlist->core, evsel) {
> > - int ret = assert_hw(evsel, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + int ret = assert_hw(evsel, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> >
> > if (ret)
> > return ret;
> > @@ -884,7 +884,7 @@ static int test__group1(struct evlist *evlist)
> >
> > /* cycles:upp */
> > evsel = evsel__next(evsel);
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -948,7 +948,7 @@ static int test__group2(struct evlist *evlist)
> > continue;
> > }
> > /* cycles:k */
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1085,7 +1085,7 @@ static int test__group4(struct evlist *evlist __maybe_unused)
> >
> > /* cycles:u + p */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1133,7 +1133,7 @@ static int test__group5(struct evlist *evlist __maybe_unused)
> > for (int i = 0; i < num_core_entries(); i++) {
> > /* cycles + G */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1168,7 +1168,7 @@ static int test__group5(struct evlist *evlist __maybe_unused)
> > for (int i = 0; i < num_core_entries(); i++) {
> > /* cycles:G */
> > evsel = leader = evsel__next(evsel);
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1202,7 +1202,7 @@ static int test__group5(struct evlist *evlist __maybe_unused)
> > for (int i = 0; i < num_core_entries(); i++) {
> > /* cycles */
> > evsel = evsel__next(evsel);
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1231,7 +1231,7 @@ static int test__group_gh1(struct evlist *evlist)
> >
> > /* cycles + :H group modifier */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1278,7 +1278,7 @@ static int test__group_gh2(struct evlist *evlist)
> >
> > /* cycles + :G group modifier */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1325,7 +1325,7 @@ static int test__group_gh3(struct evlist *evlist)
> >
> > /* cycles:G + :u group modifier */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1372,7 +1372,7 @@ static int test__group_gh4(struct evlist *evlist)
> >
> > /* cycles:G + :uG group modifier */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1417,7 +1417,7 @@ static int test__leader_sample1(struct evlist *evlist)
> >
> > /* cycles - sampling group leader */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1540,7 +1540,7 @@ static int test__pinned_group(struct evlist *evlist)
> >
> > /* cycles - group leader */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1594,7 +1594,7 @@ static int test__exclusive_group(struct evlist *evlist)
> >
> > /* cycles - group leader */
> > evsel = leader = (i == 0 ? evlist__first(evlist) : evsel__next(evsel));
> > - ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> > if (ret)
> > return ret;
> >
> > @@ -1759,7 +1759,7 @@ static int test__checkevent_raw_pmu(struct evlist *evlist)
> > static int test__sym_event_slash(struct evlist *evlist)
> > {
> > struct evsel *evsel = evlist__first(evlist);
> > - int ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + int ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> >
> > if (ret)
> > return ret;
> > @@ -1771,7 +1771,7 @@ static int test__sym_event_slash(struct evlist *evlist)
> > static int test__sym_event_dc(struct evlist *evlist)
> > {
> > struct evsel *evsel = evlist__first(evlist);
> > - int ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + int ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> >
> > if (ret)
> > return ret;
> > @@ -1783,7 +1783,7 @@ static int test__sym_event_dc(struct evlist *evlist)
> > static int test__term_equal_term(struct evlist *evlist)
> > {
> > struct evsel *evsel = evlist__first(evlist);
> > - int ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + int ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> >
> > if (ret)
> > return ret;
> > @@ -1795,7 +1795,7 @@ static int test__term_equal_term(struct evlist *evlist)
> > static int test__term_equal_legacy(struct evlist *evlist)
> > {
> > struct evsel *evsel = evlist__first(evlist);
> > - int ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, "cycles");
> > + int ret = assert_hw(&evsel->core, PERF_COUNT_HW_CPU_CYCLES, HW_CYCLES_STR);
> >
> > if (ret)
> > return ret;
> > @@ -2006,27 +2006,27 @@ static const struct evlist_test test__events[] = {
> > /* 7 */
> > },
> > {
> > - .name = "{instructions:k,cycles:upp}",
> > + .name = "{instructions:k," HW_CYCLES_STR ":upp}",
> > .check = test__group1,
> > /* 8 */
> > },
> > {
> > - .name = "{faults:k,branches}:u,cycles:k",
> > + .name = "{faults:k,branches}:u," HW_CYCLES_STR ":k",
> > .check = test__group2,
> > /* 9 */
> > },
> > {
> > - .name = "group1{syscalls:sys_enter_openat:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u",
> > + .name = "group1{syscalls:sys_enter_openat:H," HW_CYCLES_STR ":kppp},group2{" HW_CYCLES_STR ",1:3}:G,instructions:u",
> > .check = test__group3,
> > /* 0 */
> > },
> > {
> > - .name = "{cycles:u,instructions:kp}:p",
> > + .name = "{" HW_CYCLES_STR ":u,instructions:kp}:p",
> > .check = test__group4,
> > /* 1 */
> > },
> > {
> > - .name = "{cycles,instructions}:G,{cycles:G,instructions:G},cycles",
> > + .name = "{" HW_CYCLES_STR ",instructions}:G,{" HW_CYCLES_STR ":G,instructions:G}," HW_CYCLES_STR,
> > .check = test__group5,
> > /* 2 */
> > },
> > @@ -2036,27 +2036,27 @@ static const struct evlist_test test__events[] = {
> > /* 3 */
> > },
> > {
> > - .name = "{cycles,cache-misses:G}:H",
> > + .name = "{" HW_CYCLES_STR ",cache-misses:G}:H",
> > .check = test__group_gh1,
> > /* 4 */
> > },
> > {
> > - .name = "{cycles,cache-misses:H}:G",
> > + .name = "{" HW_CYCLES_STR ",cache-misses:H}:G",
> > .check = test__group_gh2,
> > /* 5 */
> > },
> > {
> > - .name = "{cycles:G,cache-misses:H}:u",
> > + .name = "{" HW_CYCLES_STR ":G,cache-misses:H}:u",
> > .check = test__group_gh3,
> > /* 6 */
> > },
> > {
> > - .name = "{cycles:G,cache-misses:H}:uG",
> > + .name = "{" HW_CYCLES_STR ":G,cache-misses:H}:uG",
> > .check = test__group_gh4,
> > /* 7 */
> > },
> > {
> > - .name = "{cycles,cache-misses,branch-misses}:S",
> > + .name = "{" HW_CYCLES_STR ",cache-misses,branch-misses}:S",
> > .check = test__leader_sample1,
> > /* 8 */
> > },
> > @@ -2071,7 +2071,7 @@ static const struct evlist_test test__events[] = {
> > /* 0 */
> > },
> > {
> > - .name = "{cycles,cache-misses,branch-misses}:D",
> > + .name = "{" HW_CYCLES_STR ",cache-misses,branch-misses}:D",
> > .check = test__pinned_group,
> > /* 1 */
> > },
> > @@ -2109,7 +2109,7 @@ static const struct evlist_test test__events[] = {
> > /* 6 */
> > },
> > {
> > - .name = "task-clock:P,cycles",
> > + .name = "task-clock:P," HW_CYCLES_STR,
> > .check = test__checkevent_precise_max_modifier,
> > /* 7 */
> > },
> > @@ -2140,17 +2140,17 @@ static const struct evlist_test test__events[] = {
> > /* 2 */
> > },
> > {
> > - .name = "cycles/name='COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks'/Duk",
> > + .name = HW_CYCLES_STR "/name='COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks'/Duk",
> > .check = test__checkevent_complex_name,
> > /* 3 */
> > },
> > {
> > - .name = "cycles//u",
> > + .name = HW_CYCLES_STR "//u",
> > .check = test__sym_event_slash,
> > /* 4 */
> > },
> > {
> > - .name = "cycles:k",
> > + .name = HW_CYCLES_STR ":k",
> > .check = test__sym_event_dc,
> > /* 5 */
> > },
> > @@ -2160,17 +2160,17 @@ static const struct evlist_test test__events[] = {
> > /* 6 */
> > },
> > {
> > - .name = "{cycles,cache-misses,branch-misses}:e",
> > + .name = "{" HW_CYCLES_STR ",cache-misses,branch-misses}:e",
> > .check = test__exclusive_group,
> > /* 7 */
> > },
> > {
> > - .name = "cycles/name=name/",
> > + .name = HW_CYCLES_STR "/name=name/",
> > .check = test__term_equal_term,
> > /* 8 */
> > },
> > {
> > - .name = "cycles/name=l1d/",
> > + .name = HW_CYCLES_STR "/name=l1d/",
> > .check = test__term_equal_legacy,
> > /* 9 */
> > },
> > @@ -2311,7 +2311,7 @@ static const struct evlist_test test__events_pmu[] = {
> > /* 9 */
> > },
> > {
> > - .name = "cpu/cycles,period=100000,config2/",
> > + .name = "cpu/" HW_CYCLES_STR ",period=100000,config2/",
> > .valid = test__pmu_cpu_valid,
> > .check = test__checkevent_symbolic_name_config,
> > /* 0 */
> > @@ -2335,43 +2335,43 @@ static const struct evlist_test test__events_pmu[] = {
> > /* 3 */
> > },
> > {
> > - .name = "{cpu/instructions/k,cpu/cycles/upp}",
> > + .name = "{cpu/instructions/k,cpu/" HW_CYCLES_STR "/upp}",
> > .valid = test__pmu_cpu_valid,
> > .check = test__group1,
> > /* 4 */
> > },
> > {
> > - .name = "{cpu/cycles/u,cpu/instructions/kp}:p",
> > + .name = "{cpu/" HW_CYCLES_STR "/u,cpu/instructions/kp}:p",
> > .valid = test__pmu_cpu_valid,
> > .check = test__group4,
> > /* 5 */
> > },
> > {
> > - .name = "{cpu/cycles/,cpu/cache-misses/G}:H",
> > + .name = "{cpu/" HW_CYCLES_STR "/,cpu/cache-misses/G}:H",
> > .valid = test__pmu_cpu_valid,
> > .check = test__group_gh1,
> > /* 6 */
> > },
> > {
> > - .name = "{cpu/cycles/,cpu/cache-misses/H}:G",
> > + .name = "{cpu/" HW_CYCLES_STR "/,cpu/cache-misses/H}:G",
> > .valid = test__pmu_cpu_valid,
> > .check = test__group_gh2,
> > /* 7 */
> > },
> > {
> > - .name = "{cpu/cycles/G,cpu/cache-misses/H}:u",
> > + .name = "{cpu/" HW_CYCLES_STR "/G,cpu/cache-misses/H}:u",
> > .valid = test__pmu_cpu_valid,
> > .check = test__group_gh3,
> > /* 8 */
> > },
> > {
> > - .name = "{cpu/cycles/G,cpu/cache-misses/H}:uG",
> > + .name = "{cpu/" HW_CYCLES_STR "/G,cpu/cache-misses/H}:uG",
> > .valid = test__pmu_cpu_valid,
> > .check = test__group_gh4,
> > /* 9 */
> > },
> > {
> > - .name = "{cpu/cycles/,cpu/cache-misses/,cpu/branch-misses/}:S",
> > + .name = "{cpu/" HW_CYCLES_STR "/,cpu/cache-misses/,cpu/branch-misses/}:S",
> > .valid = test__pmu_cpu_valid,
> > .check = test__leader_sample1,
> > /* 0 */
> > @@ -2389,7 +2389,7 @@ static const struct evlist_test test__events_pmu[] = {
> > /* 2 */
> > },
> > {
> > - .name = "{cpu/cycles/,cpu/cache-misses/,cpu/branch-misses/}:D",
> > + .name = "{cpu/" HW_CYCLES_STR "/,cpu/cache-misses/,cpu/branch-misses/}:D",
> > .valid = test__pmu_cpu_valid,
> > .check = test__pinned_group,
> > /* 3 */
> > @@ -2407,13 +2407,13 @@ static const struct evlist_test test__events_pmu[] = {
> > /* 5 */
> > },
> > {
> > - .name = "cpu/cycles/u",
> > + .name = "cpu/" HW_CYCLES_STR "/u",
> > .valid = test__pmu_cpu_valid,
> > .check = test__sym_event_slash,
> > /* 6 */
> > },
> > {
> > - .name = "cpu/cycles/k",
> > + .name = "cpu/" HW_CYCLES_STR "/k",
> > .valid = test__pmu_cpu_valid,
> > .check = test__sym_event_dc,
> > /* 7 */
> > @@ -2425,19 +2425,19 @@ static const struct evlist_test test__events_pmu[] = {
> > /* 8 */
> > },
> > {
> > - .name = "{cpu/cycles/,cpu/cache-misses/,cpu/branch-misses/}:e",
> > + .name = "{cpu/" HW_CYCLES_STR "/,cpu/cache-misses/,cpu/branch-misses/}:e",
> > .valid = test__pmu_cpu_valid,
> > .check = test__exclusive_group,
> > /* 9 */
> > },
> > {
> > - .name = "cpu/cycles,name=name/",
> > + .name = "cpu/" HW_CYCLES_STR ",name=name/",
> > .valid = test__pmu_cpu_valid,
> > .check = test__term_equal_term,
> > /* 0 */
> > },
> > {
> > - .name = "cpu/cycles,name=l1d/",
> > + .name = "cpu/" HW_CYCLES_STR ",name=l1d/",
> > .valid = test__pmu_cpu_valid,
> > .check = test__term_equal_legacy,
> > /* 1 */
> > diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
> > index d4437410c99f..7ebcb1f004b2 100644
> > --- a/tools/perf/tests/perf-time-to-tsc.c
> > +++ b/tools/perf/tests/perf-time-to-tsc.c
> > @@ -101,7 +101,7 @@ static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int su
> >
> > perf_evlist__set_maps(&evlist->core, cpus, threads);
> >
> > - CHECK__(parse_event(evlist, "cycles:u"));
> > + CHECK__(parse_event(evlist, HW_CYCLES_STR ":u"));
> >
> > evlist__config(evlist, &opts, NULL);
> >
> > diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
> > index 5be294014d3b..ad3a87978c0d 100644
> > --- a/tools/perf/tests/switch-tracking.c
> > +++ b/tools/perf/tests/switch-tracking.c
> > @@ -332,7 +332,7 @@ static int process_events(struct evlist *evlist,
> > static int test__switch_tracking(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
> > {
> > const char *sched_switch = "sched:sched_switch";
> > - const char *cycles = "cycles:u";
> > + const char *cycles = HW_CYCLES_STR ":u";
> > struct switch_tracking switch_tracking = { .tids = NULL, };
> > struct record_opts opts = {
> > .mmap_pages = UINT_MAX,
> > diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> > index e8217efdda53..d7e935faeda0 100644
> > --- a/tools/perf/util/evlist.c
> > +++ b/tools/perf/util/evlist.c
> > @@ -112,7 +112,7 @@ struct evlist *evlist__new_default(void)
> > char buf[256];
> > int err;
> >
> > - snprintf(buf, sizeof(buf), "%s/cycles/%s", pmu->name,
> > + snprintf(buf, sizeof(buf), "%s/%s/%s", pmu->name, HW_CYCLES_STR,
> > can_profile_kernel ? "P" : "Pu");
> > err = parse_event(evlist, buf);
> > if (err) {
> > diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
> > index db92cd67bc0f..304676bf32dd 100644
> > --- a/tools/perf/util/parse-events.h
> > +++ b/tools/perf/util/parse-events.h
> > @@ -20,6 +20,16 @@ struct option;
> > struct perf_pmu;
> > struct strbuf;
> >
> > +/*
> > + * The name used for the "cycles" event. A different event name is used on ARM
> > + * as many ARM PMUs define a "cycles" event.
> > + */
> > +#if defined(__aarch64__) || defined(__arm__)
> > +#define HW_CYCLES_STR "cpu-cycles"
> > +#else
> > +#define HW_CYCLES_STR "cycles"
> > +#endif
> > +
> > const char *event_type(size_t type);
> >
> > /* Arguments encoded in opt->value. */
> > diff --git a/tools/perf/util/perf_api_probe.c b/tools/perf/util/perf_api_probe.c
> > index 6ecf38314f01..693bb5891bc4 100644
> > --- a/tools/perf/util/perf_api_probe.c
> > +++ b/tools/perf/util/perf_api_probe.c
> > @@ -74,9 +74,9 @@ static bool perf_probe_api(setup_probe_fn_t fn)
> > if (!ret)
> > return true;
> >
> > - pmu = perf_pmus__scan_core(/*pmu=*/NULL);
> > + pmu = perf_pmus__find_core_pmu();
> > if (pmu) {
> > - const char *try[] = {"cycles", "instructions", NULL};
> > + const char *try[] = {HW_CYCLES_STR, "instructions", NULL};
> > char buf[256];
> > int i = 0;
> >
> > --
> > 2.51.0.384.g4c02a37b29-goog
> >
Powered by blists - more mailing lists