Commit 804fee5d authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf pmu: Avoid passing format list to perf_pmu__config_terms()

Abstract the format list better, hiding it in the PMU, by changing
perf_pmu__config_terms() the PMU rather than the format list in the PMU.

Change the PMU test to pass a dummy PMU for this purpose. Changing the
test allows perf_pmu__del_formats() to become static.
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: Gaosheng Cui <cuigaosheng1@huawei.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
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>
Link: https://lore.kernel.org/r/20230823080828.1460376-6-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 6f2f6eaf
...@@ -60,8 +60,7 @@ struct intel_pt_recording { ...@@ -60,8 +60,7 @@ struct intel_pt_recording {
size_t priv_size; size_t priv_size;
}; };
static int intel_pt_parse_terms_with_default(const char *pmu_name, static int intel_pt_parse_terms_with_default(struct perf_pmu *pmu,
struct list_head *formats,
const char *str, const char *str,
u64 *config) u64 *config)
{ {
...@@ -80,8 +79,7 @@ static int intel_pt_parse_terms_with_default(const char *pmu_name, ...@@ -80,8 +79,7 @@ static int intel_pt_parse_terms_with_default(const char *pmu_name,
goto out_free; goto out_free;
attr.config = *config; attr.config = *config;
err = perf_pmu__config_terms(pmu_name, formats, &attr, terms, true, err = perf_pmu__config_terms(pmu, &attr, terms, /*zero=*/true, /*err=*/NULL);
NULL);
if (err) if (err)
goto out_free; goto out_free;
...@@ -91,12 +89,10 @@ static int intel_pt_parse_terms_with_default(const char *pmu_name, ...@@ -91,12 +89,10 @@ static int intel_pt_parse_terms_with_default(const char *pmu_name,
return err; return err;
} }
static int intel_pt_parse_terms(const char *pmu_name, struct list_head *formats, static int intel_pt_parse_terms(struct perf_pmu *pmu, const char *str, u64 *config)
const char *str, u64 *config)
{ {
*config = 0; *config = 0;
return intel_pt_parse_terms_with_default(pmu_name, formats, str, return intel_pt_parse_terms_with_default(pmu, str, config);
config);
} }
static u64 intel_pt_masked_bits(u64 mask, u64 bits) static u64 intel_pt_masked_bits(u64 mask, u64 bits)
...@@ -236,8 +232,7 @@ static u64 intel_pt_default_config(struct perf_pmu *intel_pt_pmu) ...@@ -236,8 +232,7 @@ static u64 intel_pt_default_config(struct perf_pmu *intel_pt_pmu)
pr_debug2("%s default config: %s\n", intel_pt_pmu->name, buf); pr_debug2("%s default config: %s\n", intel_pt_pmu->name, buf);
intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, buf, intel_pt_parse_terms(intel_pt_pmu, buf, &config);
&config);
close(dirfd); close(dirfd);
return config; return config;
...@@ -348,16 +343,12 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, ...@@ -348,16 +343,12 @@ static int intel_pt_info_fill(struct auxtrace_record *itr,
if (priv_size != ptr->priv_size) if (priv_size != ptr->priv_size)
return -EINVAL; return -EINVAL;
intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, intel_pt_parse_terms(intel_pt_pmu, "tsc", &tsc_bit);
"tsc", &tsc_bit); intel_pt_parse_terms(intel_pt_pmu, "noretcomp", &noretcomp_bit);
intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, intel_pt_parse_terms(intel_pt_pmu, "mtc", &mtc_bit);
"noretcomp", &noretcomp_bit);
intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
"mtc", &mtc_bit);
mtc_freq_bits = perf_pmu__format_bits(&intel_pt_pmu->format, mtc_freq_bits = perf_pmu__format_bits(&intel_pt_pmu->format,
"mtc_period"); "mtc_period");
intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, intel_pt_parse_terms(intel_pt_pmu, "cyc", &cyc_bit);
"cyc", &cyc_bit);
intel_pt_tsc_ctc_ratio(&tsc_ctc_ratio_n, &tsc_ctc_ratio_d); intel_pt_tsc_ctc_ratio(&tsc_ctc_ratio_n, &tsc_ctc_ratio_d);
...@@ -781,8 +772,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, ...@@ -781,8 +772,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
intel_pt_evsel->core.attr.aux_watermark = aux_watermark; intel_pt_evsel->core.attr.aux_watermark = aux_watermark;
} }
intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, intel_pt_parse_terms(intel_pt_pmu, "tsc", &tsc_bit);
"tsc", &tsc_bit);
if (opts->full_auxtrace && (intel_pt_evsel->core.attr.config & tsc_bit)) if (opts->full_auxtrace && (intel_pt_evsel->core.attr.config & tsc_bit))
have_timing_info = true; have_timing_info = true;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/limits.h> #include <linux/limits.h>
#include <linux/zalloc.h>
/* Simulated format definitions. */ /* Simulated format definitions. */
static struct test_format { static struct test_format {
...@@ -141,48 +142,55 @@ static struct list_head *test_terms_list(void) ...@@ -141,48 +142,55 @@ static struct list_head *test_terms_list(void)
static int test__pmu(struct test_suite *test __maybe_unused, int subtest __maybe_unused) static int test__pmu(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{ {
char dir[PATH_MAX]; char dir[PATH_MAX];
char *format = test_format_dir_get(dir, sizeof(dir)); char *format;
LIST_HEAD(formats);
struct list_head *terms = test_terms_list(); struct list_head *terms = test_terms_list();
struct perf_event_attr attr;
struct perf_pmu *pmu;
int fd;
int ret; int ret;
if (!format) pmu = zalloc(sizeof(*pmu));
return -EINVAL; if (!pmu)
return -ENOMEM;
do {
struct perf_event_attr attr;
int fd;
memset(&attr, 0, sizeof(attr));
fd = open(format, O_DIRECTORY);
if (fd < 0) {
ret = fd;
break;
}
ret = perf_pmu__format_parse(fd, &formats);
if (ret)
break;
ret = perf_pmu__config_terms("perf-pmu-test", &formats, &attr,
terms, false, NULL);
if (ret)
break;
ret = -EINVAL; INIT_LIST_HEAD(&pmu->format);
INIT_LIST_HEAD(&pmu->aliases);
INIT_LIST_HEAD(&pmu->caps);
format = test_format_dir_get(dir, sizeof(dir));
if (!format) {
free(pmu);
return -EINVAL;
}
if (attr.config != 0xc00000000002a823) memset(&attr, 0, sizeof(attr));
break;
if (attr.config1 != 0x8000400000000145)
break;
if (attr.config2 != 0x0400000020041d07)
break;
ret = 0; fd = open(format, O_DIRECTORY);
} while (0); if (fd < 0) {
ret = fd;
goto out;
}
perf_pmu__del_formats(&formats); pmu->name = strdup("perf-pmu-test");
ret = perf_pmu__format_parse(fd, &pmu->format);
if (ret)
goto out;
ret = perf_pmu__config_terms(pmu, &attr, terms, /*zero=*/false, /*err=*/NULL);
if (ret)
goto out;
ret = -EINVAL;
if (attr.config != 0xc00000000002a823)
goto out;
if (attr.config1 != 0x8000400000000145)
goto out;
if (attr.config2 != 0x0400000020041d07)
goto out;
ret = 0;
out:
test_format_dir_put(format); test_format_dir_put(format);
perf_pmu__delete(pmu);
return ret; return ret;
} }
......
...@@ -1135,8 +1135,7 @@ static char *pmu_formats_string(struct list_head *formats) ...@@ -1135,8 +1135,7 @@ static char *pmu_formats_string(struct list_head *formats)
* Setup one of config[12] attr members based on the * Setup one of config[12] attr members based on the
* user input data - term parameter. * user input data - term parameter.
*/ */
static int pmu_config_term(const char *pmu_name, static int pmu_config_term(struct perf_pmu *pmu,
struct list_head *formats,
struct perf_event_attr *attr, struct perf_event_attr *attr,
struct parse_events_term *term, struct parse_events_term *term,
struct list_head *head_terms, struct list_head *head_terms,
...@@ -1160,15 +1159,15 @@ static int pmu_config_term(const char *pmu_name, ...@@ -1160,15 +1159,15 @@ static int pmu_config_term(const char *pmu_name,
if (parse_events__is_hardcoded_term(term)) if (parse_events__is_hardcoded_term(term))
return 0; return 0;
format = pmu_find_format(formats, term->config); format = pmu_find_format(&pmu->format, term->config);
if (!format) { if (!format) {
char *pmu_term = pmu_formats_string(formats); char *pmu_term = pmu_formats_string(&pmu->format);
char *unknown_term; char *unknown_term;
char *help_msg; char *help_msg;
if (asprintf(&unknown_term, if (asprintf(&unknown_term,
"unknown term '%s' for pmu '%s'", "unknown term '%s' for pmu '%s'",
term->config, pmu_name) < 0) term->config, pmu->name) < 0)
unknown_term = NULL; unknown_term = NULL;
help_msg = parse_events_formats_error_string(pmu_term); help_msg = parse_events_formats_error_string(pmu_term);
if (err) { if (err) {
...@@ -1259,7 +1258,7 @@ static int pmu_config_term(const char *pmu_name, ...@@ -1259,7 +1258,7 @@ static int pmu_config_term(const char *pmu_name,
return 0; return 0;
} }
int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats, int perf_pmu__config_terms(struct perf_pmu *pmu,
struct perf_event_attr *attr, struct perf_event_attr *attr,
struct list_head *head_terms, struct list_head *head_terms,
bool zero, struct parse_events_error *err) bool zero, struct parse_events_error *err)
...@@ -1267,8 +1266,7 @@ int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats, ...@@ -1267,8 +1266,7 @@ int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats,
struct parse_events_term *term; struct parse_events_term *term;
list_for_each_entry(term, head_terms, list) { list_for_each_entry(term, head_terms, list) {
if (pmu_config_term(pmu_name, formats, attr, term, head_terms, if (pmu_config_term(pmu, attr, term, head_terms, zero, err))
zero, err))
return -EINVAL; return -EINVAL;
} }
...@@ -1286,8 +1284,7 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, ...@@ -1286,8 +1284,7 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
{ {
bool zero = !!pmu->default_config; bool zero = !!pmu->default_config;
return perf_pmu__config_terms(pmu->name, &pmu->format, attr, return perf_pmu__config_terms(pmu, attr, head_terms, zero, err);
head_terms, zero, err);
} }
static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
...@@ -1417,7 +1414,7 @@ int perf_pmu__new_format(struct list_head *list, char *name, ...@@ -1417,7 +1414,7 @@ int perf_pmu__new_format(struct list_head *list, char *name,
return 0; return 0;
} }
void perf_pmu__del_formats(struct list_head *formats) static void perf_pmu__del_formats(struct list_head *formats)
{ {
struct perf_pmu_format *fmt, *tmp; struct perf_pmu_format *fmt, *tmp;
......
...@@ -217,7 +217,7 @@ void pmu_add_sys_aliases(struct list_head *head, struct perf_pmu *pmu); ...@@ -217,7 +217,7 @@ void pmu_add_sys_aliases(struct list_head *head, struct perf_pmu *pmu);
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
struct list_head *head_terms, struct list_head *head_terms,
struct parse_events_error *error); struct parse_events_error *error);
int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats, int perf_pmu__config_terms(struct perf_pmu *pmu,
struct perf_event_attr *attr, struct perf_event_attr *attr,
struct list_head *head_terms, struct list_head *head_terms,
bool zero, struct parse_events_error *error); bool zero, struct parse_events_error *error);
...@@ -231,7 +231,6 @@ struct list_head *perf_pmu__alias(struct perf_pmu *pmu, ...@@ -231,7 +231,6 @@ struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
int perf_pmu__new_format(struct list_head *list, char *name, int perf_pmu__new_format(struct list_head *list, char *name,
int config, unsigned long *bits); int config, unsigned long *bits);
int perf_pmu__format_parse(int dirfd, struct list_head *head); int perf_pmu__format_parse(int dirfd, struct list_head *head);
void perf_pmu__del_formats(struct list_head *formats);
bool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name); bool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name);
bool is_pmu_core(const char *name); bool is_pmu_core(const char *name);
......
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