diff options
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r-- | tools/perf/builtin-stat.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 468fc49420ce..0a15253b438c 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -792,6 +792,8 @@ static struct option stat_options[] = { "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_UINTEGER('D', "delay", &stat_config.initial_delay, "ms to wait before starting measurement after program start"), OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL, @@ -803,6 +805,12 @@ static struct option stat_options[] = { OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list", "monitor specified metrics or metric groups (separated by ,)", parse_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_END() }; @@ -824,6 +832,12 @@ static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused, return cpu_map__get_core(map, cpu, NULL); } +static int perf_stat__get_node(struct perf_stat_config *config __maybe_unused, + struct perf_cpu_map *map, int cpu) +{ + return cpu_map__get_node(map, cpu, NULL); +} + static int perf_stat__get_aggr(struct perf_stat_config *config, aggr_get_id_t get_id, struct perf_cpu_map *map, int idx) { @@ -858,6 +872,12 @@ static int perf_stat__get_core_cached(struct perf_stat_config *config, return perf_stat__get_aggr(config, perf_stat__get_core, map, idx); } +static int perf_stat__get_node_cached(struct perf_stat_config *config, + struct perf_cpu_map *map, int idx) +{ + return perf_stat__get_aggr(config, perf_stat__get_node, map, idx); +} + static bool term_percore_set(void) { struct evsel *counter; @@ -896,6 +916,13 @@ static int perf_stat_init_aggr_mode(void) } stat_config.aggr_get_id = perf_stat__get_core_cached; break; + case AGGR_NODE: + if (cpu_map__build_node_map(evsel_list->core.cpus, &stat_config.aggr_map)) { + perror("cannot build core map"); + return -1; + } + stat_config.aggr_get_id = perf_stat__get_node_cached; + break; case AGGR_NONE: if (term_percore_set()) { if (cpu_map__build_core_map(evsel_list->core.cpus, @@ -1008,6 +1035,13 @@ static int perf_env__get_core(struct perf_cpu_map *map, int idx, void *data) return core; } +static int perf_env__get_node(struct perf_cpu_map *map, int idx, void *data) +{ + int cpu = perf_env__get_cpu(data, map, idx); + + return perf_env__numa_node(data, cpu); +} + static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus, struct perf_cpu_map **sockp) { @@ -1026,6 +1060,12 @@ static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *c return cpu_map__build_map(cpus, corep, perf_env__get_core, env); } +static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *cpus, + struct perf_cpu_map **nodep) +{ + return cpu_map__build_map(cpus, nodep, perf_env__get_node, env); +} + static int perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused, struct perf_cpu_map *map, int idx) { @@ -1043,6 +1083,12 @@ static int perf_stat__get_core_file(struct perf_stat_config *config __maybe_unus return perf_env__get_core(map, idx, &perf_stat.session->header.env); } +static int perf_stat__get_node_file(struct perf_stat_config *config __maybe_unused, + struct perf_cpu_map *map, int idx) +{ + return perf_env__get_node(map, idx, &perf_stat.session->header.env); +} + static int perf_stat_init_aggr_mode_file(struct perf_stat *st) { struct perf_env *env = &st->session->header.env; @@ -1069,6 +1115,13 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st) } stat_config.aggr_get_id = perf_stat__get_core_file; break; + case AGGR_NODE: + if (perf_env__build_node_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) { + perror("cannot build core map"); + return -1; + } + stat_config.aggr_get_id = perf_stat__get_node_file; + break; case AGGR_NONE: case AGGR_GLOBAL: case AGGR_THREAD: @@ -1254,6 +1307,7 @@ static int add_default_attributes(void) if (stat_config.null_run) return 0; + bzero(&errinfo, sizeof(errinfo)); if (transaction_run) { /* Handle -T as -M transaction. Once platform specific metrics * support has been added to the json files, all archictures @@ -1311,6 +1365,7 @@ static int add_default_attributes(void) return -1; } if (err) { + parse_events_print_error(&errinfo, smi_cost_attrs); fprintf(stderr, "Cannot set up SMI cost events\n"); return -1; } @@ -1616,6 +1671,8 @@ static int __cmd_report(int argc, const char **argv) "aggregate counts per processor die", AGGR_DIE), OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode, "aggregate counts per physical processor core", AGGR_CORE), + OPT_SET_UINT(0, "per-node", &perf_stat.aggr_mode, + "aggregate counts per numa node", AGGR_NODE), OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode, "disable CPU count aggregation", AGGR_NONE), OPT_END() @@ -1890,6 +1947,9 @@ int cmd_stat(int argc, const char **argv) } } + if (stat_config.aggr_mode == AGGR_NODE) + cpu__setup_cpunode_map(); + if (stat_config.times && interval) interval_count = true; else if (stat_config.times && !interval) { |