diff options
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r-- | tools/perf/util/parse-events.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 6c913c3914fb..33546c3ac1fe 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -904,6 +904,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = { [PARSE_EVENTS__TERM_TYPE_MAX_STACK] = "max-stack", [PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite", [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite", + [PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config", }; static bool config_term_shrinked; @@ -1034,7 +1035,8 @@ static int config_term_pmu(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err) { - if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER) + if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER || + term->type_term == PARSE_EVENTS__TERM_TYPE_DRV_CFG) /* * Always succeed for sysfs terms, as we dont know * at this point what type they need to have. @@ -1134,6 +1136,9 @@ do { \ case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1); break; + case PARSE_EVENTS__TERM_TYPE_DRV_CFG: + ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str); + break; default: break; } @@ -1755,20 +1760,49 @@ foreach_evsel_in_last_glob(struct perf_evlist *evlist, static int set_filter(struct perf_evsel *evsel, const void *arg) { const char *str = arg; + bool found = false; + int nr_addr_filters = 0; + struct perf_pmu *pmu = NULL; - if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) { - fprintf(stderr, - "--filter option should follow a -e tracepoint option\n"); - return -1; + if (evsel == NULL) + goto err; + + if (evsel->attr.type == PERF_TYPE_TRACEPOINT) { + if (perf_evsel__append_tp_filter(evsel, str) < 0) { + fprintf(stderr, + "not enough memory to hold filter string\n"); + return -1; + } + + return 0; } - if (perf_evsel__append_filter(evsel, "&&", str) < 0) { + while ((pmu = perf_pmu__scan(pmu)) != NULL) + if (pmu->type == evsel->attr.type) { + found = true; + break; + } + + if (found) + perf_pmu__scan_file(pmu, "nr_addr_filters", + "%d", &nr_addr_filters); + + if (!nr_addr_filters) + goto err; + + if (perf_evsel__append_addr_filter(evsel, str) < 0) { fprintf(stderr, "not enough memory to hold filter string\n"); return -1; } return 0; + +err: + fprintf(stderr, + "--filter option should follow a -e tracepoint or HW tracer option\n"); + + return -1; } int parse_filter(const struct option *opt, const char *str, @@ -1793,7 +1827,7 @@ static int add_exclude_perf_filter(struct perf_evsel *evsel, snprintf(new_filter, sizeof(new_filter), "common_pid != %d", getpid()); - if (perf_evsel__append_filter(evsel, "&&", new_filter) < 0) { + if (perf_evsel__append_tp_filter(evsel, new_filter) < 0) { fprintf(stderr, "not enough memory to hold filter string\n"); return -1; |