summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ad9324d1daf9..48ac53b199fc 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;
@@ -625,14 +636,14 @@ try_again:
625 } 636 }
626 637
627 if (perf_evlist__apply_filters(evsel_list, &counter)) { 638 if (perf_evlist__apply_filters(evsel_list, &counter)) {
628 error("failed to set filter \"%s\" on event %s with %d (%s)\n", 639 pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
629 counter->filter, perf_evsel__name(counter), errno, 640 counter->filter, perf_evsel__name(counter), errno,
630 str_error_r(errno, msg, sizeof(msg))); 641 str_error_r(errno, msg, sizeof(msg)));
631 return -1; 642 return -1;
632 } 643 }
633 644
634 if (perf_evlist__apply_drv_configs(evsel_list, &counter, &err_term)) { 645 if (perf_evlist__apply_drv_configs(evsel_list, &counter, &err_term)) {
635 error("failed to set config \"%s\" on event %s with %d (%s)\n", 646 pr_err("failed to set config \"%s\" on event %s with %d (%s)\n",
636 err_term->val.drv_cfg, perf_evsel__name(counter), errno, 647 err_term->val.drv_cfg, perf_evsel__name(counter), errno,
637 str_error_r(errno, msg, sizeof(msg))); 648 str_error_r(errno, msg, sizeof(msg)));
638 return -1; 649 return -1;
@@ -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}