summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/pmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/pmu.c')
-rw-r--r--tools/perf/util/pmu.c69
1 files changed, 51 insertions, 18 deletions
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index e0429f4ef335..55f4de6442e3 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/list.h>
#include <linux/compiler.h>
+#include <linux/string.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
@@ -394,7 +395,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
buf[ret] = 0;
/* Remove trailing newline from sysfs file */
- rtrim(buf);
+ strim(buf);
return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
NULL, NULL, NULL);
@@ -700,6 +701,46 @@ struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
return map;
}
+static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
+{
+ char *tmp = NULL, *tok, *str;
+ bool res;
+
+ str = strdup(pmu_name);
+ if (!str)
+ return false;
+
+ /*
+ * uncore alias may be from different PMU with common prefix
+ */
+ tok = strtok_r(str, ",", &tmp);
+ if (strncmp(pmu_name, tok, strlen(tok))) {
+ res = false;
+ goto out;
+ }
+
+ /*
+ * Match more complex aliases where the alias name is a comma-delimited
+ * list of tokens, orderly contained in the matching PMU name.
+ *
+ * Example: For alias "socket,pmuname" and PMU "socketX_pmunameY", we
+ * match "socket" in "socketX_pmunameY" and then "pmuname" in
+ * "pmunameY".
+ */
+ for (; tok; name += strlen(tok), tok = strtok_r(NULL, ",", &tmp)) {
+ name = strstr(name, tok);
+ if (!name) {
+ res = false;
+ goto out;
+ }
+ }
+
+ res = true;
+out:
+ free(str);
+ return res;
+}
+
/*
* From the pmu_events_map, find the table of PMU events that corresponds
* to the current running CPU. Then, add all PMU events from that table
@@ -709,9 +750,7 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
{
int i;
struct pmu_events_map *map;
- struct pmu_event *pe;
const char *name = pmu->name;
- const char *pname;
map = perf_pmu__find_map(pmu);
if (!map)
@@ -722,28 +761,22 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
*/
i = 0;
while (1) {
+ const char *cpu_name = is_arm_pmu_core(name) ? name : "cpu";
+ struct pmu_event *pe = &map->table[i++];
+ const char *pname = pe->pmu ? pe->pmu : cpu_name;
- pe = &map->table[i++];
if (!pe->name) {
if (pe->metric_group || pe->metric_name)
continue;
break;
}
- if (!is_arm_pmu_core(name)) {
- pname = pe->pmu ? pe->pmu : "cpu";
-
- /*
- * uncore alias may be from different PMU
- * with common prefix
- */
- if (pmu_is_uncore(name) &&
- !strncmp(pname, name, strlen(pname)))
- goto new_alias;
+ if (pmu_is_uncore(name) &&
+ pmu_uncore_alias_match(pname, name))
+ goto new_alias;
- if (strcmp(pname, name))
- continue;
- }
+ if (strcmp(pname, name))
+ continue;
new_alias:
/* need type casts to override 'const' */
@@ -1343,7 +1376,7 @@ static void wordwrap(char *s, int start, int max, int corr)
break;
s += wlen;
column += n;
- s = ltrim(s);
+ s = skip_spaces(s);
}
}