Commit 3f980eab authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf pmu: Sort and remove duplicates using JSON PMU name

We may have a lot of copies of a particular uncore PMU, such as
uncore_cha_0 to uncore_cha_59 on Intel sapphirerapids.

The JSON events may match each of PMUs and so the events are copied to
it.

In 'perf list' this means we see the same JSON event 60 times as events
on different PMUs don't have duplicates removed.

There are 284 uncore_cha events on sapphirerapids.

Rather than use the PMU's name to sort and remove duplicates, use the
JSON PMU name.

This reduces the 60 copies back down to 1 and has the side effect of
speeding things like the "perf all PMU test" shell test.
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20230406235256.2768773-1-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 240e6fd0
......@@ -1574,7 +1574,7 @@ static int cmp_sevent(const void *a, const void *b)
{
const struct sevent *as = a;
const struct sevent *bs = b;
const char *a_pmu_name, *b_pmu_name;
const char *a_pmu_name = NULL, *b_pmu_name = NULL;
const char *a_name = "//", *a_desc = NULL, *a_topic = "";
const char *b_name = "//", *b_desc = NULL, *b_topic = "";
int ret;
......@@ -1583,11 +1583,13 @@ static int cmp_sevent(const void *a, const void *b)
a_name = as->event->name;
a_desc = as->event->desc;
a_topic = as->event->topic ?: "";
a_pmu_name = as->event->pmu_name;
}
if (bs->event) {
b_name = bs->event->name;
b_desc = bs->event->desc;
b_topic = bs->event->topic ?: "";
b_pmu_name = bs->event->pmu_name;
}
/* Put extra events last. */
if (!!a_desc != !!b_desc)
......@@ -1603,11 +1605,13 @@ static int cmp_sevent(const void *a, const void *b)
return as->is_cpu ? -1 : 1;
/* Order by PMU name. */
a_pmu_name = as->pmu->name ?: "";
b_pmu_name = bs->pmu->name ?: "";
ret = strcmp(a_pmu_name, b_pmu_name);
if (ret)
return ret;
if (as->pmu != bs->pmu) {
a_pmu_name = a_pmu_name ?: (as->pmu->name ?: "");
b_pmu_name = b_pmu_name ?: (bs->pmu->name ?: "");
ret = strcmp(a_pmu_name, b_pmu_name);
if (ret)
return ret;
}
/* Order by event name. */
return strcmp(a_name, b_name);
......@@ -1621,17 +1625,26 @@ bool is_pmu_core(const char *name)
static bool pmu_alias_is_duplicate(struct sevent *alias_a,
struct sevent *alias_b)
{
const char *a_pmu_name, *b_pmu_name;
const char *a_name = alias_a->event ? alias_a->event->name : "//";
const char *b_name = alias_b->event ? alias_b->event->name : "//";
const char *a_pmu_name = NULL, *b_pmu_name = NULL;
const char *a_name = "//", *b_name = "//";
if (alias_a->event) {
a_name = alias_a->event->name;
a_pmu_name = alias_a->event->pmu_name;
}
if (alias_b->event) {
b_name = alias_b->event->name;
b_pmu_name = alias_b->event->pmu_name;
}
/* Different names -> never duplicates */
if (strcmp(a_name, b_name))
return false;
/* Don't remove duplicates for different PMUs */
a_pmu_name = alias_a->pmu->name ?: "";
b_pmu_name = alias_b->pmu->name ?: "";
a_pmu_name = a_pmu_name ?: (alias_a->pmu->name ?: "");
b_pmu_name = b_pmu_name ?: (alias_b->pmu->name ?: "");
return strcmp(a_pmu_name, b_pmu_name) == 0;
}
......@@ -1680,7 +1693,8 @@ void print_pmu_events(const struct print_callbacks *print_cb, void *print_state)
for (j = 0; j < len; j++) {
const char *name, *alias = NULL, *scale_unit = NULL,
*desc = NULL, *long_desc = NULL,
*encoding_desc = NULL, *topic = NULL;
*encoding_desc = NULL, *topic = NULL,
*pmu_name = NULL;
bool deprecated = false;
size_t buf_used;
......@@ -1690,7 +1704,8 @@ void print_pmu_events(const struct print_callbacks *print_cb, void *print_state)
if (!aliases[j].event) {
/* A selectable event. */
buf_used = snprintf(buf, sizeof(buf), "%s//", aliases[j].pmu->name) + 1;
pmu_name = aliases[j].pmu->name;
buf_used = snprintf(buf, sizeof(buf), "%s//", pmu_name) + 1;
name = buf;
} else {
if (aliases[j].event->desc) {
......@@ -1705,6 +1720,7 @@ void print_pmu_events(const struct print_callbacks *print_cb, void *print_state)
}
buf_used = strlen(buf) + 1;
}
pmu_name = aliases[j].event->pmu_name ?: (aliases[j].pmu->name ?: "");
if (strlen(aliases[j].event->unit) || aliases[j].event->scale != 1.0) {
scale_unit = buf + buf_used;
buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used,
......@@ -1716,12 +1732,11 @@ void print_pmu_events(const struct print_callbacks *print_cb, void *print_state)
topic = aliases[j].event->topic;
encoding_desc = buf + buf_used;
buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used,
"%s/%s/", aliases[j].pmu->name,
aliases[j].event->str) + 1;
"%s/%s/", pmu_name, aliases[j].event->str) + 1;
deprecated = aliases[j].event->deprecated;
}
print_cb->print_event(print_state,
aliases[j].pmu->name,
pmu_name,
topic,
name,
alias,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment