]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.13-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Apr 2025 15:22:23 +0000 (17:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Apr 2025 15:22:23 +0000 (17:22 +0200)
added patches:
perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch

queue-6.13/perf-pmu-don-t-double-count-common-sysfs-and-json-ev.patch
queue-6.13/perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch [new file with mode: 0644]
queue-6.13/series

index 36e6adfb26183e5c8fc36b4bdaaa17865cb5b8cf..4412d8abce44ee578d9f79cac0fa6a37a3386298 100644 (file)
@@ -30,15 +30,13 @@ Link: https://lore.kernel.org/r/20250226104111.564443-3-james.clark@linaro.org
 Signed-off-by: Namhyung Kim <namhyung@kernel.org>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
- tools/perf/util/pmu.c | 7 ++++---
- tools/perf/util/pmu.h | 5 +++++
+ tools/perf/util/pmu.c |    7 ++++---
+ tools/perf/util/pmu.h |    5 +++++
  2 files changed, 9 insertions(+), 3 deletions(-)
 
-diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
-index d217678631ff5..d9a9fa7d49ec3 100644
 --- a/tools/perf/util/pmu.c
 +++ b/tools/perf/util/pmu.c
-@@ -595,7 +595,7 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
+@@ -595,7 +595,7 @@ static int perf_pmu__new_alias(struct pe
                        };
                        if (pmu_events_table__find_event(pmu->events_table, pmu, name,
                                                         update_alias, &data) == 0)
@@ -47,7 +45,7 @@ index d217678631ff5..d9a9fa7d49ec3 100644
                }
                pmu->sysfs_aliases++;
                break;
-@@ -1840,9 +1840,10 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu)
+@@ -1873,9 +1873,10 @@ size_t perf_pmu__num_events(struct perf_
        if (pmu->cpu_aliases_added)
                 nr += pmu->cpu_json_aliases;
        else if (pmu->events_table)
@@ -60,8 +58,6 @@ index d217678631ff5..d9a9fa7d49ec3 100644
  
        if (perf_pmu__is_tool(pmu))
                nr -= tool_pmu__num_skip_events();
-diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
-index dbed6c243a5ef..55005cc3caffc 100644
 --- a/tools/perf/util/pmu.h
 +++ b/tools/perf/util/pmu.h
 @@ -134,6 +134,11 @@ struct perf_pmu {
@@ -76,6 +72,3 @@ index dbed6c243a5ef..55005cc3caffc 100644
        /** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */
        bool sysfs_aliases_loaded;
        /**
--- 
-2.39.5
-
diff --git a/queue-6.13/perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch b/queue-6.13/perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch
new file mode 100644 (file)
index 0000000..90d3c95
--- /dev/null
@@ -0,0 +1,594 @@
+From 63e287131cf0c59b026053d6d63fe271604ffa7e Mon Sep 17 00:00:00 2001
+From: Ian Rogers <irogers@google.com>
+Date: Fri, 31 Jan 2025 23:43:18 -0800
+Subject: perf pmu: Rename name matching for no suffix or wildcard variants
+
+From: Ian Rogers <irogers@google.com>
+
+commit 63e287131cf0c59b026053d6d63fe271604ffa7e upstream.
+
+Wildcard PMU naming will match a name like pmu_1 to a PMU name like
+pmu_10 but not to a PMU name like pmu_2 as the suffix forms part of
+the match. No suffix matching will match pmu_10 to either pmu_1 or
+pmu_2. Add or rename matching functions on PMU to make it clearer what
+kind of matching is being performed.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lore.kernel.org/r/20250201074320.746259-4-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/perf/pmu-events/empty-pmu-events.c |    8 
+ tools/perf/pmu-events/jevents.py         |    8 
+ tools/perf/tests/pmu.c                   |   85 +++++-----
+ tools/perf/util/parse-events.c           |    2 
+ tools/perf/util/pmu.c                    |  258 +++++++++++++++++++++----------
+ tools/perf/util/pmu.h                    |    5 
+ 6 files changed, 236 insertions(+), 130 deletions(-)
+
+--- a/tools/perf/pmu-events/empty-pmu-events.c
++++ b/tools/perf/pmu-events/empty-pmu-events.c
+@@ -422,7 +422,7 @@ int pmu_events_table__for_each_event(con
+                 const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+                 int ret;
+-                if (pmu && !pmu__name_match(pmu, pmu_name))
++                if (pmu && !perf_pmu__name_wildcard_match(pmu, pmu_name))
+                         continue;
+                 ret = pmu_events_table__for_each_event_pmu(table, table_pmu, fn, data);
+@@ -443,7 +443,7 @@ int pmu_events_table__find_event(const s
+                 const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+                 int ret;
+-                if (!pmu__name_match(pmu, pmu_name))
++                if (!perf_pmu__name_wildcard_match(pmu, pmu_name))
+                         continue;
+                 ret = pmu_events_table__find_event_pmu(table, table_pmu, name, fn, data);
+@@ -462,7 +462,7 @@ size_t pmu_events_table__num_events(cons
+                 const struct pmu_table_entry *table_pmu = &table->pmus[i];
+                 const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+-                if (pmu__name_match(pmu, pmu_name))
++                if (perf_pmu__name_wildcard_match(pmu, pmu_name))
+                         count += table_pmu->num_entries;
+         }
+         return count;
+@@ -581,7 +581,7 @@ const struct pmu_events_table *perf_pmu_
+                 const struct pmu_table_entry *table_pmu = &map->event_table.pmus[i];
+                 const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+-                if (pmu__name_match(pmu, pmu_name))
++                if (perf_pmu__name_wildcard_match(pmu, pmu_name))
+                          return &map->event_table;
+         }
+         return NULL;
+--- a/tools/perf/pmu-events/jevents.py
++++ b/tools/perf/pmu-events/jevents.py
+@@ -938,7 +938,7 @@ int pmu_events_table__for_each_event(con
+                 const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+                 int ret;
+-                if (pmu && !pmu__name_match(pmu, pmu_name))
++                if (pmu && !perf_pmu__name_wildcard_match(pmu, pmu_name))
+                         continue;
+                 ret = pmu_events_table__for_each_event_pmu(table, table_pmu, fn, data);
+@@ -959,7 +959,7 @@ int pmu_events_table__find_event(const s
+                 const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+                 int ret;
+-                if (!pmu__name_match(pmu, pmu_name))
++                if (!perf_pmu__name_wildcard_match(pmu, pmu_name))
+                         continue;
+                 ret = pmu_events_table__find_event_pmu(table, table_pmu, name, fn, data);
+@@ -978,7 +978,7 @@ size_t pmu_events_table__num_events(cons
+                 const struct pmu_table_entry *table_pmu = &table->pmus[i];
+                 const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+-                if (pmu__name_match(pmu, pmu_name))
++                if (perf_pmu__name_wildcard_match(pmu, pmu_name))
+                         count += table_pmu->num_entries;
+         }
+         return count;
+@@ -1097,7 +1097,7 @@ const struct pmu_events_table *perf_pmu_
+                 const struct pmu_table_entry *table_pmu = &map->event_table.pmus[i];
+                 const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+-                if (pmu__name_match(pmu, pmu_name))
++                if (perf_pmu__name_wildcard_match(pmu, pmu_name))
+                          return &map->event_table;
+         }
+         return NULL;
+--- a/tools/perf/tests/pmu.c
++++ b/tools/perf/tests/pmu.c
+@@ -452,9 +452,9 @@ static int test__name_cmp(struct test_su
+ }
+ /**
+- * Test perf_pmu__match() that's used to search for a PMU given a name passed
++ * Test perf_pmu__wildcard_match() that's used to search for a PMU given a name passed
+  * on the command line. The name that's passed may also be a filename type glob
+- * match. If the name does not match, perf_pmu__match() attempts to match the
++ * match. If the name does not match, perf_pmu__wildcard_match() attempts to match the
+  * alias of the PMU, if provided.
+  */
+ static int test__pmu_match(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
+@@ -463,41 +463,44 @@ static int test__pmu_match(struct test_s
+               .name = "pmuname",
+       };
+-      TEST_ASSERT_EQUAL("Exact match", perf_pmu__match(&test_pmu, "pmuname"),      true);
+-      TEST_ASSERT_EQUAL("Longer token", perf_pmu__match(&test_pmu, "longertoken"), false);
+-      TEST_ASSERT_EQUAL("Shorter token", perf_pmu__match(&test_pmu, "pmu"),        false);
++#define TEST_PMU_MATCH(msg, to_match, expect)                         \
++      TEST_ASSERT_EQUAL(msg, perf_pmu__wildcard_match(&test_pmu, to_match), expect)
++
++      TEST_PMU_MATCH("Exact match", "pmuname", true);
++      TEST_PMU_MATCH("Longer token", "longertoken", false);
++      TEST_PMU_MATCH("Shorter token", "pmu", false);
+       test_pmu.name = "pmuname_10";
+-      TEST_ASSERT_EQUAL("Diff suffix_", perf_pmu__match(&test_pmu, "pmuname_2"),  false);
+-      TEST_ASSERT_EQUAL("Sub suffix_",  perf_pmu__match(&test_pmu, "pmuname_1"),  true);
+-      TEST_ASSERT_EQUAL("Same suffix_", perf_pmu__match(&test_pmu, "pmuname_10"), true);
+-      TEST_ASSERT_EQUAL("No suffix_",   perf_pmu__match(&test_pmu, "pmuname"),    true);
+-      TEST_ASSERT_EQUAL("Underscore_",  perf_pmu__match(&test_pmu, "pmuname_"),   true);
+-      TEST_ASSERT_EQUAL("Substring_",   perf_pmu__match(&test_pmu, "pmuna"),      false);
++      TEST_PMU_MATCH("Diff suffix_", "pmuname_2", false);
++      TEST_PMU_MATCH("Sub suffix_", "pmuname_1", true);
++      TEST_PMU_MATCH("Same suffix_", "pmuname_10", true);
++      TEST_PMU_MATCH("No suffix_", "pmuname", true);
++      TEST_PMU_MATCH("Underscore_", "pmuname_", true);
++      TEST_PMU_MATCH("Substring_", "pmuna", false);
+       test_pmu.name = "pmuname_ab23";
+-      TEST_ASSERT_EQUAL("Diff suffix hex_", perf_pmu__match(&test_pmu, "pmuname_2"),    false);
+-      TEST_ASSERT_EQUAL("Sub suffix hex_",  perf_pmu__match(&test_pmu, "pmuname_ab"),   true);
+-      TEST_ASSERT_EQUAL("Same suffix hex_", perf_pmu__match(&test_pmu, "pmuname_ab23"), true);
+-      TEST_ASSERT_EQUAL("No suffix hex_",   perf_pmu__match(&test_pmu, "pmuname"),      true);
+-      TEST_ASSERT_EQUAL("Underscore hex_",  perf_pmu__match(&test_pmu, "pmuname_"),     true);
+-      TEST_ASSERT_EQUAL("Substring hex_",   perf_pmu__match(&test_pmu, "pmuna"),       false);
++      TEST_PMU_MATCH("Diff suffix hex_", "pmuname_2", false);
++      TEST_PMU_MATCH("Sub suffix hex_", "pmuname_ab", true);
++      TEST_PMU_MATCH("Same suffix hex_", "pmuname_ab23", true);
++      TEST_PMU_MATCH("No suffix hex_", "pmuname", true);
++      TEST_PMU_MATCH("Underscore hex_", "pmuname_", true);
++      TEST_PMU_MATCH("Substring hex_", "pmuna", false);
+       test_pmu.name = "pmuname10";
+-      TEST_ASSERT_EQUAL("Diff suffix", perf_pmu__match(&test_pmu, "pmuname2"),  false);
+-      TEST_ASSERT_EQUAL("Sub suffix",  perf_pmu__match(&test_pmu, "pmuname1"),  true);
+-      TEST_ASSERT_EQUAL("Same suffix", perf_pmu__match(&test_pmu, "pmuname10"), true);
+-      TEST_ASSERT_EQUAL("No suffix",   perf_pmu__match(&test_pmu, "pmuname"),   true);
+-      TEST_ASSERT_EQUAL("Underscore",  perf_pmu__match(&test_pmu, "pmuname_"),  false);
+-      TEST_ASSERT_EQUAL("Substring",   perf_pmu__match(&test_pmu, "pmuna"),     false);
++      TEST_PMU_MATCH("Diff suffix", "pmuname2", false);
++      TEST_PMU_MATCH("Sub suffix", "pmuname1", true);
++      TEST_PMU_MATCH("Same suffix", "pmuname10", true);
++      TEST_PMU_MATCH("No suffix", "pmuname", true);
++      TEST_PMU_MATCH("Underscore", "pmuname_", false);
++      TEST_PMU_MATCH("Substring", "pmuna", false);
+       test_pmu.name = "pmunameab23";
+-      TEST_ASSERT_EQUAL("Diff suffix hex", perf_pmu__match(&test_pmu, "pmuname2"),    false);
+-      TEST_ASSERT_EQUAL("Sub suffix hex",  perf_pmu__match(&test_pmu, "pmunameab"),   true);
+-      TEST_ASSERT_EQUAL("Same suffix hex", perf_pmu__match(&test_pmu, "pmunameab23"), true);
+-      TEST_ASSERT_EQUAL("No suffix hex",   perf_pmu__match(&test_pmu, "pmuname"),     true);
+-      TEST_ASSERT_EQUAL("Underscore hex",  perf_pmu__match(&test_pmu, "pmuname_"),    false);
+-      TEST_ASSERT_EQUAL("Substring hex",   perf_pmu__match(&test_pmu, "pmuna"),       false);
++      TEST_PMU_MATCH("Diff suffix hex", "pmuname2", false);
++      TEST_PMU_MATCH("Sub suffix hex", "pmunameab", true);
++      TEST_PMU_MATCH("Same suffix hex", "pmunameab23", true);
++      TEST_PMU_MATCH("No suffix hex", "pmuname", true);
++      TEST_PMU_MATCH("Underscore hex", "pmuname_", false);
++      TEST_PMU_MATCH("Substring hex",   "pmuna", false);
+       /*
+        * 2 hex chars or less are not considered suffixes so it shouldn't be
+@@ -505,7 +508,7 @@ static int test__pmu_match(struct test_s
+        * false results here than above.
+        */
+       test_pmu.name = "pmuname_a3";
+-      TEST_ASSERT_EQUAL("Diff suffix 2 hex_", perf_pmu__match(&test_pmu, "pmuname_2"),  false);
++      TEST_PMU_MATCH("Diff suffix 2 hex_", "pmuname_2", false);
+       /*
+        * This one should be false, but because pmuname_a3 ends in 3 which is
+        * decimal, it's not possible to determine if it's a short hex suffix or
+@@ -513,19 +516,19 @@ static int test__pmu_match(struct test_s
+        * length of decimal suffix. Run the test anyway and expect the wrong
+        * result. And slightly fuzzy matching shouldn't do too much harm.
+        */
+-      TEST_ASSERT_EQUAL("Sub suffix 2 hex_",  perf_pmu__match(&test_pmu, "pmuname_a"),  true);
+-      TEST_ASSERT_EQUAL("Same suffix 2 hex_", perf_pmu__match(&test_pmu, "pmuname_a3"), true);
+-      TEST_ASSERT_EQUAL("No suffix 2 hex_",   perf_pmu__match(&test_pmu, "pmuname"),    false);
+-      TEST_ASSERT_EQUAL("Underscore 2 hex_",  perf_pmu__match(&test_pmu, "pmuname_"),   false);
+-      TEST_ASSERT_EQUAL("Substring 2 hex_",   perf_pmu__match(&test_pmu, "pmuna"),      false);
++      TEST_PMU_MATCH("Sub suffix 2 hex_", "pmuname_a", true);
++      TEST_PMU_MATCH("Same suffix 2 hex_", "pmuname_a3", true);
++      TEST_PMU_MATCH("No suffix 2 hex_", "pmuname", false);
++      TEST_PMU_MATCH("Underscore 2 hex_", "pmuname_", false);
++      TEST_PMU_MATCH("Substring 2 hex_", "pmuna", false);
+       test_pmu.name = "pmuname_5";
+-      TEST_ASSERT_EQUAL("Glob 1", perf_pmu__match(&test_pmu, "pmu*"),            true);
+-      TEST_ASSERT_EQUAL("Glob 2", perf_pmu__match(&test_pmu, "nomatch*"),        false);
+-      TEST_ASSERT_EQUAL("Seq 1",  perf_pmu__match(&test_pmu, "pmuname_[12345]"), true);
+-      TEST_ASSERT_EQUAL("Seq 2",  perf_pmu__match(&test_pmu, "pmuname_[67890]"), false);
+-      TEST_ASSERT_EQUAL("? 1",    perf_pmu__match(&test_pmu, "pmuname_?"),       true);
+-      TEST_ASSERT_EQUAL("? 2",    perf_pmu__match(&test_pmu, "pmuname_1?"),      false);
++      TEST_PMU_MATCH("Glob 1", "pmu*", true);
++      TEST_PMU_MATCH("Glob 2", "nomatch*", false);
++      TEST_PMU_MATCH("Seq 1", "pmuname_[12345]", true);
++      TEST_PMU_MATCH("Seq 2", "pmuname_[67890]", false);
++      TEST_PMU_MATCH("? 1", "pmuname_?", true);
++      TEST_PMU_MATCH("? 2", "pmuname_1?", false);
+       return TEST_OK;
+ }
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -1664,7 +1664,7 @@ int parse_events_multi_pmu_add_or_add_pm
+       /* Failed to add, try wildcard expansion of event_or_pmu as a PMU name. */
+       while ((pmu = perf_pmus__scan(pmu)) != NULL) {
+               if (!parse_events__filter_pmu(parse_state, pmu) &&
+-                  perf_pmu__match(pmu, event_or_pmu)) {
++                  perf_pmu__wildcard_match(pmu, event_or_pmu)) {
+                       bool auto_merge_stats = perf_pmu__auto_merge_stats(pmu);
+                       if (!parse_events_add_pmu(parse_state, *listp, pmu,
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -837,21 +837,23 @@ static size_t pmu_deduped_name_len(const
+ }
+ /**
+- * perf_pmu__match_ignoring_suffix - Does the pmu_name match tok ignoring any
+- *                                   trailing suffix? The Suffix must be in form
+- *                                   tok_{digits}, or tok{digits}.
++ * perf_pmu__match_wildcard - Does the pmu_name start with tok and is then only
++ *                            followed by nothing or a suffix? tok may contain
++ *                            part of a suffix.
+  * @pmu_name: The pmu_name with possible suffix.
+- * @tok: The possible match to pmu_name without suffix.
++ * @tok: The wildcard argument to match.
+  */
+-static bool perf_pmu__match_ignoring_suffix(const char *pmu_name, const char *tok)
++static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
+ {
+       const char *p, *suffix;
+       bool has_hex = false;
++      size_t tok_len = strlen(tok);
+-      if (strncmp(pmu_name, tok, strlen(tok)))
++      /* Check start of pmu_name for equality. */
++      if (strncmp(pmu_name, tok, tok_len))
+               return false;
+-      suffix = p = pmu_name + strlen(tok);
++      suffix = p = pmu_name + tok_len;
+       if (*p == 0)
+               return true;
+@@ -877,60 +879,84 @@ static bool perf_pmu__match_ignoring_suf
+ }
+ /**
+- * pmu_uncore_alias_match - does name match the PMU name?
+- * @pmu_name: the json struct pmu_event name. This may lack a suffix (which
+- *            matches) or be of the form "socket,pmuname" which will match
+- *            "socketX_pmunameY".
+- * @name: a real full PMU name as from sysfs.
++ * perf_pmu__match_ignoring_suffix_uncore - Does the pmu_name match tok ignoring
++ *                                          any trailing suffix on pmu_name and
++ *                                          tok?  The Suffix must be in form
++ *                                          tok_{digits}, or tok{digits}.
++ * @pmu_name: The pmu_name with possible suffix.
++ * @tok: The possible match to pmu_name.
+  */
+-static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
++static bool perf_pmu__match_ignoring_suffix_uncore(const char *pmu_name, const char *tok)
+ {
+-      char *tmp = NULL, *tok, *str;
+-      bool res;
++      size_t pmu_name_len, tok_len;
+-      if (strchr(pmu_name, ',') == NULL)
+-              return perf_pmu__match_ignoring_suffix(name, pmu_name);
++      /* For robustness, check for NULL. */
++      if (pmu_name == NULL)
++              return tok == NULL;
++
++      /* uncore_ prefixes are ignored. */
++      if (!strncmp(pmu_name, "uncore_", 7))
++              pmu_name += 7;
++      if (!strncmp(tok, "uncore_", 7))
++              tok += 7;
+-      str = strdup(pmu_name);
+-      if (!str)
++      pmu_name_len = pmu_name_len_no_suffix(pmu_name);
++      tok_len = pmu_name_len_no_suffix(tok);
++      if (pmu_name_len != tok_len)
+               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;
+-      }
++      return strncmp(pmu_name, tok, pmu_name_len) == 0;
++}
+-      /*
+-       * 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".
+-       */
+-      while (1) {
+-              char *next_tok = strtok_r(NULL, ",", &tmp);
+-              name = strstr(name, tok);
+-              if (!name ||
+-                  (!next_tok && !perf_pmu__match_ignoring_suffix(name, tok))) {
+-                      res = false;
+-                      goto out;
++/**
++ * perf_pmu__match_wildcard_uncore - does to_match match the PMU's name?
++ * @pmu_name: The pmu->name or pmu->alias to match against.
++ * @to_match: the json struct pmu_event name. This may lack a suffix (which
++ *            matches) or be of the form "socket,pmuname" which will match
++ *            "socketX_pmunameY".
++ */
++static bool perf_pmu__match_wildcard_uncore(const char *pmu_name, const char *to_match)
++{
++      char *mutable_to_match, *tok, *tmp;
++
++      if (!pmu_name)
++              return false;
++
++      /* uncore_ prefixes are ignored. */
++      if (!strncmp(pmu_name, "uncore_", 7))
++              pmu_name += 7;
++      if (!strncmp(to_match, "uncore_", 7))
++              to_match += 7;
++
++      if (strchr(to_match, ',') == NULL)
++              return perf_pmu__match_wildcard(pmu_name, to_match);
++
++      /* Process comma separated list of PMU name components. */
++      mutable_to_match = strdup(to_match);
++      if (!mutable_to_match)
++              return false;
++
++      tok = strtok_r(mutable_to_match, ",", &tmp);
++      while (tok) {
++              size_t tok_len = strlen(tok);
++
++              if (strncmp(pmu_name, tok, tok_len)) {
++                      /* Mismatch between part of pmu_name and tok. */
++                      free(mutable_to_match);
++                      return false;
+               }
+-              if (!next_tok)
+-                      break;
+-              tok = next_tok;
+-              name += strlen(tok);
+-      }
++              /* Move pmu_name forward over tok and suffix. */
++              pmu_name += tok_len;
++              while (*pmu_name != '\0' && isdigit(*pmu_name))
++                      pmu_name++;
++              if (*pmu_name == '_')
++                      pmu_name++;
+-      res = true;
+-out:
+-      free(str);
+-      return res;
++              tok = strtok_r(NULL, ",", &tmp);
++      }
++      free(mutable_to_match);
++      return *pmu_name == '\0';
+ }
+ bool pmu_uncore_identifier_match(const char *compat, const char *id)
+@@ -993,11 +1019,19 @@ static int pmu_add_sys_aliases_iter_fn(c
+ {
+       struct perf_pmu *pmu = vdata;
+-      if (!pe->compat || !pe->pmu)
++      if (!pe->compat || !pe->pmu) {
++              /* No data to match. */
+               return 0;
++      }
+-      if (pmu_uncore_alias_match(pe->pmu, pmu->name) &&
+-          pmu_uncore_identifier_match(pe->compat, pmu->id)) {
++      if (!perf_pmu__match_wildcard_uncore(pmu->name, pe->pmu) &&
++          !perf_pmu__match_wildcard_uncore(pmu->alias_name, pe->pmu)) {
++              /* PMU name/alias_name don't match. */
++              return 0;
++      }
++
++      if (pmu_uncore_identifier_match(pe->compat, pmu->id)) {
++              /* Id matched. */
+               perf_pmu__new_alias(pmu,
+                               pe->name,
+                               pe->desc,
+@@ -1006,7 +1040,6 @@ static int pmu_add_sys_aliases_iter_fn(c
+                               pe,
+                               EVENT_SRC_SYS_JSON);
+       }
+-
+       return 0;
+ }
+@@ -1963,15 +1996,82 @@ out:
+       return ret;
+ }
+-bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name)
++static bool perf_pmu___name_match(const struct perf_pmu *pmu, const char *to_match, bool wildcard)
+ {
+-      return !strcmp(pmu->name, pmu_name) ||
+-              (pmu->is_uncore && pmu_uncore_alias_match(pmu_name, pmu->name)) ||
++      const char *names[2] = {
++              pmu->name,
++              pmu->alias_name,
++      };
++      if (pmu->is_core) {
++              for (size_t i = 0; i < ARRAY_SIZE(names); i++) {
++                      const char *name = names[i];
++
++                      if (!name)
++                              continue;
++
++                      if (!strcmp(name, to_match)) {
++                              /* Exact name match. */
++                              return true;
++                      }
++              }
++              if (!strcmp(to_match, "default_core")) {
++                      /*
++                       * jevents and tests use default_core as a marker for any core
++                       * PMU as the PMU name varies across architectures.
++                       */
++                      return true;
++              }
++              return false;
++      }
++      if (!pmu->is_uncore) {
+               /*
+-               * jevents and tests use default_core as a marker for any core
+-               * PMU as the PMU name varies across architectures.
++               * PMU isn't core or uncore, some kind of broken CPU mask
++               * situation. Only match exact name.
+                */
+-              (pmu->is_core && !strcmp(pmu_name, "default_core"));
++              for (size_t i = 0; i < ARRAY_SIZE(names); i++) {
++                      const char *name = names[i];
++
++                      if (!name)
++                              continue;
++
++                      if (!strcmp(name, to_match)) {
++                              /* Exact name match. */
++                              return true;
++                      }
++              }
++              return false;
++      }
++      for (size_t i = 0; i < ARRAY_SIZE(names); i++) {
++              const char *name = names[i];
++
++              if (wildcard && perf_pmu__match_wildcard_uncore(name, to_match))
++                      return true;
++              if (!wildcard && perf_pmu__match_ignoring_suffix_uncore(name, to_match))
++                      return true;
++      }
++      return false;
++}
++
++/**
++ * perf_pmu__name_wildcard_match - Called by the jevents generated code to see
++ *                                 if pmu matches the json to_match string.
++ * @pmu: The pmu whose name/alias to match.
++ * @to_match: The possible match to pmu_name.
++ */
++bool perf_pmu__name_wildcard_match(const struct perf_pmu *pmu, const char *to_match)
++{
++      return perf_pmu___name_match(pmu, to_match, /*wildcard=*/true);
++}
++
++/**
++ * perf_pmu__name_no_suffix_match - Does pmu's name match to_match ignoring any
++ *                                  trailing suffix on the pmu_name and/or tok?
++ * @pmu: The pmu whose name/alias to match.
++ * @to_match: The possible match to pmu_name.
++ */
++bool perf_pmu__name_no_suffix_match(const struct perf_pmu *pmu, const char *to_match)
++{
++      return perf_pmu___name_match(pmu, to_match, /*wildcard=*/false);
+ }
+ bool perf_pmu__is_software(const struct perf_pmu *pmu)
+@@ -2218,29 +2318,31 @@ void perf_pmu__warn_invalid_config(struc
+                  name ?: "N/A", buf, config_name, config);
+ }
+-bool perf_pmu__match(const struct perf_pmu *pmu, const char *tok)
++bool perf_pmu__wildcard_match(const struct perf_pmu *pmu, const char *wildcard_to_match)
+ {
+-      const char *name = pmu->name;
+-      bool need_fnmatch = strisglob(tok);
++      const char *names[2] = {
++              pmu->name,
++              pmu->alias_name,
++      };
++      bool need_fnmatch = strisglob(wildcard_to_match);
+-      if (!strncmp(tok, "uncore_", 7))
+-              tok += 7;
+-      if (!strncmp(name, "uncore_", 7))
+-              name += 7;
++      if (!strncmp(wildcard_to_match, "uncore_", 7))
++              wildcard_to_match += 7;
+-      if (perf_pmu__match_ignoring_suffix(name, tok) ||
+-          (need_fnmatch && !fnmatch(tok, name, 0)))
+-              return true;
++      for (size_t i = 0; i < ARRAY_SIZE(names); i++) {
++              const char *pmu_name = names[i];
+-      name = pmu->alias_name;
+-      if (!name)
+-              return false;
++              if (!pmu_name)
++                      continue;
+-      if (!strncmp(name, "uncore_", 7))
+-              name += 7;
++              if (!strncmp(pmu_name, "uncore_", 7))
++                      pmu_name += 7;
+-      return perf_pmu__match_ignoring_suffix(name, tok) ||
+-              (need_fnmatch && !fnmatch(tok, name, 0));
++              if (perf_pmu__match_wildcard(pmu_name, wildcard_to_match) ||
++                  (need_fnmatch && !fnmatch(wildcard_to_match, pmu_name, 0)))
++                      return true;
++      }
++      return false;
+ }
+ int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size)
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -238,7 +238,8 @@ bool perf_pmu__have_event(struct perf_pm
+ size_t perf_pmu__num_events(struct perf_pmu *pmu);
+ int perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmus,
+                            void *state, pmu_event_callback cb);
+-bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name);
++bool perf_pmu__name_wildcard_match(const struct perf_pmu *pmu, const char *to_match);
++bool perf_pmu__name_no_suffix_match(const struct perf_pmu *pmu, const char *to_match);
+ /**
+  * perf_pmu_is_software - is the PMU a software PMU as in it uses the
+@@ -273,7 +274,7 @@ void perf_pmu__warn_invalid_config(struc
+                                  const char *config_name);
+ void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu);
+-bool perf_pmu__match(const struct perf_pmu *pmu, const char *tok);
++bool perf_pmu__wildcard_match(const struct perf_pmu *pmu, const char *wildcard_to_match);
+ int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size);
+ int perf_pmu__pathname_scnprintf(char *buf, size_t size,
index 2e3da0c2c51460b36e0381e61061bf64fd78fd79..773f3c3259d13740da7e9bf360e6d5ed498d9a0b 100644 (file)
@@ -202,6 +202,7 @@ staging-gpib-fix-pr_err-format-warning.patch
 iio-dac-adi-axi-dac-modify-stream-enable.patch
 perf-test-fix-hwmon-pmu-test-endianess-issue.patch
 perf-stat-don-t-merge-counters-purely-on-name.patch
+perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch
 fs-ntfs3-update-inode-i_mapping-a_ops-on-compression.patch
 phy-phy-rockchip-samsung-hdptx-don-t-use-dt-aliases-.patch
 perf-tools-add-skip-check-in-tool_pmu__event_to_str.patch