Commit 411ad22e authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo
Browse files

perf parse-events: Add pmu filter



To support the cputype argument added to "perf stat" for hybrid it is
necessary to filter events during wildcard matching. Add a scanner
argument for the filter and checking it when wildcard matching.

Signed-off-by: default avatarIan Rogers <irogers@google.com>
Tested-by: default avatarKan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ahmad Yasin <ahmad.yasin@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Edward Baker <edward.baker@intel.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kang Minchul <tegongkang@gmail.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Samantha Alt <samantha.alt@intel.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20230502223851.2234828-30-irogers@google.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 24d80818
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -3335,6 +3335,14 @@ const char record_callchain_help[] = CALLCHAIN_RECORD_HELP

static bool dry_run;

static struct parse_events_option_args parse_events_option_args = {
	.evlistp = &record.evlist,
};

static struct parse_events_option_args switch_output_parse_events_option_args = {
	.evlistp = &record.sb_evlist,
};

/*
 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
 * with it and switch to use the library functions in perf_evlist that came
@@ -3343,7 +3351,7 @@ static bool dry_run;
 * using pipes, etc.
 */
static struct option __record_options[] = {
	OPT_CALLBACK('e', "event", &record.evlist, "event",
	OPT_CALLBACK('e', "event", &parse_events_option_args, "event",
		     "event selector. use 'perf list' to list available events",
		     parse_events_option),
	OPT_CALLBACK(0, "filter", &record.evlist, "filter",
@@ -3496,7 +3504,8 @@ static struct option __record_options[] = {
			  &record.switch_output.set, "signal or size[BKMG] or time[smhd]",
			  "Switch output when receiving SIGUSR2 (signal) or cross a size or time threshold",
			  "signal"),
	OPT_CALLBACK_SET(0, "switch-output-event", &record.sb_evlist, &record.switch_output_event_set, "switch output event",
	OPT_CALLBACK_SET(0, "switch-output-event", &switch_output_parse_events_option_args,
			 &record.switch_output_event_set, "switch output event",
			 "switch output event selector. use 'perf list' to list available events",
			 parse_events_option_new_evlist),
	OPT_INTEGER(0, "switch-max-files", &record.switch_output.num_files,
+7 −3
Original line number Diff line number Diff line
@@ -101,6 +101,10 @@
static void print_counters(struct timespec *ts, int argc, const char **argv);

static struct evlist	*evsel_list;
static struct parse_events_option_args parse_events_option_args = {
	.evlistp = &evsel_list,
};

static bool all_counters_use_bpf = true;

static struct target target = {
@@ -1096,8 +1100,8 @@ static int parse_hybrid_type(const struct option *opt,
		return -1;
	}

	evlist->hybrid_pmu_name = perf_pmu__hybrid_type_to_pmu(str);
	if (!evlist->hybrid_pmu_name) {
	parse_events_option_args.pmu_filter = perf_pmu__hybrid_type_to_pmu(str);
	if (!parse_events_option_args.pmu_filter) {
		fprintf(stderr, "--cputype %s is not supported!\n", str);
		return -1;
	}
@@ -1108,7 +1112,7 @@ static int parse_hybrid_type(const struct option *opt,
static struct option stat_options[] = {
	OPT_BOOLEAN('T', "transaction", &transaction_run,
		    "hardware transaction statistics"),
	OPT_CALLBACK('e', "event", &evsel_list, "event",
	OPT_CALLBACK('e', "event", &parse_events_option_args, "event",
		     "event selector. use 'perf list' to list available events",
		     parse_events_option),
	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
+4 −1
Original line number Diff line number Diff line
@@ -1440,12 +1440,15 @@ int cmd_top(int argc, const char **argv)
		.max_stack	     = sysctl__max_stack(),
		.nr_threads_synthesize = UINT_MAX,
	};
	struct parse_events_option_args parse_events_option_args = {
		.evlistp = &top.evlist,
	};
	bool branch_call_mode = false;
	struct record_opts *opts = &top.record_opts;
	struct target *target = &opts->target;
	const char *disassembler_style = NULL, *objdump_path = NULL, *addr2line_path = NULL;
	const struct option options[] = {
	OPT_CALLBACK('e', "event", &top.evlist, "event",
	OPT_CALLBACK('e', "event", &parse_events_option_args, "event",
		     "event selector. use 'perf list' to list available events",
		     parse_events_option),
	OPT_U64('c', "count", &opts->user_interval, "event period to sample"),
+4 −1
Original line number Diff line number Diff line
@@ -4591,8 +4591,11 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
	err = 0;

	if (lists[0]) {
		struct parse_events_option_args parse_events_option_args = {
			.evlistp = &trace->evlist,
		};
		struct option o = {
			.value = &trace->evlist,
			.value = &parse_events_option_args,
		};
		err = parse_events_option(&o, lists[0], 0);
	}
+2 −1
Original line number Diff line number Diff line
@@ -1952,7 +1952,8 @@ static int test_event_fake_pmu(const char *str)
		return -ENOMEM;

	parse_events_error__init(&err);
	ret = __parse_events(evlist, str, &err, &perf_pmu__fake, /*warn_if_reordered=*/true);
	ret = __parse_events(evlist, str, /*pmu_filter=*/NULL, &err,
			     &perf_pmu__fake, /*warn_if_reordered=*/true);
	if (ret) {
		pr_debug("failed to parse event '%s', err %d, str '%s'\n",
			 str, ret, err.str);
Loading