mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
perf stat: Make options local
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> Cc: Stephane Eranian <eranian@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Link: https://lore.kernel.org/r/20240605063828.195700-1-irogers@google.com
This commit is contained in:
parent
d2307fd4f9
commit
0dddd91ab6
@ -1140,150 +1140,6 @@ out:
|
||||
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]))
|
||||
|
Loading…
Reference in New Issue
Block a user