Skip to content

Commit ce0a6d7

Browse files
committed
perf pmu: Allow hardcoded terms to be applied to attributes
JIRA: https://issues.redhat.com/browse/RHEL-77935 upstream ======== commit c798f72 Author: Ian Rogers <irogers@google.com> Date: Tue Oct 1 20:20:05 2024 -0700 description =========== Hard coded terms like "config=10" are skipped by perf_pmu__config assuming they were already applied to a perf_event_attr by parse event's config_attr function. When doing a reverse number to name lookup in perf_pmu__name_from_config, as the hardcoded terms aren't applied the config value is incorrect leading to misses or false matches. Fix this by adding a parameter to have perf_pmu__config apply hardcoded terms too (not just in parse event's config_term_common). Signed-off-by: Ian Rogers <irogers@google.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Link: https://lore.kernel.org/r/20241002032016.333748-3-irogers@google.com Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Michael Petlan <mpetlan@redhat.com>
1 parent ba4dcce commit ce0a6d7

File tree

5 files changed

+58
-12
lines changed

5 files changed

+58
-12
lines changed

tools/perf/arch/x86/util/intel-pt.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ static int intel_pt_parse_terms_with_default(const struct perf_pmu *pmu,
7575
goto out_free;
7676

7777
attr.config = *config;
78-
err = perf_pmu__config_terms(pmu, &attr, &terms, /*zero=*/true, /*err=*/NULL);
78+
err = perf_pmu__config_terms(pmu, &attr, &terms, /*zero=*/true, /*apply_hardcoded=*/false,
79+
/*err=*/NULL);
7980
if (err)
8081
goto out_free;
8182

tools/perf/tests/pmu.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ static int test__pmu_format(struct test_suite *test __maybe_unused, int subtest
176176
}
177177

178178
memset(&attr, 0, sizeof(attr));
179-
ret = perf_pmu__config_terms(pmu, &attr, &terms, /*zero=*/false, /*err=*/NULL);
179+
ret = perf_pmu__config_terms(pmu, &attr, &terms, /*zero=*/false,
180+
/*apply_hardcoded=*/false, /*err=*/NULL);
180181
if (ret) {
181182
pr_err("perf_pmu__config_terms failed");
182183
goto err_out;

tools/perf/util/parse-events.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,9 @@ static int parse_events_add_pmu(struct parse_events_state *parse_state,
15461546
return -ENOMEM;
15471547
}
15481548

1549-
if (perf_pmu__config(pmu, &attr, &parsed_terms, parse_state->error)) {
1549+
/* Skip configuring hard coded terms that were applied by config_attr. */
1550+
if (perf_pmu__config(pmu, &attr, &parsed_terms, /*apply_hardcoded=*/false,
1551+
parse_state->error)) {
15501552
free_config_terms(&config_terms);
15511553
parse_events_terms__exit(&parsed_terms);
15521554
return -EINVAL;

tools/perf/util/pmu.c

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,8 @@ static int pmu_config_term(const struct perf_pmu *pmu,
13761376
struct perf_event_attr *attr,
13771377
struct parse_events_term *term,
13781378
struct parse_events_terms *head_terms,
1379-
bool zero, struct parse_events_error *err)
1379+
bool zero, bool apply_hardcoded,
1380+
struct parse_events_error *err)
13801381
{
13811382
struct perf_pmu_format *format;
13821383
__u64 *vp;
@@ -1390,11 +1391,46 @@ static int pmu_config_term(const struct perf_pmu *pmu,
13901391
return 0;
13911392

13921393
/*
1393-
* Hardcoded terms should be already in, so nothing
1394-
* to be done for them.
1394+
* Hardcoded terms are generally handled in event parsing, which
1395+
* traditionally have had to handle not having a PMU. An alias may
1396+
* have hard coded config values, optionally apply them below.
13951397
*/
1396-
if (parse_events__is_hardcoded_term(term))
1398+
if (parse_events__is_hardcoded_term(term)) {
1399+
/* Config terms set all bits in the config. */
1400+
DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
1401+
1402+
if (!apply_hardcoded)
1403+
return 0;
1404+
1405+
bitmap_fill(bits, PERF_PMU_FORMAT_BITS);
1406+
1407+
switch (term->type_term) {
1408+
case PARSE_EVENTS__TERM_TYPE_CONFIG:
1409+
assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
1410+
pmu_format_value(bits, term->val.num, &attr->config, zero);
1411+
break;
1412+
case PARSE_EVENTS__TERM_TYPE_CONFIG1:
1413+
assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
1414+
pmu_format_value(bits, term->val.num, &attr->config1, zero);
1415+
break;
1416+
case PARSE_EVENTS__TERM_TYPE_CONFIG2:
1417+
assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
1418+
pmu_format_value(bits, term->val.num, &attr->config2, zero);
1419+
break;
1420+
case PARSE_EVENTS__TERM_TYPE_CONFIG3:
1421+
assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
1422+
pmu_format_value(bits, term->val.num, &attr->config3, zero);
1423+
break;
1424+
case PARSE_EVENTS__TERM_TYPE_USER: /* Not hardcoded. */
1425+
return -EINVAL;
1426+
case PARSE_EVENTS__TERM_TYPE_NAME ... PARSE_EVENTS__TERM_TYPE_HARDWARE:
1427+
/* Skip non-config terms. */
1428+
break;
1429+
default:
1430+
break;
1431+
}
13971432
return 0;
1433+
}
13981434

13991435
format = pmu_find_format(&pmu->format, term->config);
14001436
if (!format) {
@@ -1497,12 +1533,13 @@ static int pmu_config_term(const struct perf_pmu *pmu,
14971533
int perf_pmu__config_terms(const struct perf_pmu *pmu,
14981534
struct perf_event_attr *attr,
14991535
struct parse_events_terms *terms,
1500-
bool zero, struct parse_events_error *err)
1536+
bool zero, bool apply_hardcoded,
1537+
struct parse_events_error *err)
15011538
{
15021539
struct parse_events_term *term;
15031540

15041541
list_for_each_entry(term, &terms->terms, list) {
1505-
if (pmu_config_term(pmu, attr, term, terms, zero, err))
1542+
if (pmu_config_term(pmu, attr, term, terms, zero, apply_hardcoded, err))
15061543
return -EINVAL;
15071544
}
15081545

@@ -1516,6 +1553,7 @@ int perf_pmu__config_terms(const struct perf_pmu *pmu,
15161553
*/
15171554
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
15181555
struct parse_events_terms *head_terms,
1556+
bool apply_hardcoded,
15191557
struct parse_events_error *err)
15201558
{
15211559
bool zero = !!pmu->perf_event_attr_init_default;
@@ -1524,7 +1562,7 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
15241562
if (perf_pmu__is_fake(pmu))
15251563
return 0;
15261564

1527-
return perf_pmu__config_terms(pmu, attr, head_terms, zero, err);
1565+
return perf_pmu__config_terms(pmu, attr, head_terms, zero, apply_hardcoded, err);
15281566
}
15291567

15301568
static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
@@ -2293,7 +2331,9 @@ const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config)
22932331
pmu_add_cpu_aliases(pmu);
22942332
list_for_each_entry(event, &pmu->aliases, list) {
22952333
struct perf_event_attr attr = {.config = 0,};
2296-
int ret = perf_pmu__config(pmu, &attr, &event->terms, NULL);
2334+
2335+
int ret = perf_pmu__config(pmu, &attr, &event->terms, /*apply_hardcoded=*/true,
2336+
/*err=*/NULL);
22972337

22982338
if (ret == 0 && config == attr.config)
22992339
return event->name;

tools/perf/util/pmu.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,13 @@ typedef int (*pmu_format_callback)(void *state, const char *name, int config,
206206
void pmu_add_sys_aliases(struct perf_pmu *pmu);
207207
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
208208
struct parse_events_terms *head_terms,
209+
bool apply_hardcoded,
209210
struct parse_events_error *error);
210211
int perf_pmu__config_terms(const struct perf_pmu *pmu,
211212
struct perf_event_attr *attr,
212213
struct parse_events_terms *terms,
213-
bool zero, struct parse_events_error *error);
214+
bool zero, bool apply_hardcoded,
215+
struct parse_events_error *error);
214216
__u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name);
215217
int perf_pmu__format_type(struct perf_pmu *pmu, const char *name);
216218
int perf_pmu__check_alias(struct perf_pmu *pmu, struct parse_events_terms *head_terms,

0 commit comments

Comments
 (0)