summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
authorKan Liang <Kan.liang@intel.com>2017-05-26 15:05:38 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-06-21 10:35:35 -0400
commitdaefd0bc0bd28cea2e6b2f3e1a9da005cd4f58fc (patch)
tree81eaf64f1c5ad6f199d88322616c4c6eca157e0e /tools/perf/builtin-stat.c
parent3b00ea938653d136c8e4bcbe9722d954e128ce2e (diff)
perf stat: Add support to measure SMI cost
Implementing a new --smi-cost mode in perf stat to measure SMI cost. During the measurement, the /sys/device/cpu/freeze_on_smi will be set. The measurement can be done with one counter (unhalted core cycles), and two free running MSR counters (IA32_APERF and SMI_COUNT). In practice, the percentages of SMI core cycles should be more useful than absolute value. So the output will be the percentage of SMI core cycles and SMI#. metric_only will be set by default. SMI cycles% = (aperf - unhalted core cycles) / aperf Here is an example output. Performance counter stats for 'sudo echo ': SMI cycles% SMI# 0.1% 1 0.010858678 seconds time elapsed Users who wants to get the actual value can apply additional --no-metric-only. Signed-off-by: Kan Liang <Kan.liang@intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Andi Kleen <ak@linux.intel.com> Cc: Kan Liang <kan.liang@intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Robert Elliott <elliott@hpe.com> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1495825538-5230-3-git-send-email-kan.liang@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ad9324d1daf9..324363054c3f 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -86,6 +86,7 @@
86#define DEFAULT_SEPARATOR " " 86#define DEFAULT_SEPARATOR " "
87#define CNTR_NOT_SUPPORTED "<not supported>" 87#define CNTR_NOT_SUPPORTED "<not supported>"
88#define CNTR_NOT_COUNTED "<not counted>" 88#define CNTR_NOT_COUNTED "<not counted>"
89#define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi"
89 90
90static void print_counters(struct timespec *ts, int argc, const char **argv); 91static void print_counters(struct timespec *ts, int argc, const char **argv);
91 92
@@ -122,6 +123,14 @@ static const char * topdown_attrs[] = {
122 NULL, 123 NULL,
123}; 124};
124 125
126static const char *smi_cost_attrs = {
127 "{"
128 "msr/aperf/,"
129 "msr/smi/,"
130 "cycles"
131 "}"
132};
133
125static struct perf_evlist *evsel_list; 134static struct perf_evlist *evsel_list;
126 135
127static struct target target = { 136static struct target target = {
@@ -137,6 +146,8 @@ static bool null_run = false;
137static int detailed_run = 0; 146static int detailed_run = 0;
138static bool transaction_run; 147static bool transaction_run;
139static bool topdown_run = false; 148static bool topdown_run = false;
149static bool smi_cost = false;
150static bool smi_reset = false;
140static bool big_num = true; 151static bool big_num = true;
141static int big_num_opt = -1; 152static int big_num_opt = -1;
142static const char *csv_sep = NULL; 153static const char *csv_sep = NULL;
@@ -1782,6 +1793,8 @@ static const struct option stat_options[] = {
1782 "Only print computed metrics. No raw values", enable_metric_only), 1793 "Only print computed metrics. No raw values", enable_metric_only),
1783 OPT_BOOLEAN(0, "topdown", &topdown_run, 1794 OPT_BOOLEAN(0, "topdown", &topdown_run,
1784 "measure topdown level 1 statistics"), 1795 "measure topdown level 1 statistics"),
1796 OPT_BOOLEAN(0, "smi-cost", &smi_cost,
1797 "measure SMI cost"),
1785 OPT_END() 1798 OPT_END()
1786}; 1799};
1787 1800
@@ -2160,6 +2173,39 @@ static int add_default_attributes(void)
2160 return 0; 2173 return 0;
2161 } 2174 }
2162 2175
2176 if (smi_cost) {
2177 int smi;
2178
2179 if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) {
2180 fprintf(stderr, "freeze_on_smi is not supported.\n");
2181 return -1;
2182 }
2183
2184 if (!smi) {
2185 if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) {
2186 fprintf(stderr, "Failed to set freeze_on_smi.\n");
2187 return -1;
2188 }
2189 smi_reset = true;
2190 }
2191
2192 if (pmu_have_event("msr", "aperf") &&
2193 pmu_have_event("msr", "smi")) {
2194 if (!force_metric_only)
2195 metric_only = true;
2196 err = parse_events(evsel_list, smi_cost_attrs, NULL);
2197 } else {
2198 fprintf(stderr, "To measure SMI cost, it needs "
2199 "msr/aperf/, msr/smi/ and cpu/cycles/ support\n");
2200 return -1;
2201 }
2202 if (err) {
2203 fprintf(stderr, "Cannot set up SMI cost events\n");
2204 return -1;
2205 }
2206 return 0;
2207 }
2208
2163 if (topdown_run) { 2209 if (topdown_run) {
2164 char *str = NULL; 2210 char *str = NULL;
2165 bool warn = false; 2211 bool warn = false;
@@ -2742,6 +2788,9 @@ int cmd_stat(int argc, const char **argv)
2742 perf_stat__exit_aggr_mode(); 2788 perf_stat__exit_aggr_mode();
2743 perf_evlist__free_stats(evsel_list); 2789 perf_evlist__free_stats(evsel_list);
2744out: 2790out:
2791 if (smi_cost && smi_reset)
2792 sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
2793
2745 perf_evlist__delete(evsel_list); 2794 perf_evlist__delete(evsel_list);
2746 return status; 2795 return status;
2747} 2796}