size_t priv_size;
};
-static int intel_pt_parse_terms_with_default(const char *pmu_name,
- struct list_head *formats,
+static int intel_pt_parse_terms_with_default(struct perf_pmu *pmu,
const char *str,
u64 *config)
{
goto out_free;
attr.config = *config;
- err = perf_pmu__config_terms(pmu_name, formats, &attr, terms, true,
- NULL);
+ err = perf_pmu__config_terms(pmu, &attr, terms, /*zero=*/true, /*err=*/NULL);
if (err)
goto out_free;
return err;
}
-static int intel_pt_parse_terms(const char *pmu_name, struct list_head *formats,
- const char *str, u64 *config)
+static int intel_pt_parse_terms(struct perf_pmu *pmu, const char *str, u64 *config)
{
*config = 0;
- return intel_pt_parse_terms_with_default(pmu_name, formats, str,
- config);
+ return intel_pt_parse_terms_with_default(pmu, str, config);
}
static u64 intel_pt_masked_bits(u64 mask, u64 bits)
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,
- &config);
+ intel_pt_parse_terms(intel_pt_pmu, buf, &config);
close(dirfd);
return config;
if (priv_size != ptr->priv_size)
return -EINVAL;
- intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
- "tsc", &tsc_bit);
- intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
- "noretcomp", &noretcomp_bit);
- intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
- "mtc", &mtc_bit);
+ intel_pt_parse_terms(intel_pt_pmu, "tsc", &tsc_bit);
+ intel_pt_parse_terms(intel_pt_pmu, "noretcomp", &noretcomp_bit);
+ intel_pt_parse_terms(intel_pt_pmu, "mtc", &mtc_bit);
mtc_freq_bits = perf_pmu__format_bits(&intel_pt_pmu->format,
"mtc_period");
- intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
- "cyc", &cyc_bit);
+ intel_pt_parse_terms(intel_pt_pmu, "cyc", &cyc_bit);
intel_pt_tsc_ctc_ratio(&tsc_ctc_ratio_n, &tsc_ctc_ratio_d);
intel_pt_evsel->core.attr.aux_watermark = aux_watermark;
}
- intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
- "tsc", &tsc_bit);
+ intel_pt_parse_terms(intel_pt_pmu, "tsc", &tsc_bit);
if (opts->full_auxtrace && (intel_pt_evsel->core.attr.config & tsc_bit))
have_timing_info = true;
#include <stdio.h>
#include <linux/kernel.h>
#include <linux/limits.h>
+#include <linux/zalloc.h>
/* Simulated format definitions. */
static struct test_format {
static int test__pmu(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
char dir[PATH_MAX];
- char *format = test_format_dir_get(dir, sizeof(dir));
- LIST_HEAD(formats);
+ char *format;
struct list_head *terms = test_terms_list();
+ struct perf_event_attr attr;
+ struct perf_pmu *pmu;
+ int fd;
int ret;
- if (!format)
- return -EINVAL;
-
- 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;
+ pmu = zalloc(sizeof(*pmu));
+ if (!pmu)
+ return -ENOMEM;
- 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)
- break;
- if (attr.config1 != 0x8000400000000145)
- break;
- if (attr.config2 != 0x0400000020041d07)
- break;
+ memset(&attr, 0, sizeof(attr));
- ret = 0;
- } while (0);
+ fd = open(format, O_DIRECTORY);
+ 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);
+ perf_pmu__delete(pmu);
return ret;
}
* Setup one of config[12] attr members based on the
* user input data - term parameter.
*/
-static int pmu_config_term(const char *pmu_name,
- struct list_head *formats,
+static int pmu_config_term(struct perf_pmu *pmu,
struct perf_event_attr *attr,
struct parse_events_term *term,
struct list_head *head_terms,
if (parse_events__is_hardcoded_term(term))
return 0;
- format = pmu_find_format(formats, term->config);
+ format = pmu_find_format(&pmu->format, term->config);
if (!format) {
- char *pmu_term = pmu_formats_string(formats);
+ char *pmu_term = pmu_formats_string(&pmu->format);
char *unknown_term;
char *help_msg;
if (asprintf(&unknown_term,
"unknown term '%s' for pmu '%s'",
- term->config, pmu_name) < 0)
+ term->config, pmu->name) < 0)
unknown_term = NULL;
help_msg = parse_events_formats_error_string(pmu_term);
if (err) {
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 list_head *head_terms,
bool zero, struct parse_events_error *err)
struct parse_events_term *term;
list_for_each_entry(term, head_terms, list) {
- if (pmu_config_term(pmu_name, formats, attr, term, head_terms,
- zero, err))
+ if (pmu_config_term(pmu, attr, term, head_terms, zero, err))
return -EINVAL;
}
{
bool zero = !!pmu->default_config;
- return perf_pmu__config_terms(pmu->name, &pmu->format, attr,
- head_terms, zero, err);
+ return perf_pmu__config_terms(pmu, attr, head_terms, zero, err);
}
static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
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;
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
struct list_head *head_terms,
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 list_head *head_terms,
bool zero, struct parse_events_error *error);
int perf_pmu__new_format(struct list_head *list, char *name,
int config, unsigned long *bits);
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 is_pmu_core(const char *name);