summaryrefslogtreecommitdiff
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c167
1 files changed, 93 insertions, 74 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 371ff3aee769..5ec21d21113c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -10,20 +10,21 @@
#include <fcntl.h>
#include <sys/param.h>
#include "term.h"
-#include "../perf.h"
+#include "build-id.h"
#include "evlist.h"
#include "evsel.h"
+#include <subcmd/pager.h>
#include <subcmd/parse-options.h>
#include "parse-events.h"
#include <subcmd/exec-cmd.h>
#include "string2.h"
#include "strlist.h"
#include "symbol.h"
-#include "cache.h"
#include "header.h"
#include "bpf-loader.h"
#include "debug.h"
#include <api/fs/tracing_path.h>
+#include <perf/cpumap.h>
#include "parse-events-bison.h"
#define YY_EXTRA_TYPE int
#include "parse-events-flex.h"
@@ -314,16 +315,16 @@ static char *get_config_name(struct list_head *head_terms)
return NULL;
}
-static struct perf_evsel *
+static struct evsel *
__add_event(struct list_head *list, int *idx,
struct perf_event_attr *attr,
char *name, struct perf_pmu *pmu,
struct list_head *config_terms, bool auto_merge_stats,
const char *cpu_list)
{
- struct perf_evsel *evsel;
- struct cpu_map *cpus = pmu ? pmu->cpus :
- cpu_list ? cpu_map__new(cpu_list) : NULL;
+ struct evsel *evsel;
+ struct perf_cpu_map *cpus = pmu ? pmu->cpus :
+ cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
event_attr_init(attr);
@@ -332,8 +333,8 @@ __add_event(struct list_head *list, int *idx,
return NULL;
(*idx)++;
- evsel->cpus = cpu_map__get(cpus);
- evsel->own_cpus = cpu_map__get(cpus);
+ evsel->core.cpus = perf_cpu_map__get(cpus);
+ evsel->core.own_cpus = perf_cpu_map__get(cpus);
evsel->system_wide = pmu ? pmu->is_uncore : false;
evsel->auto_merge_stats = auto_merge_stats;
@@ -343,7 +344,7 @@ __add_event(struct list_head *list, int *idx,
if (config_terms)
list_splice(config_terms, &evsel->config_terms);
- list_add_tail(&evsel->node, list);
+ list_add_tail(&evsel->core.node, list);
return evsel;
}
@@ -357,7 +358,7 @@ static int add_event(struct list_head *list, int *idx,
static int add_event_tool(struct list_head *list, int *idx,
enum perf_tool_event tool_event)
{
- struct perf_evsel *evsel;
+ struct evsel *evsel;
struct perf_event_attr attr = {
.type = PERF_TYPE_SOFTWARE,
.config = PERF_COUNT_SW_DUMMY,
@@ -510,7 +511,7 @@ static int add_tracepoint(struct list_head *list, int *idx,
struct parse_events_error *err,
struct list_head *head_config)
{
- struct perf_evsel *evsel;
+ struct evsel *evsel;
evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++);
if (IS_ERR(evsel)) {
@@ -526,7 +527,7 @@ static int add_tracepoint(struct list_head *list, int *idx,
list_splice(&config_terms, &evsel->config_terms);
}
- list_add_tail(&evsel->node, list);
+ list_add_tail(&evsel->core.node, list);
return 0;
}
@@ -630,15 +631,24 @@ struct __add_bpf_event_param {
struct list_head *head_config;
};
-static int add_bpf_event(const char *group, const char *event, int fd,
+static int add_bpf_event(const char *group, const char *event, int fd, struct bpf_object *obj,
void *_param)
{
LIST_HEAD(new_evsels);
struct __add_bpf_event_param *param = _param;
struct parse_events_state *parse_state = param->parse_state;
struct list_head *list = param->list;
- struct perf_evsel *pos;
+ struct evsel *pos;
int err;
+ /*
+ * Check if we should add the event, i.e. if it is a TP but starts with a '!',
+ * then don't add the tracepoint, this will be used for something else, like
+ * adding to a BPF_MAP_TYPE_PROG_ARRAY.
+ *
+ * See tools/perf/examples/bpf/augmented_raw_syscalls.c
+ */
+ if (group[0] == '!')
+ return 0;
pr_debug("add bpf event %s:%s and attach bpf program %d\n",
group, event, fd);
@@ -647,22 +657,23 @@ static int add_bpf_event(const char *group, const char *event, int fd,
event, parse_state->error,
param->head_config);
if (err) {
- struct perf_evsel *evsel, *tmp;
+ struct evsel *evsel, *tmp;
pr_debug("Failed to add BPF event %s:%s\n",
group, event);
- list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
- list_del_init(&evsel->node);
- perf_evsel__delete(evsel);
+ list_for_each_entry_safe(evsel, tmp, &new_evsels, core.node) {
+ list_del_init(&evsel->core.node);
+ evsel__delete(evsel);
}
return err;
}
pr_debug("adding %s:%s\n", group, event);
- list_for_each_entry(pos, &new_evsels, node) {
+ list_for_each_entry(pos, &new_evsels, core.node) {
pr_debug("adding %s:%s to %p\n",
group, event, pos);
pos->bpf_fd = fd;
+ pos->bpf_obj = obj;
}
list_splice(&new_evsels, list);
return 0;
@@ -952,6 +963,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
[PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
[PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config",
[PARSE_EVENTS__TERM_TYPE_PERCORE] = "percore",
+ [PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT] = "aux-output",
};
static bool config_term_shrinked;
@@ -1072,6 +1084,9 @@ do { \
return -EINVAL;
}
break;
+ case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
+ CHECK_TYPE_VAL(NUM);
+ break;
default:
err->str = strdup("unknown term");
err->idx = term->err_term;
@@ -1122,6 +1137,7 @@ static int config_term_tracepoint(struct perf_event_attr *attr,
case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
+ case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
return config_term_common(attr, term, err);
default:
if (err) {
@@ -1214,6 +1230,9 @@ do { \
ADD_CONFIG_TERM(PERCORE, percore,
term->val.num ? true : false);
break;
+ case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
+ ADD_CONFIG_TERM(AUX_OUTPUT, aux_output, term->val.num ? 1 : 0);
+ break;
default:
break;
}
@@ -1296,7 +1315,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
struct perf_event_attr attr;
struct perf_pmu_info info;
struct perf_pmu *pmu;
- struct perf_evsel *evsel;
+ struct evsel *evsel;
struct parse_events_error *err = parse_state->error;
bool use_uncore_alias;
LIST_HEAD(config_terms);
@@ -1443,13 +1462,13 @@ static int
parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list,
struct parse_events_state *parse_state)
{
- struct perf_evsel *evsel, *leader;
+ struct evsel *evsel, *leader;
uintptr_t *leaders;
bool is_leader = true;
int i, nr_pmu = 0, total_members, ret = 0;
- leader = list_first_entry(list, struct perf_evsel, node);
- evsel = list_last_entry(list, struct perf_evsel, node);
+ leader = list_first_entry(list, struct evsel, core.node);
+ evsel = list_last_entry(list, struct evsel, core.node);
total_members = evsel->idx - leader->idx + 1;
leaders = calloc(total_members, sizeof(uintptr_t));
@@ -1511,13 +1530,13 @@ parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list,
__evlist__for_each_entry(list, evsel) {
if (i >= nr_pmu)
i = 0;
- evsel->leader = (struct perf_evsel *) leaders[i++];
+ evsel->leader = (struct evsel *) leaders[i++];
}
/* The number of members and group name are same for each group */
for (i = 0; i < nr_pmu; i++) {
- evsel = (struct perf_evsel *) leaders[i];
- evsel->nr_members = total_members / nr_pmu;
+ evsel = (struct evsel *) leaders[i];
+ evsel->core.nr_members = total_members / nr_pmu;
evsel->group_name = name ? strdup(name) : NULL;
}
@@ -1534,7 +1553,7 @@ out:
void parse_events__set_leader(char *name, struct list_head *list,
struct parse_events_state *parse_state)
{
- struct perf_evsel *leader;
+ struct evsel *leader;
if (list_empty(list)) {
WARN_ONCE(true, "WARNING: failed to set leader: empty list");
@@ -1545,7 +1564,7 @@ void parse_events__set_leader(char *name, struct list_head *list,
return;
__perf_evlist__set_leader(list);
- leader = list_entry(list->next, struct perf_evsel, node);
+ leader = list_entry(list->next, struct evsel, core.node);
leader->group_name = name ? strdup(name) : NULL;
}
@@ -1578,18 +1597,18 @@ struct event_modifier {
};
static int get_event_modifier(struct event_modifier *mod, char *str,
- struct perf_evsel *evsel)
-{
- int eu = evsel ? evsel->attr.exclude_user : 0;
- int ek = evsel ? evsel->attr.exclude_kernel : 0;
- int eh = evsel ? evsel->attr.exclude_hv : 0;
- int eH = evsel ? evsel->attr.exclude_host : 0;
- int eG = evsel ? evsel->attr.exclude_guest : 0;
- int eI = evsel ? evsel->attr.exclude_idle : 0;
- int precise = evsel ? evsel->attr.precise_ip : 0;
+ struct evsel *evsel)
+{
+ int eu = evsel ? evsel->core.attr.exclude_user : 0;
+ int ek = evsel ? evsel->core.attr.exclude_kernel : 0;
+ int eh = evsel ? evsel->core.attr.exclude_hv : 0;
+ int eH = evsel ? evsel->core.attr.exclude_host : 0;
+ int eG = evsel ? evsel->core.attr.exclude_guest : 0;
+ int eI = evsel ? evsel->core.attr.exclude_idle : 0;
+ int precise = evsel ? evsel->core.attr.precise_ip : 0;
int precise_max = 0;
int sample_read = 0;
- int pinned = evsel ? evsel->attr.pinned : 0;
+ int pinned = evsel ? evsel->core.attr.pinned : 0;
int exclude = eu | ek | eh;
int exclude_GH = evsel ? evsel->exclude_GH : 0;
@@ -1691,7 +1710,7 @@ static int check_modifier(char *str)
int parse_events__modifier_event(struct list_head *list, char *str, bool add)
{
- struct perf_evsel *evsel;
+ struct evsel *evsel;
struct event_modifier mod;
if (str == NULL)
@@ -1707,20 +1726,20 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
if (add && get_event_modifier(&mod, str, evsel))
return -EINVAL;
- evsel->attr.exclude_user = mod.eu;
- evsel->attr.exclude_kernel = mod.ek;
- evsel->attr.exclude_hv = mod.eh;
- evsel->attr.precise_ip = mod.precise;
- evsel->attr.exclude_host = mod.eH;
- evsel->attr.exclude_guest = mod.eG;
- evsel->attr.exclude_idle = mod.eI;
+ evsel->core.attr.exclude_user = mod.eu;
+ evsel->core.attr.exclude_kernel = mod.ek;
+ evsel->core.attr.exclude_hv = mod.eh;
+ evsel->core.attr.precise_ip = mod.precise;
+ evsel->core.attr.exclude_host = mod.eH;
+ evsel->core.attr.exclude_guest = mod.eG;
+ evsel->core.attr.exclude_idle = mod.eI;
evsel->exclude_GH = mod.exclude_GH;
evsel->sample_read = mod.sample_read;
evsel->precise_max = mod.precise_max;
evsel->weak_group = mod.weak;
if (perf_evsel__is_group_leader(evsel))
- evsel->attr.pinned = mod.pinned;
+ evsel->core.attr.pinned = mod.pinned;
}
return 0;
@@ -1728,7 +1747,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
int parse_events_name(struct list_head *list, char *name)
{
- struct perf_evsel *evsel;
+ struct evsel *evsel;
__evlist__for_each_entry(list, evsel) {
if (!evsel->name)
@@ -1894,12 +1913,12 @@ int parse_events_terms(struct list_head *terms, const char *str)
return ret;
}
-int parse_events(struct perf_evlist *evlist, const char *str,
+int parse_events(struct evlist *evlist, const char *str,
struct parse_events_error *err)
{
struct parse_events_state parse_state = {
.list = LIST_HEAD_INIT(parse_state.list),
- .idx = evlist->nr_entries,
+ .idx = evlist->core.nr_entries,
.error = err,
.evlist = evlist,
};
@@ -1908,7 +1927,7 @@ int parse_events(struct perf_evlist *evlist, const char *str,
ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS);
perf_pmu__parse_cleanup();
if (!ret) {
- struct perf_evsel *last;
+ struct evsel *last;
if (list_empty(&parse_state.list)) {
WARN_ONCE(true, "WARNING: event parser found nothing\n");
@@ -1925,7 +1944,7 @@ int parse_events(struct perf_evlist *evlist, const char *str,
/*
* There are 2 users - builtin-record and builtin-test objects.
- * Both call perf_evlist__delete in case of error, so we dont
+ * Both call evlist__delete in case of error, so we dont
* need to bother.
*/
return ret;
@@ -2003,7 +2022,7 @@ void parse_events_print_error(struct parse_events_error *err,
int parse_events_option(const struct option *opt, const char *str,
int unset __maybe_unused)
{
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
+ struct evlist *evlist = *(struct evlist **)opt->value;
struct parse_events_error err = { .idx = 0, };
int ret = parse_events(evlist, str, &err);
@@ -2016,12 +2035,12 @@ int parse_events_option(const struct option *opt, const char *str,
}
static int
-foreach_evsel_in_last_glob(struct perf_evlist *evlist,
- int (*func)(struct perf_evsel *evsel,
+foreach_evsel_in_last_glob(struct evlist *evlist,
+ int (*func)(struct evsel *evsel,
const void *arg),
const void *arg)
{
- struct perf_evsel *last = NULL;
+ struct evsel *last = NULL;
int err;
/*
@@ -2030,7 +2049,7 @@ foreach_evsel_in_last_glob(struct perf_evlist *evlist,
*
* So no need to WARN here, let *func do this.
*/
- if (evlist->nr_entries > 0)
+ if (evlist->core.nr_entries > 0)
last = perf_evlist__last(evlist);
do {
@@ -2040,15 +2059,15 @@ foreach_evsel_in_last_glob(struct perf_evlist *evlist,
if (!last)
return 0;
- if (last->node.prev == &evlist->entries)
+ if (last->core.node.prev == &evlist->core.entries)
return 0;
- last = list_entry(last->node.prev, struct perf_evsel, node);
+ last = list_entry(last->core.node.prev, struct evsel, core.node);
} while (!last->cmdline_group_boundary);
return 0;
}
-static int set_filter(struct perf_evsel *evsel, const void *arg)
+static int set_filter(struct evsel *evsel, const void *arg)
{
const char *str = arg;
bool found = false;
@@ -2061,7 +2080,7 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
return -1;
}
- if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
+ if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
if (perf_evsel__append_tp_filter(evsel, str) < 0) {
fprintf(stderr,
"not enough memory to hold filter string\n");
@@ -2072,7 +2091,7 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
}
while ((pmu = perf_pmu__scan(pmu)) != NULL)
- if (pmu->type == evsel->attr.type) {
+ if (pmu->type == evsel->core.attr.type) {
found = true;
break;
}
@@ -2099,18 +2118,18 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
int parse_filter(const struct option *opt, const char *str,
int unset __maybe_unused)
{
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
+ struct evlist *evlist = *(struct evlist **)opt->value;
return foreach_evsel_in_last_glob(evlist, set_filter,
(const void *)str);
}
-static int add_exclude_perf_filter(struct perf_evsel *evsel,
+static int add_exclude_perf_filter(struct evsel *evsel,
const void *arg __maybe_unused)
{
char new_filter[64];
- if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) {
+ if (evsel == NULL || evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
fprintf(stderr,
"--exclude-perf option should follow a -e tracepoint option\n");
return -1;
@@ -2131,7 +2150,7 @@ int exclude_perf(const struct option *opt,
const char *arg __maybe_unused,
int unset __maybe_unused)
{
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
+ struct evlist *evlist = *(struct evlist **)opt->value;
return foreach_evsel_in_last_glob(evlist, add_exclude_perf_filter,
NULL);
@@ -2297,20 +2316,20 @@ static bool is_event_supported(u8 type, unsigned config)
{
bool ret = true;
int open_return;
- struct perf_evsel *evsel;
+ struct evsel *evsel;
struct perf_event_attr attr = {
.type = type,
.config = config,
.disabled = 1,
};
- struct thread_map *tmap = thread_map__new_by_tid(0);
+ struct perf_thread_map *tmap = thread_map__new_by_tid(0);
if (tmap == NULL)
return false;
- evsel = perf_evsel__new(&attr);
+ evsel = evsel__new(&attr);
if (evsel) {
- open_return = perf_evsel__open(evsel, NULL, tmap);
+ open_return = evsel__open(evsel, NULL, tmap);
ret = open_return >= 0;
if (open_return == -EACCES) {
@@ -2321,13 +2340,13 @@ static bool is_event_supported(u8 type, unsigned config)
* by default as some ARM machines do not support it.
*
*/
- evsel->attr.exclude_kernel = 1;
- ret = perf_evsel__open(evsel, NULL, tmap) >= 0;
+ evsel->core.attr.exclude_kernel = 1;
+ ret = evsel__open(evsel, NULL, tmap) >= 0;
}
- perf_evsel__delete(evsel);
+ evsel__delete(evsel);
}
- thread_map__put(tmap);
+ perf_thread_map__put(tmap);
return ret;
}