From: Greg Kroah-Hartman Date: Tue, 8 Apr 2025 15:24:07 +0000 (+0200) Subject: 6.14-stable patches X-Git-Tag: v5.4.292~21 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=617775c1b5022b4b3f94a3bd023036b0336a0c02;p=thirdparty%2Fkernel%2Fstable-queue.git 6.14-stable patches added patches: include-topology-cpuset-move-dl_rebuild_rd_accounting-to-cpuset.h.patch perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch --- diff --git a/queue-6.14/include-topology-cpuset-move-dl_rebuild_rd_accounting-to-cpuset.h.patch b/queue-6.14/include-topology-cpuset-move-dl_rebuild_rd_accounting-to-cpuset.h.patch new file mode 100644 index 0000000000..67c4936f0a --- /dev/null +++ b/queue-6.14/include-topology-cpuset-move-dl_rebuild_rd_accounting-to-cpuset.h.patch @@ -0,0 +1,62 @@ +From 34929a070b7fd06c386080c926b61ee844e6ad34 Mon Sep 17 00:00:00 2001 +From: Juri Lelli +Date: Thu, 13 Mar 2025 18:13:29 +0100 +Subject: include/{topology,cpuset}: Move dl_rebuild_rd_accounting to cpuset.h + +From: Juri Lelli + +commit 34929a070b7fd06c386080c926b61ee844e6ad34 upstream. + +dl_rebuild_rd_accounting() is defined in cpuset.c, so it makes more +sense to move related declarations to cpuset.h. + +Implement the move. + +Suggested-by: Waiman Long +Signed-off-by: Juri Lelli +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Waiman Long +Reviewed-by: Valentin Schneider +Reviewed-by: Dietmar Eggemann +Tested-by: Waiman Long +Tested-by: Jon Hunter +Tested-by: Dietmar Eggemann +Link: https://lore.kernel.org/r/Z9MSOVMpU7jpVrMU@jlelli-thinkpadt14gen4.remote.csb +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/cpuset.h | 5 +++++ + include/linux/sched/topology.h | 2 -- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- a/include/linux/cpuset.h ++++ b/include/linux/cpuset.h +@@ -125,6 +125,7 @@ static inline int cpuset_do_page_mem_spr + + extern bool current_cpuset_is_being_rebound(void); + ++extern void dl_rebuild_rd_accounting(void); + extern void rebuild_sched_domains(void); + + extern void cpuset_print_current_mems_allowed(void); +@@ -260,6 +261,10 @@ static inline bool current_cpuset_is_bei + return false; + } + ++static inline void dl_rebuild_rd_accounting(void) ++{ ++} ++ + static inline void rebuild_sched_domains(void) + { + partition_sched_domains(1, NULL, NULL); +--- a/include/linux/sched/topology.h ++++ b/include/linux/sched/topology.h +@@ -166,8 +166,6 @@ static inline struct cpumask *sched_doma + return to_cpumask(sd->span); + } + +-extern void dl_rebuild_rd_accounting(void); +- + extern void partition_sched_domains_locked(int ndoms_new, + cpumask_var_t doms_new[], + struct sched_domain_attr *dattr_new); diff --git a/queue-6.14/perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch b/queue-6.14/perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch new file mode 100644 index 0000000000..878d34c85d --- /dev/null +++ b/queue-6.14/perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch @@ -0,0 +1,594 @@ +From 63e287131cf0c59b026053d6d63fe271604ffa7e Mon Sep 17 00:00:00 2001 +From: Ian Rogers +Date: Fri, 31 Jan 2025 23:43:18 -0800 +Subject: perf pmu: Rename name matching for no suffix or wildcard variants + +From: Ian Rogers + +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 +Reviewed-by: Kan Liang +Link: https://lore.kernel.org/r/20250201074320.746259-4-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -945,7 +945,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); +@@ -966,7 +966,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); +@@ -985,7 +985,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; +@@ -1104,7 +1104,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 +@@ -1660,7 +1660,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 +@@ -847,21 +847,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; + +@@ -887,60 +889,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) +@@ -1003,11 +1029,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, +@@ -1016,7 +1050,6 @@ static int pmu_add_sys_aliases_iter_fn(c + pe, + EVENT_SRC_SYS_JSON); + } +- + return 0; + } + +@@ -1975,15 +2008,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) +@@ -2230,29 +2330,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 +@@ -245,7 +245,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 +@@ -280,7 +281,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, diff --git a/queue-6.14/series b/queue-6.14/series index bf2cb9349f..5919a48ae5 100644 --- a/queue-6.14/series +++ b/queue-6.14/series @@ -727,3 +727,5 @@ nfsd-fix-management-of-listener-transports.patch nfsd-nfsd_unlink-clobbers-non-zero-status-returned-from-fh_fill_pre_attrs.patch nfsd-never-return-nfs4err_file_open-when-removing-a-directory.patch nfsd-skip-sending-cb_recall_any-when-the-backchannel-isn-t-up.patch +perf-pmu-rename-name-matching-for-no-suffix-or-wildcard-variants.patch +include-topology-cpuset-move-dl_rebuild_rd_accounting-to-cpuset.h.patch