linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v1 1/2] perf stat: Make options local
@ 2024-06-05  6:38 Ian Rogers
  2024-06-05  6:38 ` [RFC PATCH v1 2/2] perf stat: Choose the most disaggregate command line option Ian Rogers
  2024-06-09  2:33 ` [RFC PATCH v1 1/2] perf stat: Make options local Namhyung Kim
  0 siblings, 2 replies; 3+ messages in thread
From: Ian Rogers @ 2024-06-05  6:38 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, Kan Liang, linux-perf-users,
	linux-kernel, Stephane Eranian

Reduce the scope of stat_options to cmd_stat, and pass as an argument
to __cmd_record. This is done to make more localized changes to the
options in later patches. A side-effect of the change is to reduce the
size of a stripped PIE perf binary by 5952 bytes. The savings come
mainly in the dynamic relocation section.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/builtin-stat.c | 291 +++++++++++++++++++-------------------
 1 file changed, 145 insertions(+), 146 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 35f79b48e8dc..6227b25d1446 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1140,150 +1140,6 @@ static int parse_cache_level(const struct option *opt,
 	return 0;
 }
 
-static struct option stat_options[] = {
-	OPT_BOOLEAN('T', "transaction", &transaction_run,
-		    "hardware transaction statistics"),
-	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",
-		     "event filter", parse_filter),
-	OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit,
-		    "child tasks do not inherit counters"),
-	OPT_STRING('p', "pid", &target.pid, "pid",
-		   "stat events on existing process id"),
-	OPT_STRING('t', "tid", &target.tid, "tid",
-		   "stat events on existing thread id"),
-#ifdef HAVE_BPF_SKEL
-	OPT_STRING('b', "bpf-prog", &target.bpf_str, "bpf-prog-id",
-		   "stat events on existing bpf program id"),
-	OPT_BOOLEAN(0, "bpf-counters", &target.use_bpf,
-		    "use bpf program to count events"),
-	OPT_STRING(0, "bpf-attr-map", &target.attr_map, "attr-map-path",
-		   "path to perf_event_attr map"),
-#endif
-	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
-		    "system-wide collection from all CPUs"),
-	OPT_BOOLEAN(0, "scale", &stat_config.scale,
-		    "Use --no-scale to disable counter scaling for multiplexing"),
-	OPT_INCR('v', "verbose", &verbose,
-		    "be more verbose (show counter open errors, etc)"),
-	OPT_INTEGER('r', "repeat", &stat_config.run_count,
-		    "repeat command and print average + stddev (max: 100, forever: 0)"),
-	OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table,
-		    "display details about each run (only with -r option)"),
-	OPT_BOOLEAN('n', "null", &stat_config.null_run,
-		    "null run - dont start any counters"),
-	OPT_INCR('d', "detailed", &detailed_run,
-		    "detailed run - start a lot of events"),
-	OPT_BOOLEAN('S', "sync", &sync_run,
-		    "call sync() before starting a run"),
-	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
-			   "print large numbers with thousands\' separators",
-			   stat__set_big_num),
-	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
-		    "list of cpus to monitor in system-wide"),
-	OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
-		    "disable aggregation across CPUs or PMUs", AGGR_NONE),
-	OPT_SET_UINT(0, "no-merge", &stat_config.aggr_mode,
-		    "disable aggregation the same as -A or -no-aggr", AGGR_NONE),
-	OPT_BOOLEAN(0, "hybrid-merge", &stat_config.hybrid_merge,
-		    "Merge identical named hybrid events"),
-	OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator",
-		   "print counts with custom separator"),
-	OPT_BOOLEAN('j', "json-output", &stat_config.json_output,
-		   "print counts in JSON format"),
-	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
-		     "monitor event in cgroup name only", parse_stat_cgroups),
-	OPT_STRING(0, "for-each-cgroup", &stat_config.cgroup_list, "name",
-		    "expand events for each cgroup"),
-	OPT_STRING('o', "output", &output_name, "file", "output file name"),
-	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
-	OPT_INTEGER(0, "log-fd", &output_fd,
-		    "log output to fd, instead of stderr"),
-	OPT_STRING(0, "pre", &pre_cmd, "command",
-			"command to run prior to the measured command"),
-	OPT_STRING(0, "post", &post_cmd, "command",
-			"command to run after to the measured command"),
-	OPT_UINTEGER('I', "interval-print", &stat_config.interval,
-		    "print counts at regular interval in ms "
-		    "(overhead is possible for values <= 100ms)"),
-	OPT_INTEGER(0, "interval-count", &stat_config.times,
-		    "print counts for fixed number of times"),
-	OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear,
-		    "clear screen in between new interval"),
-	OPT_UINTEGER(0, "timeout", &stat_config.timeout,
-		    "stop workload and print counts after a timeout period in ms (>= 10ms)"),
-	OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
-		     "aggregate counts per processor socket", AGGR_SOCKET),
-	OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
-		     "aggregate counts per processor die", AGGR_DIE),
-	OPT_SET_UINT(0, "per-cluster", &stat_config.aggr_mode,
-		     "aggregate counts per processor cluster", AGGR_CLUSTER),
-	OPT_CALLBACK_OPTARG(0, "per-cache", &stat_config.aggr_mode, &stat_config.aggr_level,
-			    "cache level", "aggregate count at this cache level (Default: LLC)",
-			    parse_cache_level),
-	OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
-		     "aggregate counts per physical processor core", AGGR_CORE),
-	OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
-		     "aggregate counts per thread", AGGR_THREAD),
-	OPT_SET_UINT(0, "per-node", &stat_config.aggr_mode,
-		     "aggregate counts per numa node", AGGR_NODE),
-	OPT_INTEGER('D', "delay", &target.initial_delay,
-		    "ms to wait before starting measurement after program start (-1: start with events disabled)"),
-	OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
-			"Only print computed metrics. No raw values", enable_metric_only),
-	OPT_BOOLEAN(0, "metric-no-group", &stat_config.metric_no_group,
-		       "don't group metric events, impacts multiplexing"),
-	OPT_BOOLEAN(0, "metric-no-merge", &stat_config.metric_no_merge,
-		       "don't try to share events between metrics in a group"),
-	OPT_BOOLEAN(0, "metric-no-threshold", &stat_config.metric_no_threshold,
-		       "disable adding events for the metric threshold calculation"),
-	OPT_BOOLEAN(0, "topdown", &topdown_run,
-			"measure top-down statistics"),
-	OPT_UINTEGER(0, "td-level", &stat_config.topdown_level,
-			"Set the metrics level for the top-down statistics (0: max level)"),
-	OPT_BOOLEAN(0, "smi-cost", &smi_cost,
-			"measure SMI cost"),
-	OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list",
-		     "monitor specified metrics or metric groups (separated by ,)",
-		     append_metric_groups),
-	OPT_BOOLEAN_FLAG(0, "all-kernel", &stat_config.all_kernel,
-			 "Configure all used events to run in kernel space.",
-			 PARSE_OPT_EXCLUSIVE),
-	OPT_BOOLEAN_FLAG(0, "all-user", &stat_config.all_user,
-			 "Configure all used events to run in user space.",
-			 PARSE_OPT_EXCLUSIVE),
-	OPT_BOOLEAN(0, "percore-show-thread", &stat_config.percore_show_thread,
-		    "Use with 'percore' event qualifier to show the event "
-		    "counts of one hardware thread by sum up total hardware "
-		    "threads of same physical core"),
-	OPT_BOOLEAN(0, "summary", &stat_config.summary,
-		       "print summary for interval mode"),
-	OPT_BOOLEAN(0, "no-csv-summary", &stat_config.no_csv_summary,
-		       "don't print 'summary' for CSV summary output"),
-	OPT_BOOLEAN(0, "quiet", &quiet,
-			"don't print any output, messages or warnings (useful with record)"),
-	OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type",
-		     "Only enable events on applying cpu with this type "
-		     "for hybrid platform (e.g. core or atom)",
-		     parse_cputype),
-#ifdef HAVE_LIBPFM
-	OPT_CALLBACK(0, "pfm-events", &evsel_list, "event",
-		"libpfm4 event selector. use 'perf list' to list available events",
-		parse_libpfm_events_option),
-#endif
-	OPT_CALLBACK(0, "control", &stat_config, "fd:ctl-fd[,ack-fd] or fifo:ctl-fifo[,ack-fifo]",
-		     "Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events).\n"
-		     "\t\t\t  Optionally send control command completion ('ack\\n') to ack-fd descriptor.\n"
-		     "\t\t\t  Alternatively, ctl-fifo / ack-fifo will be opened and used as ctl-fd / ack-fd.",
-		      parse_control_option),
-	OPT_CALLBACK_OPTARG(0, "iostat", &evsel_list, &stat_config, "default",
-			    "measure I/O performance metrics provided by arch/platform",
-			    iostat_parse),
-	OPT_END()
-};
-
 /**
  * Calculate the cache instance ID from the map in
  * /sys/devices/system/cpu/cpuX/cache/indexY/shared_cpu_list
@@ -2245,7 +2101,7 @@ static void init_features(struct perf_session *session)
 	perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
 }
 
-static int __cmd_record(int argc, const char **argv)
+static int __cmd_record(const struct option stat_options[], int argc, const char **argv)
 {
 	struct perf_session *session;
 	struct perf_data *data = &perf_stat.data;
@@ -2494,6 +2350,149 @@ static void setup_system_wide(int forks)
 
 int cmd_stat(int argc, const char **argv)
 {
+	struct option stat_options[] = {
+		OPT_BOOLEAN('T', "transaction", &transaction_run,
+			"hardware transaction statistics"),
+		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",
+			"event filter", parse_filter),
+		OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit,
+			"child tasks do not inherit counters"),
+		OPT_STRING('p', "pid", &target.pid, "pid",
+			"stat events on existing process id"),
+		OPT_STRING('t', "tid", &target.tid, "tid",
+			"stat events on existing thread id"),
+#ifdef HAVE_BPF_SKEL
+		OPT_STRING('b', "bpf-prog", &target.bpf_str, "bpf-prog-id",
+			"stat events on existing bpf program id"),
+		OPT_BOOLEAN(0, "bpf-counters", &target.use_bpf,
+			"use bpf program to count events"),
+		OPT_STRING(0, "bpf-attr-map", &target.attr_map, "attr-map-path",
+			"path to perf_event_attr map"),
+#endif
+		OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
+			"system-wide collection from all CPUs"),
+		OPT_BOOLEAN(0, "scale", &stat_config.scale,
+			"Use --no-scale to disable counter scaling for multiplexing"),
+		OPT_INCR('v', "verbose", &verbose,
+			"be more verbose (show counter open errors, etc)"),
+		OPT_INTEGER('r', "repeat", &stat_config.run_count,
+			"repeat command and print average + stddev (max: 100, forever: 0)"),
+		OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table,
+			"display details about each run (only with -r option)"),
+		OPT_BOOLEAN('n', "null", &stat_config.null_run,
+			"null run - dont start any counters"),
+		OPT_INCR('d', "detailed", &detailed_run,
+			"detailed run - start a lot of events"),
+		OPT_BOOLEAN('S', "sync", &sync_run,
+			"call sync() before starting a run"),
+		OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
+				"print large numbers with thousands\' separators",
+				stat__set_big_num),
+		OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
+			"list of cpus to monitor in system-wide"),
+		OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
+			"disable aggregation across CPUs or PMUs", AGGR_NONE),
+		OPT_SET_UINT(0, "no-merge", &stat_config.aggr_mode,
+			"disable aggregation the same as -A or -no-aggr", AGGR_NONE),
+		OPT_BOOLEAN(0, "hybrid-merge", &stat_config.hybrid_merge,
+			"Merge identical named hybrid events"),
+		OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator",
+			"print counts with custom separator"),
+		OPT_BOOLEAN('j', "json-output", &stat_config.json_output,
+			"print counts in JSON format"),
+		OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
+			"monitor event in cgroup name only", parse_stat_cgroups),
+		OPT_STRING(0, "for-each-cgroup", &stat_config.cgroup_list, "name",
+			"expand events for each cgroup"),
+		OPT_STRING('o', "output", &output_name, "file", "output file name"),
+		OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
+		OPT_INTEGER(0, "log-fd", &output_fd,
+			"log output to fd, instead of stderr"),
+		OPT_STRING(0, "pre", &pre_cmd, "command",
+			"command to run prior to the measured command"),
+		OPT_STRING(0, "post", &post_cmd, "command",
+			"command to run after to the measured command"),
+		OPT_UINTEGER('I', "interval-print", &stat_config.interval,
+			"print counts at regular interval in ms "
+			"(overhead is possible for values <= 100ms)"),
+		OPT_INTEGER(0, "interval-count", &stat_config.times,
+			"print counts for fixed number of times"),
+		OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear,
+			"clear screen in between new interval"),
+		OPT_UINTEGER(0, "timeout", &stat_config.timeout,
+			"stop workload and print counts after a timeout period in ms (>= 10ms)"),
+		OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
+			"aggregate counts per processor socket", AGGR_SOCKET),
+		OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
+			"aggregate counts per processor die", AGGR_DIE),
+		OPT_SET_UINT(0, "per-cluster", &stat_config.aggr_mode,
+			"aggregate counts per processor cluster", AGGR_CLUSTER),
+		OPT_CALLBACK_OPTARG(0, "per-cache", &stat_config.aggr_mode, &stat_config.aggr_level,
+				"cache level", "aggregate count at this cache level (Default: LLC)",
+				parse_cache_level),
+		OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
+			"aggregate counts per physical processor core", AGGR_CORE),
+		OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
+			"aggregate counts per thread", AGGR_THREAD),
+		OPT_SET_UINT(0, "per-node", &stat_config.aggr_mode,
+			"aggregate counts per numa node", AGGR_NODE),
+		OPT_INTEGER('D', "delay", &target.initial_delay,
+			"ms to wait before starting measurement after program start (-1: start with events disabled)"),
+		OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
+				"Only print computed metrics. No raw values", enable_metric_only),
+		OPT_BOOLEAN(0, "metric-no-group", &stat_config.metric_no_group,
+			"don't group metric events, impacts multiplexing"),
+		OPT_BOOLEAN(0, "metric-no-merge", &stat_config.metric_no_merge,
+			"don't try to share events between metrics in a group"),
+		OPT_BOOLEAN(0, "metric-no-threshold", &stat_config.metric_no_threshold,
+			"disable adding events for the metric threshold calculation"),
+		OPT_BOOLEAN(0, "topdown", &topdown_run,
+			"measure top-down statistics"),
+		OPT_UINTEGER(0, "td-level", &stat_config.topdown_level,
+			"Set the metrics level for the top-down statistics (0: max level)"),
+		OPT_BOOLEAN(0, "smi-cost", &smi_cost,
+			"measure SMI cost"),
+		OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list",
+			"monitor specified metrics or metric groups (separated by ,)",
+			append_metric_groups),
+		OPT_BOOLEAN_FLAG(0, "all-kernel", &stat_config.all_kernel,
+				"Configure all used events to run in kernel space.",
+				PARSE_OPT_EXCLUSIVE),
+		OPT_BOOLEAN_FLAG(0, "all-user", &stat_config.all_user,
+				"Configure all used events to run in user space.",
+				PARSE_OPT_EXCLUSIVE),
+		OPT_BOOLEAN(0, "percore-show-thread", &stat_config.percore_show_thread,
+			"Use with 'percore' event qualifier to show the event "
+			"counts of one hardware thread by sum up total hardware "
+			"threads of same physical core"),
+		OPT_BOOLEAN(0, "summary", &stat_config.summary,
+			"print summary for interval mode"),
+		OPT_BOOLEAN(0, "no-csv-summary", &stat_config.no_csv_summary,
+			"don't print 'summary' for CSV summary output"),
+		OPT_BOOLEAN(0, "quiet", &quiet,
+			"don't print any output, messages or warnings (useful with record)"),
+		OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type",
+			"Only enable events on applying cpu with this type "
+			"for hybrid platform (e.g. core or atom)",
+			parse_cputype),
+#ifdef HAVE_LIBPFM
+		OPT_CALLBACK(0, "pfm-events", &evsel_list, "event",
+			"libpfm4 event selector. use 'perf list' to list available events",
+			parse_libpfm_events_option),
+#endif
+		OPT_CALLBACK(0, "control", &stat_config, "fd:ctl-fd[,ack-fd] or fifo:ctl-fifo[,ack-fifo]",
+			"Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events).\n"
+			"\t\t\t  Optionally send control command completion ('ack\\n') to ack-fd descriptor.\n"
+			"\t\t\t  Alternatively, ctl-fifo / ack-fifo will be opened and used as ctl-fd / ack-fd.",
+			parse_control_option),
+		OPT_CALLBACK_OPTARG(0, "iostat", &evsel_list, &stat_config, "default",
+				"measure I/O performance metrics provided by arch/platform",
+				iostat_parse),
+		OPT_END()
+	};
 	const char * const stat_usage[] = {
 		"perf stat [<options>] [<command>]",
 		NULL
@@ -2530,7 +2529,7 @@ int cmd_stat(int argc, const char **argv)
 		stat_config.csv_sep = DEFAULT_SEPARATOR;
 
 	if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
-		argc = __cmd_record(argc, argv);
+		argc = __cmd_record(stat_options, argc, argv);
 		if (argc < 0)
 			return -1;
 	} else if (argc && strlen(argv[0]) > 2 && strstarts("report", argv[0]))
-- 
2.45.1.288.g0e0cd299f1-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC PATCH v1 2/2] perf stat: Choose the most disaggregate command line option
  2024-06-05  6:38 [RFC PATCH v1 1/2] perf stat: Make options local Ian Rogers
@ 2024-06-05  6:38 ` Ian Rogers
  2024-06-09  2:33 ` [RFC PATCH v1 1/2] perf stat: Make options local Namhyung Kim
  1 sibling, 0 replies; 3+ messages in thread
From: Ian Rogers @ 2024-06-05  6:38 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, Kan Liang, linux-perf-users,
	linux-kernel, Stephane Eranian

When multiple aggregation options are passed to perf stat the behavior
isn't clear. Consider "perf stat -A --per-socket .." and "perf stat
--per-socket -A ..", the first won't aggregate at all while the second
will do per-socket aggregation, even though the same options were
passed.

Rather than set an enum value, gather the options in a struct and
process them from most to least aggregate. This ensures the least
aggregate option always applies, so no aggregation if "-A" is passed.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/builtin-stat.c | 73 ++++++++++++++++++++++++++++-----------
 1 file changed, 52 insertions(+), 21 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 6227b25d1446..603a9684153d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -164,6 +164,35 @@ static struct perf_stat_config stat_config = {
 	.iostat_run		= false,
 };
 
+/* Options set from the command line. */
+struct opt_aggr_mode {
+	bool node, socket, die, cluster, cache, core, thread, no_aggr;
+};
+
+/* Turn command line option into most generic aggregation mode setting. */
+static enum aggr_mode opt_aggr_mode_to_aggr_mode(struct opt_aggr_mode *opt_mode)
+{
+	enum aggr_mode mode = AGGR_GLOBAL;
+
+	if (opt_mode->node)
+		mode = AGGR_NODE;
+	if (opt_mode->socket)
+		mode = AGGR_SOCKET;
+	if (opt_mode->die)
+		mode = AGGR_DIE;
+	if (opt_mode->cluster)
+		mode = AGGR_CLUSTER;
+	if (opt_mode->cache)
+		mode = AGGR_CACHE;
+	if (opt_mode->core)
+		mode = AGGR_CORE;
+	if (opt_mode->thread)
+		mode = AGGR_THREAD;
+	if (opt_mode->no_aggr)
+		mode = AGGR_NONE;
+	return mode;
+}
+
 static void evlist__check_cpu_maps(struct evlist *evlist)
 {
 	struct evsel *evsel, *warned_leader = NULL;
@@ -1096,7 +1125,7 @@ static int parse_cache_level(const struct option *opt,
 			     int unset __maybe_unused)
 {
 	int level;
-	u32 *aggr_mode = (u32 *)opt->value;
+	struct opt_aggr_mode *opt_aggr_mode = (struct opt_aggr_mode *)opt->value;
 	u32 *aggr_level = (u32 *)opt->data;
 
 	/*
@@ -1135,7 +1164,7 @@ static int parse_cache_level(const struct option *opt,
 		return -EINVAL;
 	}
 out:
-	*aggr_mode = AGGR_CACHE;
+	opt_aggr_mode->cache = true;
 	*aggr_level = level;
 	return 0;
 }
@@ -2101,13 +2130,15 @@ static void init_features(struct perf_session *session)
 	perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
 }
 
-static int __cmd_record(const struct option stat_options[], int argc, const char **argv)
+static int __cmd_record(const struct option stat_options[], struct opt_aggr_mode *opt_mode,
+			int argc, const char **argv)
 {
 	struct perf_session *session;
 	struct perf_data *data = &perf_stat.data;
 
 	argc = parse_options(argc, argv, stat_options, stat_record_usage,
 			     PARSE_OPT_STOP_AT_NON_OPTION);
+	stat_config.aggr_mode = opt_aggr_mode_to_aggr_mode(opt_mode);
 
 	if (output_name)
 		data->path = output_name;
@@ -2350,6 +2381,7 @@ static void setup_system_wide(int forks)
 
 int cmd_stat(int argc, const char **argv)
 {
+	struct opt_aggr_mode opt_mode = {};
 	struct option stat_options[] = {
 		OPT_BOOLEAN('T', "transaction", &transaction_run,
 			"hardware transaction statistics"),
@@ -2393,10 +2425,10 @@ int cmd_stat(int argc, const char **argv)
 				stat__set_big_num),
 		OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
 			"list of cpus to monitor in system-wide"),
-		OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
-			"disable aggregation across CPUs or PMUs", AGGR_NONE),
-		OPT_SET_UINT(0, "no-merge", &stat_config.aggr_mode,
-			"disable aggregation the same as -A or -no-aggr", AGGR_NONE),
+		OPT_BOOLEAN('A', "no-aggr", &opt_mode.no_aggr,
+			"disable aggregation across CPUs or PMUs"),
+		OPT_BOOLEAN(0, "no-merge", &opt_mode.no_aggr,
+			"disable aggregation the same as -A or -no-aggr"),
 		OPT_BOOLEAN(0, "hybrid-merge", &stat_config.hybrid_merge,
 			"Merge identical named hybrid events"),
 		OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator",
@@ -2424,21 +2456,18 @@ int cmd_stat(int argc, const char **argv)
 			"clear screen in between new interval"),
 		OPT_UINTEGER(0, "timeout", &stat_config.timeout,
 			"stop workload and print counts after a timeout period in ms (>= 10ms)"),
-		OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
-			"aggregate counts per processor socket", AGGR_SOCKET),
-		OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
-			"aggregate counts per processor die", AGGR_DIE),
-		OPT_SET_UINT(0, "per-cluster", &stat_config.aggr_mode,
-			"aggregate counts per processor cluster", AGGR_CLUSTER),
-		OPT_CALLBACK_OPTARG(0, "per-cache", &stat_config.aggr_mode, &stat_config.aggr_level,
+		OPT_BOOLEAN(0, "per-socket", &opt_mode.socket,
+			"aggregate counts per processor socket"),
+		OPT_BOOLEAN(0, "per-die", &opt_mode.die, "aggregate counts per processor die"),
+		OPT_BOOLEAN(0, "per-cluster", &opt_mode.cluster,
+			"aggregate counts per processor cluster"),
+		OPT_CALLBACK_OPTARG(0, "per-cache", &opt_mode, &stat_config.aggr_level,
 				"cache level", "aggregate count at this cache level (Default: LLC)",
 				parse_cache_level),
-		OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
-			"aggregate counts per physical processor core", AGGR_CORE),
-		OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
-			"aggregate counts per thread", AGGR_THREAD),
-		OPT_SET_UINT(0, "per-node", &stat_config.aggr_mode,
-			"aggregate counts per numa node", AGGR_NODE),
+		OPT_BOOLEAN(0, "per-core", &opt_mode.core,
+			"aggregate counts per physical processor core"),
+		OPT_BOOLEAN(0, "per-thread", &opt_mode.thread, "aggregate counts per thread"),
+		OPT_BOOLEAN(0, "per-node", &opt_mode.node, "aggregate counts per numa node"),
 		OPT_INTEGER('D', "delay", &target.initial_delay,
 			"ms to wait before starting measurement after program start (-1: start with events disabled)"),
 		OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
@@ -2521,6 +2550,8 @@ int cmd_stat(int argc, const char **argv)
 					(const char **) stat_usage,
 					PARSE_OPT_STOP_AT_NON_OPTION);
 
+	stat_config.aggr_mode = opt_aggr_mode_to_aggr_mode(&opt_mode);
+
 	if (stat_config.csv_sep) {
 		stat_config.csv_output = true;
 		if (!strcmp(stat_config.csv_sep, "\\t"))
@@ -2529,7 +2560,7 @@ int cmd_stat(int argc, const char **argv)
 		stat_config.csv_sep = DEFAULT_SEPARATOR;
 
 	if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
-		argc = __cmd_record(stat_options, argc, argv);
+		argc = __cmd_record(stat_options, &opt_mode, argc, argv);
 		if (argc < 0)
 			return -1;
 	} else if (argc && strlen(argv[0]) > 2 && strstarts("report", argv[0]))
-- 
2.45.1.288.g0e0cd299f1-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [RFC PATCH v1 1/2] perf stat: Make options local
  2024-06-05  6:38 [RFC PATCH v1 1/2] perf stat: Make options local Ian Rogers
  2024-06-05  6:38 ` [RFC PATCH v1 2/2] perf stat: Choose the most disaggregate command line option Ian Rogers
@ 2024-06-09  2:33 ` Namhyung Kim
  1 sibling, 0 replies; 3+ messages in thread
From: Namhyung Kim @ 2024-06-09  2:33 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Adrian Hunter,
	Kan Liang, linux-perf-users, linux-kernel, Stephane Eranian,
	Ian Rogers

On Tue, 04 Jun 2024 23:38:27 -0700, Ian Rogers wrote:

> Reduce the scope of stat_options to cmd_stat, and pass as an argument
> to __cmd_record. This is done to make more localized changes to the
> options in later patches. A side-effect of the change is to reduce the
> size of a stripped PIE perf binary by 5952 bytes. The savings come
> mainly in the dynamic relocation section.
> 
> 
> [...]

Applied to perf-tools-next, thanks!

Best regards,
Namhyung

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-06-09  2:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-05  6:38 [RFC PATCH v1 1/2] perf stat: Make options local Ian Rogers
2024-06-05  6:38 ` [RFC PATCH v1 2/2] perf stat: Choose the most disaggregate command line option Ian Rogers
2024-06-09  2:33 ` [RFC PATCH v1 1/2] perf stat: Make options local Namhyung Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).