/* used for matching against events from generated pmu-events.c */
struct pmu_event event;
- /* used for matching against event aliases */
- /* extra events for aliases */
- const char *alias_str;
-
/*
* Note: For when PublicDescription does not exist in the JSON, we
* will have no long_desc in pmu_event.long_desc, but long_desc may
.desc = "L1 BTB Correction",
.topic = "branch",
},
- .alias_str = "event=0x8a",
};
static const struct perf_pmu_test_event bp_l2_btb_correct = {
.desc = "L2 BTB Correction",
.topic = "branch",
},
- .alias_str = "event=0x8b",
};
static const struct perf_pmu_test_event segment_reg_loads_any = {
.desc = "Number of segment register loads",
.topic = "other",
},
- .alias_str = "event=0x6,period=0x30d40,umask=0x80",
};
static const struct perf_pmu_test_event dispatch_blocked_any = {
.desc = "Memory cluster signals to block micro-op dispatch for any reason",
.topic = "other",
},
- .alias_str = "event=0x9,period=0x30d40,umask=0x20",
};
static const struct perf_pmu_test_event eist_trans = {
.desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions",
.topic = "other",
},
- .alias_str = "event=0x3a,period=0x30d40",
};
static const struct perf_pmu_test_event l3_cache_rd = {
.long_desc = "Attributable Level 3 cache access, read",
.topic = "cache",
},
- .alias_str = "event=0x40",
.alias_long_desc = "Attributable Level 3 cache access, read",
};
.topic = "uncore",
.pmu = "hisi_sccl,ddrc",
},
- .alias_str = "event=0x2",
.matching_pmu = "hisi_sccl1_ddrc2",
};
.topic = "uncore",
.pmu = "uncore_cbox",
},
- .alias_str = "event=0x22,umask=0x81",
.matching_pmu = "uncore_cbox_0",
};
.topic = "uncore",
.pmu = "uncore_cbox",
},
- .alias_str = "event=0xe0",
.matching_pmu = "uncore_cbox_0",
};
.topic = "uncore",
.pmu = "uncore_cbox",
},
- .alias_str = "event=0xc0",
.matching_pmu = "uncore_cbox_0",
};
.topic = "uncore",
.pmu = "hisi_sccl,l3c",
},
- .alias_str = "event=0x7",
.matching_pmu = "hisi_sccl3_l3c7",
};
.topic = "uncore",
.pmu = "uncore_imc_free_running",
},
- .alias_str = "event=0x12",
.matching_pmu = "uncore_imc_free_running_0",
};
.topic = "uncore",
.pmu = "uncore_imc",
},
- .alias_str = "event=0x34",
.matching_pmu = "uncore_imc_0",
};
.pmu = "uncore_sys_ddr_pmu",
.compat = "v8",
},
- .alias_str = "event=0x2b",
.matching_pmu = "uncore_sys_ddr_pmu0",
};
.pmu = "uncore_sys_ccn_pmu",
.compat = "0x01",
},
- .alias_str = "config=0x2c",
.matching_pmu = "uncore_sys_ccn_pmu4",
};
.pmu = "uncore_sys_cmn_pmu",
.compat = "(434|436|43c|43a).*",
},
- .alias_str = "eventid=0x1,type=0x5",
.matching_pmu = "uncore_sys_cmn_pmu0",
};
return -1;
}
- if (!is_same(alias->str, test_event->alias_str)) {
+ if (!is_same(alias->str, test_event->event.event)) {
pr_debug("testing aliases PMU %s: mismatched str, %s vs %s\n",
- pmu_name, alias->str, test_event->alias_str);
+ pmu_name, alias->str, test_event->event.event);
return -1;
}
* json events.
*/
char *topic;
- /** @terms: Owned list of the original parsed parameters. */
- struct parse_events_terms terms;
+ /** @terms: Owned copy of the event terms. */
+ char *terms;
/**
* @pmu_name: The name copied from the json struct pmu_event. This can
* differ from the PMU name as it won't have suffixes.
zfree(&alias->long_desc);
zfree(&alias->topic);
zfree(&alias->pmu_name);
- parse_events_terms__exit(&alias->terms);
+ zfree(&alias->terms);
free(alias);
}
assign_str(pe->name, "topic", &data->alias->topic, pe->topic);
data->alias->per_pkg = pe->perpkg;
if (pe->event) {
- parse_events_terms__exit(&data->alias->terms);
- ret = parse_events_terms(&data->alias->terms, pe->event, /*input=*/NULL);
+ zfree(&data->alias->terms);
+ data->alias->terms = strdup(pe->event);
}
if (!ret && pe->unit) {
char *unit;
if (!alias)
return -ENOMEM;
- parse_events_terms__init(&alias->terms);
alias->scale = 1.0;
alias->unit[0] = '\0';
alias->per_pkg = perpkg;
if (ret)
return ret;
- ret = parse_events_terms(&alias->terms, val, val_fd);
- if (ret) {
- pr_err("Cannot parse alias %s: %d\n", val, ret);
- free(alias);
- return ret;
+ if (!val_fd) {
+ alias->terms = strdup(val);
+ } else {
+ size_t line_len;
+
+ ret = getline(&alias->terms, &line_len, val_fd) < 0 ? -errno : 0;
+ if (ret) {
+ pr_err("Failed to read alias %s\n", name);
+ return ret;
+ }
}
alias->name = strdup(name);
return ret;
}
-static int pmu_alias_terms(struct perf_pmu_alias *alias, int err_loc, struct list_head *terms)
+static int pmu_alias_terms(struct perf_pmu_alias *alias, struct list_head *terms)
{
- struct parse_events_term *term, *cloned;
- struct parse_events_terms clone_terms;
-
- parse_events_terms__init(&clone_terms);
- list_for_each_entry(term, &alias->terms.terms, list) {
- int ret = parse_events_term__clone(&cloned, term);
+ struct parse_events_terms alias_terms;
+ int ret;
- if (ret) {
- parse_events_terms__exit(&clone_terms);
- return ret;
- }
- /*
- * Weak terms don't override command line options,
- * which we don't want for implicit terms in aliases.
- */
- cloned->weak = true;
- cloned->err_term = cloned->err_val = err_loc;
- list_add_tail(&cloned->list, &clone_terms.terms);
+ parse_events_terms__init(&alias_terms);
+ ret = parse_events_terms(&alias_terms, alias->terms, /*input=*/NULL);
+ if (ret) {
+ pr_err("Cannot parse '%s' terms '%s': %d\n",
+ alias->name, alias->terms, ret);
+ parse_events_terms__exit(&alias_terms);
+ return ret;
}
- list_splice_init(&clone_terms.terms, terms);
- parse_events_terms__exit(&clone_terms);
+ list_splice_init(&alias_terms.terms, terms);
+ parse_events_terms__exit(&alias_terms);
return 0;
}
alias = pmu_find_alias(pmu, term);
if (!alias)
continue;
- ret = pmu_alias_terms(alias, term->err_term, &term->list);
+ ret = pmu_alias_terms(alias, &term->list);
if (ret) {
parse_events_error__handle(err, term->err_term,
- strdup("Failure to duplicate terms"),
+ strdup("Failed to parse terms"),
NULL);
return ret;
}
static char *format_alias(char *buf, int len, const struct perf_pmu *pmu,
const struct perf_pmu_alias *alias, bool skip_duplicate_pmus)
{
+ struct parse_events_terms terms;
struct parse_events_term *term;
+ int ret, used;
size_t pmu_name_len = pmu_deduped_name_len(pmu, pmu->name,
skip_duplicate_pmus);
- int used = snprintf(buf, len, "%.*s/%s", (int)pmu_name_len, pmu->name, alias->name);
- list_for_each_entry(term, &alias->terms.terms, list) {
+ /* Paramemterized events have the parameters shown. */
+ if (strstr(alias->terms, "=?")) {
+ /* No parameters. */
+ snprintf(buf, len, "%.*s/%s/", (int)pmu_name_len, pmu->name, alias->name);
+ return buf;
+ }
+
+ parse_events_terms__init(&terms);
+ ret = parse_events_terms(&terms, alias->terms, /*input=*/NULL);
+ if (ret) {
+ pr_err("Failure to parse '%s' terms '%s': %d\n",
+ alias->name, alias->terms, ret);
+ parse_events_terms__exit(&terms);
+ snprintf(buf, len, "%.*s/%s/", (int)pmu_name_len, pmu->name, alias->name);
+ return buf;
+ }
+ used = snprintf(buf, len, "%.*s/%s", (int)pmu_name_len, pmu->name, alias->name);
+
+ list_for_each_entry(term, &terms.terms, list) {
if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
used += snprintf(buf + used, sub_non_neg(len, used),
",%s=%s", term->config,
term->val.str);
}
-
+ parse_events_terms__exit(&terms);
if (sub_non_neg(len, used) > 0) {
buf[used] = '/';
used++;
.event_type_desc = "Kernel PMU event",
};
int ret = 0;
- struct strbuf sb;
struct hashmap_entry *entry;
size_t bkt;
if (perf_pmu__is_drm(pmu))
return drm_pmu__for_each_event(pmu, state, cb);
- strbuf_init(&sb, /*hint=*/ 0);
pmu_aliases_parse(pmu);
pmu_add_cpu_aliases(pmu);
hashmap__for_each_entry(pmu->aliases, entry, bkt) {
info.desc = event->desc;
info.long_desc = event->long_desc;
info.encoding_desc = buf + buf_used;
- parse_events_terms__to_strbuf(&event->terms, &sb);
buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used,
- "%.*s/%s/", (int)pmu_name_len, info.pmu_name, sb.buf) + 1;
+ "%.*s/%s/", (int)pmu_name_len, info.pmu_name, event->terms) + 1;
+ info.str = event->terms;
info.topic = event->topic;
- info.str = sb.buf;
info.deprecated = event->deprecated;
ret = cb(state, &info);
if (ret)
goto out;
- strbuf_setlen(&sb, /*len=*/ 0);
}
if (pmu->selectable) {
info.name = buf;
ret = cb(state, &info);
}
out:
- strbuf_release(&sb);
return ret;
}
hashmap__for_each_entry(pmu->aliases, entry, bkt) {
struct perf_pmu_alias *event = entry->pvalue;
struct perf_event_attr attr = {.config = 0,};
+ struct parse_events_terms terms;
+ int ret;
- int ret = perf_pmu__config(pmu, &attr, &event->terms, /*apply_hardcoded=*/true,
- /*err=*/NULL);
+ parse_events_terms__init(&terms);
+ ret = parse_events_terms(&terms, event->terms, /*input=*/NULL);
+ if (ret) {
+ pr_debug("Failed to parse '%s' terms '%s': %d\n",
+ event->name, event->terms, ret);
+ parse_events_terms__exit(&terms);
+ continue;
+ }
+ ret = perf_pmu__config(pmu, &attr, &terms, /*apply_hardcoded=*/true,
+ /*err=*/NULL);
+ parse_events_terms__exit(&terms);
if (ret == 0 && config == attr.config)
return event->name;
}