diff options
author | Jin Yao <yao.jin@linux.intel.com> | 2019-04-12 09:59:49 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-05-16 13:17:24 -0400 |
commit | 4fc4d8dfa056dfd48afe73b9ea3b7570ceb80b9c (patch) | |
tree | 6ac8af8fe1ab5768a49d22ba74569acbd41b4f0d | |
parent | 40480a8136700d678dc07222c4d7287c89d0c04d (diff) |
perf stat: Support 'percore' event qualifier
With this patch, we can use the 'percore' event qualifier in perf-stat.
root@skl:/tmp# perf stat -e cpu/event=0,umask=0x3,percore=1/,cpu/event=0,umask=0x3/ -a -A -I1000
1.000773050 S0-C0 98,352,832 cpu/event=0,umask=0x3,percore=1/ (50.01%)
1.000773050 S0-C1 103,763,057 cpu/event=0,umask=0x3,percore=1/ (50.02%)
1.000773050 S0-C2 196,776,995 cpu/event=0,umask=0x3,percore=1/ (50.02%)
1.000773050 S0-C3 176,493,779 cpu/event=0,umask=0x3,percore=1/ (50.02%)
1.000773050 CPU0 47,699,641 cpu/event=0,umask=0x3/ (50.02%)
1.000773050 CPU1 49,052,451 cpu/event=0,umask=0x3/ (49.98%)
1.000773050 CPU2 102,771,422 cpu/event=0,umask=0x3/ (49.98%)
1.000773050 CPU3 100,784,662 cpu/event=0,umask=0x3/ (49.98%)
1.000773050 CPU4 43,171,342 cpu/event=0,umask=0x3/ (49.98%)
1.000773050 CPU5 54,152,158 cpu/event=0,umask=0x3/ (49.98%)
1.000773050 CPU6 93,618,410 cpu/event=0,umask=0x3/ (49.98%)
1.000773050 CPU7 74,477,589 cpu/event=0,umask=0x3/ (49.99%)
In this example, we count the event 'ref-cycles' per-core and per-CPU in
one perf stat command-line. From the output, we can see:
S0-C0 = CPU0 + CPU4
S0-C1 = CPU1 + CPU5
S0-C2 = CPU2 + CPU6
S0-C3 = CPU3 + CPU7
So the result is expected (tiny difference is ignored).
Note that, the 'percore' event qualifier needs to use with option '-A'.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Tested-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jin Yao <yao.jin@intel.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1555077590-27664-4-git-send-email-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/Documentation/perf-stat.txt | 4 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 21 | ||||
-rw-r--r-- | tools/perf/util/stat-display.c | 43 | ||||
-rw-r--r-- | tools/perf/util/stat.c | 8 |
4 files changed, 69 insertions, 7 deletions
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 39c05f89104e..1e312c2672e4 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt | |||
@@ -43,6 +43,10 @@ report:: | |||
43 | param1 and param2 are defined as formats for the PMU in | 43 | param1 and param2 are defined as formats for the PMU in |
44 | /sys/bus/event_source/devices/<pmu>/format/* | 44 | /sys/bus/event_source/devices/<pmu>/format/* |
45 | 45 | ||
46 | 'percore' is a event qualifier that sums up the event counts for both | ||
47 | hardware threads in a core. For example: | ||
48 | perf stat -A -a -e cpu/event,percore=1/,otherevent ... | ||
49 | |||
46 | - a symbolically formed event like 'pmu/config=M,config1=N,config2=K/' | 50 | - a symbolically formed event like 'pmu/config=M,config1=N,config2=K/' |
47 | where M, N, K are numbers (in decimal, hex, octal format). | 51 | where M, N, K are numbers (in decimal, hex, octal format). |
48 | Acceptable values for each of 'config', 'config1' and 'config2' | 52 | Acceptable values for each of 'config', 'config1' and 'config2' |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index a3c060878faa..24b8e690fb69 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -847,6 +847,18 @@ static int perf_stat__get_core_cached(struct perf_stat_config *config, | |||
847 | return perf_stat__get_aggr(config, perf_stat__get_core, map, idx); | 847 | return perf_stat__get_aggr(config, perf_stat__get_core, map, idx); |
848 | } | 848 | } |
849 | 849 | ||
850 | static bool term_percore_set(void) | ||
851 | { | ||
852 | struct perf_evsel *counter; | ||
853 | |||
854 | evlist__for_each_entry(evsel_list, counter) { | ||
855 | if (counter->percore) | ||
856 | return true; | ||
857 | } | ||
858 | |||
859 | return false; | ||
860 | } | ||
861 | |||
850 | static int perf_stat_init_aggr_mode(void) | 862 | static int perf_stat_init_aggr_mode(void) |
851 | { | 863 | { |
852 | int nr; | 864 | int nr; |
@@ -867,6 +879,15 @@ static int perf_stat_init_aggr_mode(void) | |||
867 | stat_config.aggr_get_id = perf_stat__get_core_cached; | 879 | stat_config.aggr_get_id = perf_stat__get_core_cached; |
868 | break; | 880 | break; |
869 | case AGGR_NONE: | 881 | case AGGR_NONE: |
882 | if (term_percore_set()) { | ||
883 | if (cpu_map__build_core_map(evsel_list->cpus, | ||
884 | &stat_config.aggr_map)) { | ||
885 | perror("cannot build core map"); | ||
886 | return -1; | ||
887 | } | ||
888 | stat_config.aggr_get_id = perf_stat__get_core_cached; | ||
889 | } | ||
890 | break; | ||
870 | case AGGR_GLOBAL: | 891 | case AGGR_GLOBAL: |
871 | case AGGR_THREAD: | 892 | case AGGR_THREAD: |
872 | case AGGR_UNSET: | 893 | case AGGR_UNSET: |
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index f5b4ee79568c..4c53bae5644b 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c | |||
@@ -88,9 +88,17 @@ static void aggr_printout(struct perf_stat_config *config, | |||
88 | config->csv_sep); | 88 | config->csv_sep); |
89 | break; | 89 | break; |
90 | case AGGR_NONE: | 90 | case AGGR_NONE: |
91 | fprintf(config->output, "CPU%*d%s", | 91 | if (evsel->percore) { |
92 | config->csv_output ? 0 : -4, | 92 | fprintf(config->output, "S%d-C%*d%s", |
93 | perf_evsel__cpus(evsel)->map[id], config->csv_sep); | 93 | cpu_map__id_to_socket(id), |
94 | config->csv_output ? 0 : -5, | ||
95 | cpu_map__id_to_cpu(id), config->csv_sep); | ||
96 | } else { | ||
97 | fprintf(config->output, "CPU%*d%s ", | ||
98 | config->csv_output ? 0 : -5, | ||
99 | perf_evsel__cpus(evsel)->map[id], | ||
100 | config->csv_sep); | ||
101 | } | ||
94 | break; | 102 | break; |
95 | case AGGR_THREAD: | 103 | case AGGR_THREAD: |
96 | fprintf(config->output, "%*s-%*d%s", | 104 | fprintf(config->output, "%*s-%*d%s", |
@@ -1103,6 +1111,30 @@ static void print_footer(struct perf_stat_config *config) | |||
1103 | "the same PMU. Try reorganizing the group.\n"); | 1111 | "the same PMU. Try reorganizing the group.\n"); |
1104 | } | 1112 | } |
1105 | 1113 | ||
1114 | static void print_percore(struct perf_stat_config *config, | ||
1115 | struct perf_evsel *counter, char *prefix) | ||
1116 | { | ||
1117 | bool metric_only = config->metric_only; | ||
1118 | FILE *output = config->output; | ||
1119 | int s; | ||
1120 | bool first = true; | ||
1121 | |||
1122 | if (!(config->aggr_map || config->aggr_get_id)) | ||
1123 | return; | ||
1124 | |||
1125 | for (s = 0; s < config->aggr_map->nr; s++) { | ||
1126 | if (prefix && metric_only) | ||
1127 | fprintf(output, "%s", prefix); | ||
1128 | |||
1129 | print_counter_aggrdata(config, counter, s, | ||
1130 | prefix, metric_only, | ||
1131 | &first); | ||
1132 | } | ||
1133 | |||
1134 | if (metric_only) | ||
1135 | fputc('\n', output); | ||
1136 | } | ||
1137 | |||
1106 | void | 1138 | void |
1107 | perf_evlist__print_counters(struct perf_evlist *evlist, | 1139 | perf_evlist__print_counters(struct perf_evlist *evlist, |
1108 | struct perf_stat_config *config, | 1140 | struct perf_stat_config *config, |
@@ -1153,7 +1185,10 @@ perf_evlist__print_counters(struct perf_evlist *evlist, | |||
1153 | print_no_aggr_metric(config, evlist, prefix); | 1185 | print_no_aggr_metric(config, evlist, prefix); |
1154 | else { | 1186 | else { |
1155 | evlist__for_each_entry(evlist, counter) { | 1187 | evlist__for_each_entry(evlist, counter) { |
1156 | print_counter(config, counter, prefix); | 1188 | if (counter->percore) |
1189 | print_percore(config, counter, prefix); | ||
1190 | else | ||
1191 | print_counter(config, counter, prefix); | ||
1157 | } | 1192 | } |
1158 | } | 1193 | } |
1159 | break; | 1194 | break; |
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 2856cc9d5a31..c3115d939b0b 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c | |||
@@ -277,9 +277,11 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel | |||
277 | if (!evsel->snapshot) | 277 | if (!evsel->snapshot) |
278 | perf_evsel__compute_deltas(evsel, cpu, thread, count); | 278 | perf_evsel__compute_deltas(evsel, cpu, thread, count); |
279 | perf_counts_values__scale(count, config->scale, NULL); | 279 | perf_counts_values__scale(count, config->scale, NULL); |
280 | if (config->aggr_mode == AGGR_NONE) | 280 | if ((config->aggr_mode == AGGR_NONE) && (!evsel->percore)) { |
281 | perf_stat__update_shadow_stats(evsel, count->val, cpu, | 281 | perf_stat__update_shadow_stats(evsel, count->val, |
282 | &rt_stat); | 282 | cpu, &rt_stat); |
283 | } | ||
284 | |||
283 | if (config->aggr_mode == AGGR_THREAD) { | 285 | if (config->aggr_mode == AGGR_THREAD) { |
284 | if (config->stats) | 286 | if (config->stats) |
285 | perf_stat__update_shadow_stats(evsel, | 287 | perf_stat__update_shadow_stats(evsel, |