186470930SIngo Molnar /* 286470930SIngo Molnar * builtin-stat.c 386470930SIngo Molnar * 486470930SIngo Molnar * Builtin stat command: Give a precise performance counters summary 586470930SIngo Molnar * overview about any workload, CPU or specific PID. 686470930SIngo Molnar * 786470930SIngo Molnar * Sample output: 886470930SIngo Molnar 92cba3ffbSIngo Molnar $ perf stat ./hackbench 10 1086470930SIngo Molnar 112cba3ffbSIngo Molnar Time: 0.118 1286470930SIngo Molnar 132cba3ffbSIngo Molnar Performance counter stats for './hackbench 10': 1486470930SIngo Molnar 152cba3ffbSIngo Molnar 1708.761321 task-clock # 11.037 CPUs utilized 162cba3ffbSIngo Molnar 41,190 context-switches # 0.024 M/sec 172cba3ffbSIngo Molnar 6,735 CPU-migrations # 0.004 M/sec 182cba3ffbSIngo Molnar 17,318 page-faults # 0.010 M/sec 192cba3ffbSIngo Molnar 5,205,202,243 cycles # 3.046 GHz 202cba3ffbSIngo Molnar 3,856,436,920 stalled-cycles-frontend # 74.09% frontend cycles idle 212cba3ffbSIngo Molnar 1,600,790,871 stalled-cycles-backend # 30.75% backend cycles idle 222cba3ffbSIngo Molnar 2,603,501,247 instructions # 0.50 insns per cycle 232cba3ffbSIngo Molnar # 1.48 stalled cycles per insn 242cba3ffbSIngo Molnar 484,357,498 branches # 283.455 M/sec 252cba3ffbSIngo Molnar 6,388,934 branch-misses # 1.32% of all branches 262cba3ffbSIngo Molnar 272cba3ffbSIngo Molnar 0.154822978 seconds time elapsed 2886470930SIngo Molnar 2986470930SIngo Molnar * 302cba3ffbSIngo Molnar * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 3186470930SIngo Molnar * 3286470930SIngo Molnar * Improvements and fixes by: 3386470930SIngo Molnar * 3486470930SIngo Molnar * Arjan van de Ven <arjan@linux.intel.com> 3586470930SIngo Molnar * Yanmin Zhang <yanmin.zhang@intel.com> 3686470930SIngo Molnar * Wu Fengguang <fengguang.wu@intel.com> 3786470930SIngo Molnar * Mike Galbraith <efault@gmx.de> 3886470930SIngo Molnar * Paul Mackerras <paulus@samba.org> 396e750a8fSJaswinder Singh Rajput * Jaswinder Singh Rajput <jaswinder@kernel.org> 4086470930SIngo Molnar * 4186470930SIngo Molnar * Released under the GPL v2. (and only v2, not any later version) 4286470930SIngo Molnar */ 4386470930SIngo Molnar 4486470930SIngo Molnar #include "perf.h" 4586470930SIngo Molnar #include "builtin.h" 4686470930SIngo Molnar #include "util/util.h" 4786470930SIngo Molnar #include "util/parse-options.h" 4886470930SIngo Molnar #include "util/parse-events.h" 498f28827aSFrederic Weisbecker #include "util/event.h" 50361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 5169aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 528f28827aSFrederic Weisbecker #include "util/debug.h" 53a5d243d0SIngo Molnar #include "util/color.h" 540007eceaSXiao Guangrong #include "util/stat.h" 5560666c63SLiming Wang #include "util/header.h" 56a12b51c4SPaul Mackerras #include "util/cpumap.h" 57d6d901c2SZhang, Yanmin #include "util/thread.h" 58fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 5986470930SIngo Molnar 601f16c575SPeter Zijlstra #include <stdlib.h> 6186470930SIngo Molnar #include <sys/prctl.h> 625af52b51SStephane Eranian #include <locale.h> 6386470930SIngo Molnar 64d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR " " 652cee77c4SDavid Ahern #define CNTR_NOT_SUPPORTED "<not supported>" 662cee77c4SDavid Ahern #define CNTR_NOT_COUNTED "<not counted>" 67d7470b6aSStephane Eranian 6813370a9bSStephane Eranian static void print_stat(int argc, const char **argv); 6913370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix); 7013370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix); 7186ee6e18SStephane Eranian static void print_aggr(char *prefix); 7213370a9bSStephane Eranian 73666e6d48SRobert Richter static struct perf_evlist *evsel_list; 74361c99a6SArnaldo Carvalho de Melo 7577a6f014SNamhyung Kim static struct perf_target target = { 7677a6f014SNamhyung Kim .uid = UINT_MAX, 7777a6f014SNamhyung Kim }; 7842202dd5SIngo Molnar 7986ee6e18SStephane Eranian enum aggr_mode { 8086ee6e18SStephane Eranian AGGR_NONE, 8186ee6e18SStephane Eranian AGGR_GLOBAL, 8286ee6e18SStephane Eranian AGGR_SOCKET, 8312c08a9fSStephane Eranian AGGR_CORE, 8486ee6e18SStephane Eranian }; 8586ee6e18SStephane Eranian 863d632595SJaswinder Singh Rajput static int run_count = 1; 872e6cdf99SStephane Eranian static bool no_inherit = false; 88c0555642SIan Munsie static bool scale = true; 8986ee6e18SStephane Eranian static enum aggr_mode aggr_mode = AGGR_GLOBAL; 90d07f0b12SStephane Eranian static volatile pid_t child_pid = -1; 91c0555642SIan Munsie static bool null_run = false; 922cba3ffbSIngo Molnar static int detailed_run = 0; 93201e0b06SArnaldo Carvalho de Melo static bool big_num = true; 94d7470b6aSStephane Eranian static int big_num_opt = -1; 95d7470b6aSStephane Eranian static const char *csv_sep = NULL; 96d7470b6aSStephane Eranian static bool csv_output = false; 9743bece79SLin Ming static bool group = false; 984aa9015fSStephane Eranian static FILE *output = NULL; 991f16c575SPeter Zijlstra static const char *pre_cmd = NULL; 1001f16c575SPeter Zijlstra static const char *post_cmd = NULL; 1011f16c575SPeter Zijlstra static bool sync_run = false; 10213370a9bSStephane Eranian static unsigned int interval = 0; 103a7e191c3SFrederik Deweerdt static bool forever = false; 10413370a9bSStephane Eranian static struct timespec ref_time; 10586ee6e18SStephane Eranian static struct cpu_map *aggr_map; 10686ee6e18SStephane Eranian static int (*aggr_get_id)(struct cpu_map *m, int cpu); 1075af52b51SStephane Eranian 10860666c63SLiming Wang static volatile int done = 0; 10960666c63SLiming Wang 11069aad6f1SArnaldo Carvalho de Melo struct perf_stat { 11169aad6f1SArnaldo Carvalho de Melo struct stats res_stats[3]; 11269aad6f1SArnaldo Carvalho de Melo }; 11369aad6f1SArnaldo Carvalho de Melo 11413370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a, 11513370a9bSStephane Eranian struct timespec *b) 11613370a9bSStephane Eranian { 11713370a9bSStephane Eranian r->tv_sec = a->tv_sec - b->tv_sec; 11813370a9bSStephane Eranian if (a->tv_nsec < b->tv_nsec) { 11913370a9bSStephane Eranian r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec; 12013370a9bSStephane Eranian r->tv_sec--; 12113370a9bSStephane Eranian } else { 12213370a9bSStephane Eranian r->tv_nsec = a->tv_nsec - b->tv_nsec ; 12313370a9bSStephane Eranian } 12413370a9bSStephane Eranian } 12513370a9bSStephane Eranian 12613370a9bSStephane Eranian static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) 12713370a9bSStephane Eranian { 12813370a9bSStephane Eranian return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus; 12913370a9bSStephane Eranian } 13013370a9bSStephane Eranian 13113370a9bSStephane Eranian static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) 13213370a9bSStephane Eranian { 13313370a9bSStephane Eranian return perf_evsel__cpus(evsel)->nr; 13413370a9bSStephane Eranian } 13513370a9bSStephane Eranian 136a7e191c3SFrederik Deweerdt static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) 137a7e191c3SFrederik Deweerdt { 138a7e191c3SFrederik Deweerdt memset(evsel->priv, 0, sizeof(struct perf_stat)); 139a7e191c3SFrederik Deweerdt } 140a7e191c3SFrederik Deweerdt 141c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) 14269aad6f1SArnaldo Carvalho de Melo { 143c52b12edSArnaldo Carvalho de Melo evsel->priv = zalloc(sizeof(struct perf_stat)); 14469aad6f1SArnaldo Carvalho de Melo return evsel->priv == NULL ? -ENOMEM : 0; 14569aad6f1SArnaldo Carvalho de Melo } 14669aad6f1SArnaldo Carvalho de Melo 14769aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) 14869aad6f1SArnaldo Carvalho de Melo { 14969aad6f1SArnaldo Carvalho de Melo free(evsel->priv); 15069aad6f1SArnaldo Carvalho de Melo evsel->priv = NULL; 15169aad6f1SArnaldo Carvalho de Melo } 15269aad6f1SArnaldo Carvalho de Melo 15313370a9bSStephane Eranian static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) 1547ae92e74SYan, Zheng { 15513370a9bSStephane Eranian void *addr; 15613370a9bSStephane Eranian size_t sz; 15713370a9bSStephane Eranian 15813370a9bSStephane Eranian sz = sizeof(*evsel->counts) + 15913370a9bSStephane Eranian (perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values)); 16013370a9bSStephane Eranian 16113370a9bSStephane Eranian addr = zalloc(sz); 16213370a9bSStephane Eranian if (!addr) 16313370a9bSStephane Eranian return -ENOMEM; 16413370a9bSStephane Eranian 16513370a9bSStephane Eranian evsel->prev_raw_counts = addr; 16613370a9bSStephane Eranian 16713370a9bSStephane Eranian return 0; 1687ae92e74SYan, Zheng } 1697ae92e74SYan, Zheng 17013370a9bSStephane Eranian static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) 1717ae92e74SYan, Zheng { 17213370a9bSStephane Eranian free(evsel->prev_raw_counts); 17313370a9bSStephane Eranian evsel->prev_raw_counts = NULL; 1747ae92e74SYan, Zheng } 1757ae92e74SYan, Zheng 176d134ffb9SArnaldo Carvalho de Melo static void perf_evlist__free_stats(struct perf_evlist *evlist) 177d134ffb9SArnaldo Carvalho de Melo { 178d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 179d134ffb9SArnaldo Carvalho de Melo 180d134ffb9SArnaldo Carvalho de Melo list_for_each_entry(evsel, &evlist->entries, node) { 181d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_stat_priv(evsel); 182d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_counts(evsel); 183d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_prev_raw_counts(evsel); 184d134ffb9SArnaldo Carvalho de Melo } 185d134ffb9SArnaldo Carvalho de Melo } 186d134ffb9SArnaldo Carvalho de Melo 187d134ffb9SArnaldo Carvalho de Melo static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw) 188d134ffb9SArnaldo Carvalho de Melo { 189d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 190d134ffb9SArnaldo Carvalho de Melo 191d134ffb9SArnaldo Carvalho de Melo list_for_each_entry(evsel, &evlist->entries, node) { 192d134ffb9SArnaldo Carvalho de Melo if (perf_evsel__alloc_stat_priv(evsel) < 0 || 193d134ffb9SArnaldo Carvalho de Melo perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 || 194d134ffb9SArnaldo Carvalho de Melo (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0)) 195d134ffb9SArnaldo Carvalho de Melo goto out_free; 196d134ffb9SArnaldo Carvalho de Melo } 197d134ffb9SArnaldo Carvalho de Melo 198d134ffb9SArnaldo Carvalho de Melo return 0; 199d134ffb9SArnaldo Carvalho de Melo 200d134ffb9SArnaldo Carvalho de Melo out_free: 201d134ffb9SArnaldo Carvalho de Melo perf_evlist__free_stats(evlist); 202d134ffb9SArnaldo Carvalho de Melo return -1; 203d134ffb9SArnaldo Carvalho de Melo } 204d134ffb9SArnaldo Carvalho de Melo 205666e6d48SRobert Richter static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 206666e6d48SRobert Richter static struct stats runtime_cycles_stats[MAX_NR_CPUS]; 207666e6d48SRobert Richter static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS]; 208666e6d48SRobert Richter static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS]; 209666e6d48SRobert Richter static struct stats runtime_branches_stats[MAX_NR_CPUS]; 210666e6d48SRobert Richter static struct stats runtime_cacherefs_stats[MAX_NR_CPUS]; 211666e6d48SRobert Richter static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS]; 212666e6d48SRobert Richter static struct stats runtime_l1_icache_stats[MAX_NR_CPUS]; 213666e6d48SRobert Richter static struct stats runtime_ll_cache_stats[MAX_NR_CPUS]; 214666e6d48SRobert Richter static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; 215666e6d48SRobert Richter static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; 216666e6d48SRobert Richter static struct stats walltime_nsecs_stats; 21786470930SIngo Molnar 218d134ffb9SArnaldo Carvalho de Melo static void perf_stat__reset_stats(struct perf_evlist *evlist) 219a7e191c3SFrederik Deweerdt { 220d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 221d134ffb9SArnaldo Carvalho de Melo 222d134ffb9SArnaldo Carvalho de Melo list_for_each_entry(evsel, &evlist->entries, node) { 223d134ffb9SArnaldo Carvalho de Melo perf_evsel__reset_stat_priv(evsel); 224d134ffb9SArnaldo Carvalho de Melo perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel)); 225d134ffb9SArnaldo Carvalho de Melo } 226d134ffb9SArnaldo Carvalho de Melo 227a7e191c3SFrederik Deweerdt memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats)); 228a7e191c3SFrederik Deweerdt memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats)); 229a7e191c3SFrederik Deweerdt memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats)); 230a7e191c3SFrederik Deweerdt memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats)); 231a7e191c3SFrederik Deweerdt memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats)); 232a7e191c3SFrederik Deweerdt memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats)); 233a7e191c3SFrederik Deweerdt memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats)); 234a7e191c3SFrederik Deweerdt memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats)); 235a7e191c3SFrederik Deweerdt memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats)); 236a7e191c3SFrederik Deweerdt memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats)); 237a7e191c3SFrederik Deweerdt memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats)); 238a7e191c3SFrederik Deweerdt memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats)); 239a7e191c3SFrederik Deweerdt } 240a7e191c3SFrederik Deweerdt 241cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel) 24286470930SIngo Molnar { 24369aad6f1SArnaldo Carvalho de Melo struct perf_event_attr *attr = &evsel->attr; 244727ab04eSArnaldo Carvalho de Melo 24586470930SIngo Molnar if (scale) 24686470930SIngo Molnar attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 24786470930SIngo Molnar PERF_FORMAT_TOTAL_TIME_RUNNING; 24886470930SIngo Molnar 2492e6cdf99SStephane Eranian attr->inherit = !no_inherit; 2505d2cd909SArnaldo Carvalho de Melo 251594ac61aSArnaldo Carvalho de Melo if (perf_target__has_cpu(&target)) 252594ac61aSArnaldo Carvalho de Melo return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); 2535622c07bSStephane Eranian 25407ac002fSArnaldo Carvalho de Melo if (!perf_target__has_task(&target) && 255823254edSNamhyung Kim perf_evsel__is_group_leader(evsel)) { 25686470930SIngo Molnar attr->disabled = 1; 25757e7986eSPaul Mackerras attr->enable_on_exec = 1; 2586be2850eSZhang, Yanmin } 259084ab9f8SArnaldo Carvalho de Melo 260594ac61aSArnaldo Carvalho de Melo return perf_evsel__open_per_thread(evsel, evsel_list->threads); 26186470930SIngo Molnar } 26286470930SIngo Molnar 26386470930SIngo Molnar /* 26486470930SIngo Molnar * Does the counter have nsecs as a unit? 26586470930SIngo Molnar */ 266daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel) 26786470930SIngo Molnar { 268daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || 269daec78a0SArnaldo Carvalho de Melo perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 27086470930SIngo Molnar return 1; 27186470930SIngo Molnar 27286470930SIngo Molnar return 0; 27386470930SIngo Molnar } 27486470930SIngo Molnar 27586470930SIngo Molnar /* 276dcd9936aSIngo Molnar * Update various tracking values we maintain to print 277dcd9936aSIngo Molnar * more semantic information such as miss/hit ratios, 278dcd9936aSIngo Molnar * instruction rates, etc: 279dcd9936aSIngo Molnar */ 280dcd9936aSIngo Molnar static void update_shadow_stats(struct perf_evsel *counter, u64 *count) 281dcd9936aSIngo Molnar { 282dcd9936aSIngo Molnar if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 283dcd9936aSIngo Molnar update_stats(&runtime_nsecs_stats[0], count[0]); 284dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 285dcd9936aSIngo Molnar update_stats(&runtime_cycles_stats[0], count[0]); 286d3d1e86dSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) 287d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_front_stats[0], count[0]); 288129c04cbSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) 289d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_back_stats[0], count[0]); 290dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS)) 291dcd9936aSIngo Molnar update_stats(&runtime_branches_stats[0], count[0]); 292dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES)) 293dcd9936aSIngo Molnar update_stats(&runtime_cacherefs_stats[0], count[0]); 2948bb6c79fSIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D)) 2958bb6c79fSIngo Molnar update_stats(&runtime_l1_dcache_stats[0], count[0]); 296c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I)) 297c3305257SIngo Molnar update_stats(&runtime_l1_icache_stats[0], count[0]); 298c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL)) 299c3305257SIngo Molnar update_stats(&runtime_ll_cache_stats[0], count[0]); 300c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB)) 301c3305257SIngo Molnar update_stats(&runtime_dtlb_cache_stats[0], count[0]); 302c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) 303c3305257SIngo Molnar update_stats(&runtime_itlb_cache_stats[0], count[0]); 304dcd9936aSIngo Molnar } 305dcd9936aSIngo Molnar 306dcd9936aSIngo Molnar /* 30786470930SIngo Molnar * Read out the results of a single counter: 308f5b4a9c3SStephane Eranian * aggregate counts across CPUs in system-wide mode 30986470930SIngo Molnar */ 310c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter) 31186470930SIngo Molnar { 31269aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 313c52b12edSArnaldo Carvalho de Melo u64 *count = counter->counts->aggr.values; 314c52b12edSArnaldo Carvalho de Melo int i; 31586470930SIngo Molnar 3167ae92e74SYan, Zheng if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter), 317b3a319d5SNamhyung Kim thread_map__nr(evsel_list->threads), scale) < 0) 318c52b12edSArnaldo Carvalho de Melo return -1; 3199e9772c4SPeter Zijlstra 3209e9772c4SPeter Zijlstra for (i = 0; i < 3; i++) 32169aad6f1SArnaldo Carvalho de Melo update_stats(&ps->res_stats[i], count[i]); 3229e9772c4SPeter Zijlstra 3239e9772c4SPeter Zijlstra if (verbose) { 3244aa9015fSStephane Eranian fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 3257289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter), count[0], count[1], count[2]); 3269e9772c4SPeter Zijlstra } 3279e9772c4SPeter Zijlstra 32886470930SIngo Molnar /* 32986470930SIngo Molnar * Save the full runtime - to allow normalization during printout: 33086470930SIngo Molnar */ 331dcd9936aSIngo Molnar update_shadow_stats(counter, count); 332c52b12edSArnaldo Carvalho de Melo 333c52b12edSArnaldo Carvalho de Melo return 0; 334f5b4a9c3SStephane Eranian } 335f5b4a9c3SStephane Eranian 336f5b4a9c3SStephane Eranian /* 337f5b4a9c3SStephane Eranian * Read out the results of a single counter: 338f5b4a9c3SStephane Eranian * do not aggregate counts across CPUs in system-wide mode 339f5b4a9c3SStephane Eranian */ 340c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter) 341f5b4a9c3SStephane Eranian { 342c52b12edSArnaldo Carvalho de Melo u64 *count; 343f5b4a9c3SStephane Eranian int cpu; 344f5b4a9c3SStephane Eranian 3457ae92e74SYan, Zheng for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 346c52b12edSArnaldo Carvalho de Melo if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) 347c52b12edSArnaldo Carvalho de Melo return -1; 348f5b4a9c3SStephane Eranian 349c52b12edSArnaldo Carvalho de Melo count = counter->counts->cpu[cpu].values; 350f5b4a9c3SStephane Eranian 351dcd9936aSIngo Molnar update_shadow_stats(counter, count); 352f5b4a9c3SStephane Eranian } 353c52b12edSArnaldo Carvalho de Melo 354c52b12edSArnaldo Carvalho de Melo return 0; 35586470930SIngo Molnar } 35686470930SIngo Molnar 35713370a9bSStephane Eranian static void print_interval(void) 35813370a9bSStephane Eranian { 35913370a9bSStephane Eranian static int num_print_interval; 36013370a9bSStephane Eranian struct perf_evsel *counter; 36113370a9bSStephane Eranian struct perf_stat *ps; 36213370a9bSStephane Eranian struct timespec ts, rs; 36313370a9bSStephane Eranian char prefix[64]; 36413370a9bSStephane Eranian 36586ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) { 36613370a9bSStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) { 36713370a9bSStephane Eranian ps = counter->priv; 36813370a9bSStephane Eranian memset(ps->res_stats, 0, sizeof(ps->res_stats)); 36913370a9bSStephane Eranian read_counter_aggr(counter); 37013370a9bSStephane Eranian } 37186ee6e18SStephane Eranian } else { 37286ee6e18SStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) { 37386ee6e18SStephane Eranian ps = counter->priv; 37486ee6e18SStephane Eranian memset(ps->res_stats, 0, sizeof(ps->res_stats)); 37586ee6e18SStephane Eranian read_counter(counter); 37613370a9bSStephane Eranian } 37786ee6e18SStephane Eranian } 37886ee6e18SStephane Eranian 37913370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ts); 38013370a9bSStephane Eranian diff_timespec(&rs, &ts, &ref_time); 38113370a9bSStephane Eranian sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep); 38213370a9bSStephane Eranian 38313370a9bSStephane Eranian if (num_print_interval == 0 && !csv_output) { 38486ee6e18SStephane Eranian switch (aggr_mode) { 38586ee6e18SStephane Eranian case AGGR_SOCKET: 386d7e7a451SStephane Eranian fprintf(output, "# time socket cpus counts events\n"); 38786ee6e18SStephane Eranian break; 38812c08a9fSStephane Eranian case AGGR_CORE: 38912c08a9fSStephane Eranian fprintf(output, "# time core cpus counts events\n"); 39012c08a9fSStephane Eranian break; 39186ee6e18SStephane Eranian case AGGR_NONE: 39213370a9bSStephane Eranian fprintf(output, "# time CPU counts events\n"); 39386ee6e18SStephane Eranian break; 39486ee6e18SStephane Eranian case AGGR_GLOBAL: 39586ee6e18SStephane Eranian default: 39613370a9bSStephane Eranian fprintf(output, "# time counts events\n"); 39713370a9bSStephane Eranian } 39886ee6e18SStephane Eranian } 39913370a9bSStephane Eranian 40013370a9bSStephane Eranian if (++num_print_interval == 25) 40113370a9bSStephane Eranian num_print_interval = 0; 40213370a9bSStephane Eranian 40386ee6e18SStephane Eranian switch (aggr_mode) { 40412c08a9fSStephane Eranian case AGGR_CORE: 40586ee6e18SStephane Eranian case AGGR_SOCKET: 40686ee6e18SStephane Eranian print_aggr(prefix); 40786ee6e18SStephane Eranian break; 40886ee6e18SStephane Eranian case AGGR_NONE: 40913370a9bSStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) 41013370a9bSStephane Eranian print_counter(counter, prefix); 41186ee6e18SStephane Eranian break; 41286ee6e18SStephane Eranian case AGGR_GLOBAL: 41386ee6e18SStephane Eranian default: 41413370a9bSStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) 41513370a9bSStephane Eranian print_counter_aggr(counter, prefix); 41613370a9bSStephane Eranian } 41713370a9bSStephane Eranian } 41813370a9bSStephane Eranian 419acf28922SNamhyung Kim static int __run_perf_stat(int argc, const char **argv) 42086470930SIngo Molnar { 42156e52e85SArnaldo Carvalho de Melo char msg[512]; 42286470930SIngo Molnar unsigned long long t0, t1; 423cac21425SJiri Olsa struct perf_evsel *counter; 42413370a9bSStephane Eranian struct timespec ts; 42542202dd5SIngo Molnar int status = 0; 4266be2850eSZhang, Yanmin const bool forks = (argc > 0); 42786470930SIngo Molnar 42813370a9bSStephane Eranian if (interval) { 42913370a9bSStephane Eranian ts.tv_sec = interval / 1000; 43013370a9bSStephane Eranian ts.tv_nsec = (interval % 1000) * 1000000; 43113370a9bSStephane Eranian } else { 43213370a9bSStephane Eranian ts.tv_sec = 1; 43313370a9bSStephane Eranian ts.tv_nsec = 0; 43413370a9bSStephane Eranian } 43513370a9bSStephane Eranian 436acf28922SNamhyung Kim if (forks) { 437acf28922SNamhyung Kim if (perf_evlist__prepare_workload(evsel_list, &target, argv, 438acf28922SNamhyung Kim false, false) < 0) { 439acf28922SNamhyung Kim perror("failed to prepare workload"); 440fceda7feSDavid Ahern return -1; 441051ae7f7SPaul Mackerras } 44260666c63SLiming Wang } 443051ae7f7SPaul Mackerras 4446a4bb04cSJiri Olsa if (group) 44563dab225SArnaldo Carvalho de Melo perf_evlist__set_leader(evsel_list); 4466a4bb04cSJiri Olsa 447361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 448cac21425SJiri Olsa if (create_perf_stat_counter(counter) < 0) { 449979987a5SDavid Ahern /* 450979987a5SDavid Ahern * PPC returns ENXIO for HW counters until 2.6.37 451979987a5SDavid Ahern * (behavior changed with commit b0a873e). 452979987a5SDavid Ahern */ 45338f6ae1eSAnton Blanchard if (errno == EINVAL || errno == ENOSYS || 454979987a5SDavid Ahern errno == ENOENT || errno == EOPNOTSUPP || 455979987a5SDavid Ahern errno == ENXIO) { 456c63ca0c0SDavid Ahern if (verbose) 457c63ca0c0SDavid Ahern ui__warning("%s event is not supported by the kernel.\n", 4587289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 4592cee77c4SDavid Ahern counter->supported = false; 460ede70290SIngo Molnar continue; 461c63ca0c0SDavid Ahern } 462ede70290SIngo Molnar 46356e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(counter, &target, 46456e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 46556e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 46656e52e85SArnaldo Carvalho de Melo 467084ab9f8SArnaldo Carvalho de Melo if (child_pid != -1) 468084ab9f8SArnaldo Carvalho de Melo kill(child_pid, SIGTERM); 469fceda7feSDavid Ahern 470084ab9f8SArnaldo Carvalho de Melo return -1; 471084ab9f8SArnaldo Carvalho de Melo } 4722cee77c4SDavid Ahern counter->supported = true; 47348290609SArnaldo Carvalho de Melo } 47486470930SIngo Molnar 4751491a632SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evsel_list)) { 476cfd748aeSFrederic Weisbecker error("failed to set filter with %d (%s)\n", errno, 477cfd748aeSFrederic Weisbecker strerror(errno)); 478cfd748aeSFrederic Weisbecker return -1; 479cfd748aeSFrederic Weisbecker } 480cfd748aeSFrederic Weisbecker 48186470930SIngo Molnar /* 48286470930SIngo Molnar * Enable counters and exec the command: 48386470930SIngo Molnar */ 48486470930SIngo Molnar t0 = rdclock(); 48513370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ref_time); 48686470930SIngo Molnar 48760666c63SLiming Wang if (forks) { 488acf28922SNamhyung Kim perf_evlist__start_workload(evsel_list); 489acf28922SNamhyung Kim 49013370a9bSStephane Eranian if (interval) { 49113370a9bSStephane Eranian while (!waitpid(child_pid, &status, WNOHANG)) { 49213370a9bSStephane Eranian nanosleep(&ts, NULL); 49313370a9bSStephane Eranian print_interval(); 49413370a9bSStephane Eranian } 49513370a9bSStephane Eranian } 49642202dd5SIngo Molnar wait(&status); 49733e49ea7SAndi Kleen if (WIFSIGNALED(status)) 49833e49ea7SAndi Kleen psignal(WTERMSIG(status), argv[0]); 49960666c63SLiming Wang } else { 50013370a9bSStephane Eranian while (!done) { 50113370a9bSStephane Eranian nanosleep(&ts, NULL); 50213370a9bSStephane Eranian if (interval) 50313370a9bSStephane Eranian print_interval(); 50413370a9bSStephane Eranian } 50560666c63SLiming Wang } 50686470930SIngo Molnar 50786470930SIngo Molnar t1 = rdclock(); 50886470930SIngo Molnar 5099e9772c4SPeter Zijlstra update_stats(&walltime_nsecs_stats, t1 - t0); 51042202dd5SIngo Molnar 51186ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) { 512361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 513c52b12edSArnaldo Carvalho de Melo read_counter_aggr(counter); 5147ae92e74SYan, Zheng perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 515b3a319d5SNamhyung Kim thread_map__nr(evsel_list->threads)); 516c52b12edSArnaldo Carvalho de Melo } 51786ee6e18SStephane Eranian } else { 51886ee6e18SStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) { 51986ee6e18SStephane Eranian read_counter(counter); 52086ee6e18SStephane Eranian perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1); 52186ee6e18SStephane Eranian } 522c52b12edSArnaldo Carvalho de Melo } 523c52b12edSArnaldo Carvalho de Melo 52442202dd5SIngo Molnar return WEXITSTATUS(status); 52542202dd5SIngo Molnar } 52642202dd5SIngo Molnar 5271f16c575SPeter Zijlstra static int run_perf_stat(int argc __maybe_unused, const char **argv) 5281f16c575SPeter Zijlstra { 5291f16c575SPeter Zijlstra int ret; 5301f16c575SPeter Zijlstra 5311f16c575SPeter Zijlstra if (pre_cmd) { 5321f16c575SPeter Zijlstra ret = system(pre_cmd); 5331f16c575SPeter Zijlstra if (ret) 5341f16c575SPeter Zijlstra return ret; 5351f16c575SPeter Zijlstra } 5361f16c575SPeter Zijlstra 5371f16c575SPeter Zijlstra if (sync_run) 5381f16c575SPeter Zijlstra sync(); 5391f16c575SPeter Zijlstra 5401f16c575SPeter Zijlstra ret = __run_perf_stat(argc, argv); 5411f16c575SPeter Zijlstra if (ret) 5421f16c575SPeter Zijlstra return ret; 5431f16c575SPeter Zijlstra 5441f16c575SPeter Zijlstra if (post_cmd) { 5451f16c575SPeter Zijlstra ret = system(post_cmd); 5461f16c575SPeter Zijlstra if (ret) 5471f16c575SPeter Zijlstra return ret; 5481f16c575SPeter Zijlstra } 5491f16c575SPeter Zijlstra 5501f16c575SPeter Zijlstra return ret; 5511f16c575SPeter Zijlstra } 5521f16c575SPeter Zijlstra 553f99844cbSIngo Molnar static void print_noise_pct(double total, double avg) 554f99844cbSIngo Molnar { 5550007eceaSXiao Guangrong double pct = rel_stddev_stats(total, avg); 556f99844cbSIngo Molnar 5573ae9a34dSZhengyu He if (csv_output) 5584aa9015fSStephane Eranian fprintf(output, "%s%.2f%%", csv_sep, pct); 559a1bca6ccSJim Cromie else if (pct) 5604aa9015fSStephane Eranian fprintf(output, " ( +-%6.2f%% )", pct); 561f99844cbSIngo Molnar } 562f99844cbSIngo Molnar 56369aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg) 56442202dd5SIngo Molnar { 56569aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps; 56669aad6f1SArnaldo Carvalho de Melo 567849abde9SPeter Zijlstra if (run_count == 1) 568849abde9SPeter Zijlstra return; 569849abde9SPeter Zijlstra 57069aad6f1SArnaldo Carvalho de Melo ps = evsel->priv; 571f99844cbSIngo Molnar print_noise_pct(stddev_stats(&ps->res_stats[0]), avg); 57242202dd5SIngo Molnar } 57342202dd5SIngo Molnar 57412c08a9fSStephane Eranian static void aggr_printout(struct perf_evsel *evsel, int id, int nr) 57542202dd5SIngo Molnar { 57686ee6e18SStephane Eranian switch (aggr_mode) { 57712c08a9fSStephane Eranian case AGGR_CORE: 57812c08a9fSStephane Eranian fprintf(output, "S%d-C%*d%s%*d%s", 57912c08a9fSStephane Eranian cpu_map__id_to_socket(id), 58012c08a9fSStephane Eranian csv_output ? 0 : -8, 58112c08a9fSStephane Eranian cpu_map__id_to_cpu(id), 58212c08a9fSStephane Eranian csv_sep, 58312c08a9fSStephane Eranian csv_output ? 0 : 4, 58412c08a9fSStephane Eranian nr, 58512c08a9fSStephane Eranian csv_sep); 58612c08a9fSStephane Eranian break; 58786ee6e18SStephane Eranian case AGGR_SOCKET: 58886ee6e18SStephane Eranian fprintf(output, "S%*d%s%*d%s", 589d7e7a451SStephane Eranian csv_output ? 0 : -5, 59012c08a9fSStephane Eranian id, 591d7e7a451SStephane Eranian csv_sep, 592d7e7a451SStephane Eranian csv_output ? 0 : 4, 593d7e7a451SStephane Eranian nr, 594d7e7a451SStephane Eranian csv_sep); 59586ee6e18SStephane Eranian break; 59686ee6e18SStephane Eranian case AGGR_NONE: 59786ee6e18SStephane Eranian fprintf(output, "CPU%*d%s", 598d7470b6aSStephane Eranian csv_output ? 0 : -4, 59912c08a9fSStephane Eranian perf_evsel__cpus(evsel)->map[id], csv_sep); 60086ee6e18SStephane Eranian break; 60186ee6e18SStephane Eranian case AGGR_GLOBAL: 60286ee6e18SStephane Eranian default: 60386ee6e18SStephane Eranian break; 60486ee6e18SStephane Eranian } 60586ee6e18SStephane Eranian } 606d7470b6aSStephane Eranian 60786ee6e18SStephane Eranian static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) 60886ee6e18SStephane Eranian { 60986ee6e18SStephane Eranian double msecs = avg / 1e6; 61086ee6e18SStephane Eranian const char *fmt = csv_output ? "%.6f%s%s" : "%18.6f%s%-25s"; 61186ee6e18SStephane Eranian 61286ee6e18SStephane Eranian aggr_printout(evsel, cpu, nr); 61386ee6e18SStephane Eranian 61486ee6e18SStephane Eranian fprintf(output, fmt, msecs, csv_sep, perf_evsel__name(evsel)); 615d7470b6aSStephane Eranian 616023695d9SStephane Eranian if (evsel->cgrp) 6174aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 618023695d9SStephane Eranian 61913370a9bSStephane Eranian if (csv_output || interval) 620d7470b6aSStephane Eranian return; 62142202dd5SIngo Molnar 622daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 6234aa9015fSStephane Eranian fprintf(output, " # %8.3f CPUs utilized ", 6244aa9015fSStephane Eranian avg / avg_stats(&walltime_nsecs_stats)); 6259dac6a29SNamhyung Kim else 6269dac6a29SNamhyung Kim fprintf(output, " "); 62742202dd5SIngo Molnar } 62842202dd5SIngo Molnar 62915e6392fSNamhyung Kim /* used for get_ratio_color() */ 63015e6392fSNamhyung Kim enum grc_type { 63115e6392fSNamhyung Kim GRC_STALLED_CYCLES_FE, 63215e6392fSNamhyung Kim GRC_STALLED_CYCLES_BE, 63315e6392fSNamhyung Kim GRC_CACHE_MISSES, 63415e6392fSNamhyung Kim GRC_MAX_NR 63515e6392fSNamhyung Kim }; 63615e6392fSNamhyung Kim 63715e6392fSNamhyung Kim static const char *get_ratio_color(enum grc_type type, double ratio) 63815e6392fSNamhyung Kim { 63915e6392fSNamhyung Kim static const double grc_table[GRC_MAX_NR][3] = { 64015e6392fSNamhyung Kim [GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 }, 64115e6392fSNamhyung Kim [GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 }, 64215e6392fSNamhyung Kim [GRC_CACHE_MISSES] = { 20.0, 10.0, 5.0 }, 64315e6392fSNamhyung Kim }; 64415e6392fSNamhyung Kim const char *color = PERF_COLOR_NORMAL; 64515e6392fSNamhyung Kim 64615e6392fSNamhyung Kim if (ratio > grc_table[type][0]) 64715e6392fSNamhyung Kim color = PERF_COLOR_RED; 64815e6392fSNamhyung Kim else if (ratio > grc_table[type][1]) 64915e6392fSNamhyung Kim color = PERF_COLOR_MAGENTA; 65015e6392fSNamhyung Kim else if (ratio > grc_table[type][2]) 65115e6392fSNamhyung Kim color = PERF_COLOR_YELLOW; 65215e6392fSNamhyung Kim 65315e6392fSNamhyung Kim return color; 65415e6392fSNamhyung Kim } 65515e6392fSNamhyung Kim 6561d037ca1SIrina Tirdea static void print_stalled_cycles_frontend(int cpu, 6571d037ca1SIrina Tirdea struct perf_evsel *evsel 6581d037ca1SIrina Tirdea __maybe_unused, double avg) 659d3d1e86dSIngo Molnar { 660d3d1e86dSIngo Molnar double total, ratio = 0.0; 661d3d1e86dSIngo Molnar const char *color; 662d3d1e86dSIngo Molnar 663d3d1e86dSIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 664d3d1e86dSIngo Molnar 665d3d1e86dSIngo Molnar if (total) 666d3d1e86dSIngo Molnar ratio = avg / total * 100.0; 667d3d1e86dSIngo Molnar 66815e6392fSNamhyung Kim color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio); 669d3d1e86dSIngo Molnar 6704aa9015fSStephane Eranian fprintf(output, " # "); 6714aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6724aa9015fSStephane Eranian fprintf(output, " frontend cycles idle "); 673d3d1e86dSIngo Molnar } 674d3d1e86dSIngo Molnar 6751d037ca1SIrina Tirdea static void print_stalled_cycles_backend(int cpu, 6761d037ca1SIrina Tirdea struct perf_evsel *evsel 6771d037ca1SIrina Tirdea __maybe_unused, double avg) 678a5d243d0SIngo Molnar { 679a5d243d0SIngo Molnar double total, ratio = 0.0; 680a5d243d0SIngo Molnar const char *color; 681a5d243d0SIngo Molnar 682a5d243d0SIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 683a5d243d0SIngo Molnar 684a5d243d0SIngo Molnar if (total) 685a5d243d0SIngo Molnar ratio = avg / total * 100.0; 686a5d243d0SIngo Molnar 68715e6392fSNamhyung Kim color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio); 688a5d243d0SIngo Molnar 6894aa9015fSStephane Eranian fprintf(output, " # "); 6904aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6914aa9015fSStephane Eranian fprintf(output, " backend cycles idle "); 692a5d243d0SIngo Molnar } 693a5d243d0SIngo Molnar 6941d037ca1SIrina Tirdea static void print_branch_misses(int cpu, 6951d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 6961d037ca1SIrina Tirdea double avg) 697c78df6c1SIngo Molnar { 698c78df6c1SIngo Molnar double total, ratio = 0.0; 699c78df6c1SIngo Molnar const char *color; 700c78df6c1SIngo Molnar 701c78df6c1SIngo Molnar total = avg_stats(&runtime_branches_stats[cpu]); 702c78df6c1SIngo Molnar 703c78df6c1SIngo Molnar if (total) 704c78df6c1SIngo Molnar ratio = avg / total * 100.0; 705c78df6c1SIngo Molnar 70615e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 707c78df6c1SIngo Molnar 7084aa9015fSStephane Eranian fprintf(output, " # "); 7094aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7104aa9015fSStephane Eranian fprintf(output, " of all branches "); 711c78df6c1SIngo Molnar } 712c78df6c1SIngo Molnar 7131d037ca1SIrina Tirdea static void print_l1_dcache_misses(int cpu, 7141d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 7151d037ca1SIrina Tirdea double avg) 7168bb6c79fSIngo Molnar { 7178bb6c79fSIngo Molnar double total, ratio = 0.0; 7188bb6c79fSIngo Molnar const char *color; 7198bb6c79fSIngo Molnar 7208bb6c79fSIngo Molnar total = avg_stats(&runtime_l1_dcache_stats[cpu]); 7218bb6c79fSIngo Molnar 7228bb6c79fSIngo Molnar if (total) 7238bb6c79fSIngo Molnar ratio = avg / total * 100.0; 7248bb6c79fSIngo Molnar 72515e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 7268bb6c79fSIngo Molnar 7274aa9015fSStephane Eranian fprintf(output, " # "); 7284aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7294aa9015fSStephane Eranian fprintf(output, " of all L1-dcache hits "); 7308bb6c79fSIngo Molnar } 7318bb6c79fSIngo Molnar 7321d037ca1SIrina Tirdea static void print_l1_icache_misses(int cpu, 7331d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 7341d037ca1SIrina Tirdea double avg) 735c3305257SIngo Molnar { 736c3305257SIngo Molnar double total, ratio = 0.0; 737c3305257SIngo Molnar const char *color; 738c3305257SIngo Molnar 739c3305257SIngo Molnar total = avg_stats(&runtime_l1_icache_stats[cpu]); 740c3305257SIngo Molnar 741c3305257SIngo Molnar if (total) 742c3305257SIngo Molnar ratio = avg / total * 100.0; 743c3305257SIngo Molnar 74415e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 745c3305257SIngo Molnar 7464aa9015fSStephane Eranian fprintf(output, " # "); 7474aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7484aa9015fSStephane Eranian fprintf(output, " of all L1-icache hits "); 749c3305257SIngo Molnar } 750c3305257SIngo Molnar 7511d037ca1SIrina Tirdea static void print_dtlb_cache_misses(int cpu, 7521d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 7531d037ca1SIrina Tirdea double avg) 754c3305257SIngo Molnar { 755c3305257SIngo Molnar double total, ratio = 0.0; 756c3305257SIngo Molnar const char *color; 757c3305257SIngo Molnar 758c3305257SIngo Molnar total = avg_stats(&runtime_dtlb_cache_stats[cpu]); 759c3305257SIngo Molnar 760c3305257SIngo Molnar if (total) 761c3305257SIngo Molnar ratio = avg / total * 100.0; 762c3305257SIngo Molnar 76315e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 764c3305257SIngo Molnar 7654aa9015fSStephane Eranian fprintf(output, " # "); 7664aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7674aa9015fSStephane Eranian fprintf(output, " of all dTLB cache hits "); 768c3305257SIngo Molnar } 769c3305257SIngo Molnar 7701d037ca1SIrina Tirdea static void print_itlb_cache_misses(int cpu, 7711d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 7721d037ca1SIrina Tirdea double avg) 773c3305257SIngo Molnar { 774c3305257SIngo Molnar double total, ratio = 0.0; 775c3305257SIngo Molnar const char *color; 776c3305257SIngo Molnar 777c3305257SIngo Molnar total = avg_stats(&runtime_itlb_cache_stats[cpu]); 778c3305257SIngo Molnar 779c3305257SIngo Molnar if (total) 780c3305257SIngo Molnar ratio = avg / total * 100.0; 781c3305257SIngo Molnar 78215e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 783c3305257SIngo Molnar 7844aa9015fSStephane Eranian fprintf(output, " # "); 7854aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7864aa9015fSStephane Eranian fprintf(output, " of all iTLB cache hits "); 787c3305257SIngo Molnar } 788c3305257SIngo Molnar 7891d037ca1SIrina Tirdea static void print_ll_cache_misses(int cpu, 7901d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 7911d037ca1SIrina Tirdea double avg) 792c3305257SIngo Molnar { 793c3305257SIngo Molnar double total, ratio = 0.0; 794c3305257SIngo Molnar const char *color; 795c3305257SIngo Molnar 796c3305257SIngo Molnar total = avg_stats(&runtime_ll_cache_stats[cpu]); 797c3305257SIngo Molnar 798c3305257SIngo Molnar if (total) 799c3305257SIngo Molnar ratio = avg / total * 100.0; 800c3305257SIngo Molnar 80115e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 802c3305257SIngo Molnar 8034aa9015fSStephane Eranian fprintf(output, " # "); 8044aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 8054aa9015fSStephane Eranian fprintf(output, " of all LL-cache hits "); 806c3305257SIngo Molnar } 807c3305257SIngo Molnar 808d7e7a451SStephane Eranian static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) 80942202dd5SIngo Molnar { 810c7f7fea3SIngo Molnar double total, ratio = 0.0; 811d7470b6aSStephane Eranian const char *fmt; 812d7470b6aSStephane Eranian 813d7470b6aSStephane Eranian if (csv_output) 81486ee6e18SStephane Eranian fmt = "%.0f%s%s"; 815d7470b6aSStephane Eranian else if (big_num) 81686ee6e18SStephane Eranian fmt = "%'18.0f%s%-25s"; 817d7470b6aSStephane Eranian else 81886ee6e18SStephane Eranian fmt = "%18.0f%s%-25s"; 819f5b4a9c3SStephane Eranian 82086ee6e18SStephane Eranian aggr_printout(evsel, cpu, nr); 82186ee6e18SStephane Eranian 82286ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) 823f5b4a9c3SStephane Eranian cpu = 0; 824c7f7fea3SIngo Molnar 82586ee6e18SStephane Eranian fprintf(output, fmt, avg, csv_sep, perf_evsel__name(evsel)); 826d7470b6aSStephane Eranian 827023695d9SStephane Eranian if (evsel->cgrp) 8284aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 829023695d9SStephane Eranian 83013370a9bSStephane Eranian if (csv_output || interval) 831d7470b6aSStephane Eranian return; 83242202dd5SIngo Molnar 833daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 834f5b4a9c3SStephane Eranian total = avg_stats(&runtime_cycles_stats[cpu]); 835c7f7fea3SIngo Molnar if (total) 836c7f7fea3SIngo Molnar ratio = avg / total; 837c7f7fea3SIngo Molnar 8384aa9015fSStephane Eranian fprintf(output, " # %5.2f insns per cycle ", ratio); 839481f988aSIngo Molnar 840d3d1e86dSIngo Molnar total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]); 841d3d1e86dSIngo Molnar total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu])); 842481f988aSIngo Molnar 843481f988aSIngo Molnar if (total && avg) { 844481f988aSIngo Molnar ratio = total / avg; 8454aa9015fSStephane Eranian fprintf(output, "\n # %5.2f stalled cycles per insn", ratio); 846481f988aSIngo Molnar } 847481f988aSIngo Molnar 848daec78a0SArnaldo Carvalho de Melo } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 849f5b4a9c3SStephane Eranian runtime_branches_stats[cpu].n != 0) { 850c78df6c1SIngo Molnar print_branch_misses(cpu, evsel, avg); 8518bb6c79fSIngo Molnar } else if ( 8528bb6c79fSIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 8538bb6c79fSIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D | 8548bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 8558bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 856c6264defSIngo Molnar runtime_l1_dcache_stats[cpu].n != 0) { 8578bb6c79fSIngo Molnar print_l1_dcache_misses(cpu, evsel, avg); 858c3305257SIngo Molnar } else if ( 859c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 860c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I | 861c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 862c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 863c3305257SIngo Molnar runtime_l1_icache_stats[cpu].n != 0) { 864c3305257SIngo Molnar print_l1_icache_misses(cpu, evsel, avg); 865c3305257SIngo Molnar } else if ( 866c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 867c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB | 868c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 869c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 870c3305257SIngo Molnar runtime_dtlb_cache_stats[cpu].n != 0) { 871c3305257SIngo Molnar print_dtlb_cache_misses(cpu, evsel, avg); 872c3305257SIngo Molnar } else if ( 873c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 874c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB | 875c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 876c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 877c3305257SIngo Molnar runtime_itlb_cache_stats[cpu].n != 0) { 878c3305257SIngo Molnar print_itlb_cache_misses(cpu, evsel, avg); 879c3305257SIngo Molnar } else if ( 880c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 881c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL | 882c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 883c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 884c3305257SIngo Molnar runtime_ll_cache_stats[cpu].n != 0) { 885c3305257SIngo Molnar print_ll_cache_misses(cpu, evsel, avg); 886d58f4c82SIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) && 887d58f4c82SIngo Molnar runtime_cacherefs_stats[cpu].n != 0) { 888d58f4c82SIngo Molnar total = avg_stats(&runtime_cacherefs_stats[cpu]); 889d58f4c82SIngo Molnar 890d58f4c82SIngo Molnar if (total) 891d58f4c82SIngo Molnar ratio = avg * 100 / total; 892d58f4c82SIngo Molnar 8934aa9015fSStephane Eranian fprintf(output, " # %8.3f %% of all cache refs ", ratio); 894d58f4c82SIngo Molnar 895d3d1e86dSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 896d3d1e86dSIngo Molnar print_stalled_cycles_frontend(cpu, evsel, avg); 897129c04cbSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) { 898d3d1e86dSIngo Molnar print_stalled_cycles_backend(cpu, evsel, avg); 899481f988aSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) { 900481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 901481f988aSIngo Molnar 902481f988aSIngo Molnar if (total) 903481f988aSIngo Molnar ratio = 1.0 * avg / total; 904481f988aSIngo Molnar 9054aa9015fSStephane Eranian fprintf(output, " # %8.3f GHz ", ratio); 906481f988aSIngo Molnar } else if (runtime_nsecs_stats[cpu].n != 0) { 9075fde2523SNamhyung Kim char unit = 'M'; 9085fde2523SNamhyung Kim 909481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 910481f988aSIngo Molnar 911481f988aSIngo Molnar if (total) 912481f988aSIngo Molnar ratio = 1000.0 * avg / total; 9135fde2523SNamhyung Kim if (ratio < 0.001) { 9145fde2523SNamhyung Kim ratio *= 1000; 9155fde2523SNamhyung Kim unit = 'K'; 9165fde2523SNamhyung Kim } 917481f988aSIngo Molnar 9185fde2523SNamhyung Kim fprintf(output, " # %8.3f %c/sec ", ratio, unit); 919a5d243d0SIngo Molnar } else { 9204aa9015fSStephane Eranian fprintf(output, " "); 92142202dd5SIngo Molnar } 92242202dd5SIngo Molnar } 92342202dd5SIngo Molnar 92486ee6e18SStephane Eranian static void print_aggr(char *prefix) 925d7e7a451SStephane Eranian { 926d7e7a451SStephane Eranian struct perf_evsel *counter; 927582ec082SStephane Eranian int cpu, cpu2, s, s2, id, nr; 928d7e7a451SStephane Eranian u64 ena, run, val; 929d7e7a451SStephane Eranian 93086ee6e18SStephane Eranian if (!(aggr_map || aggr_get_id)) 931d7e7a451SStephane Eranian return; 932d7e7a451SStephane Eranian 93386ee6e18SStephane Eranian for (s = 0; s < aggr_map->nr; s++) { 93486ee6e18SStephane Eranian id = aggr_map->map[s]; 935d7e7a451SStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) { 936d7e7a451SStephane Eranian val = ena = run = 0; 937d7e7a451SStephane Eranian nr = 0; 938d7e7a451SStephane Eranian for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 939582ec082SStephane Eranian cpu2 = perf_evsel__cpus(counter)->map[cpu]; 940582ec082SStephane Eranian s2 = aggr_get_id(evsel_list->cpus, cpu2); 94186ee6e18SStephane Eranian if (s2 != id) 942d7e7a451SStephane Eranian continue; 943d7e7a451SStephane Eranian val += counter->counts->cpu[cpu].val; 944d7e7a451SStephane Eranian ena += counter->counts->cpu[cpu].ena; 945d7e7a451SStephane Eranian run += counter->counts->cpu[cpu].run; 946d7e7a451SStephane Eranian nr++; 947d7e7a451SStephane Eranian } 948d7e7a451SStephane Eranian if (prefix) 949d7e7a451SStephane Eranian fprintf(output, "%s", prefix); 950d7e7a451SStephane Eranian 951d7e7a451SStephane Eranian if (run == 0 || ena == 0) { 952582ec082SStephane Eranian aggr_printout(counter, id, nr); 95386ee6e18SStephane Eranian 95486ee6e18SStephane Eranian fprintf(output, "%*s%s%*s", 955d7e7a451SStephane Eranian csv_output ? 0 : 18, 956d7e7a451SStephane Eranian counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 957d7e7a451SStephane Eranian csv_sep, 958d7e7a451SStephane Eranian csv_output ? 0 : -24, 959d7e7a451SStephane Eranian perf_evsel__name(counter)); 96086ee6e18SStephane Eranian 961d7e7a451SStephane Eranian if (counter->cgrp) 962d7e7a451SStephane Eranian fprintf(output, "%s%s", 963d7e7a451SStephane Eranian csv_sep, counter->cgrp->name); 964d7e7a451SStephane Eranian 965d7e7a451SStephane Eranian fputc('\n', output); 966d7e7a451SStephane Eranian continue; 967d7e7a451SStephane Eranian } 968d7e7a451SStephane Eranian 969d7e7a451SStephane Eranian if (nsec_counter(counter)) 97086ee6e18SStephane Eranian nsec_printout(id, nr, counter, val); 971d7e7a451SStephane Eranian else 97286ee6e18SStephane Eranian abs_printout(id, nr, counter, val); 973d7e7a451SStephane Eranian 974d7e7a451SStephane Eranian if (!csv_output) { 975d7e7a451SStephane Eranian print_noise(counter, 1.0); 976d7e7a451SStephane Eranian 977d7e7a451SStephane Eranian if (run != ena) 978d7e7a451SStephane Eranian fprintf(output, " (%.2f%%)", 979d7e7a451SStephane Eranian 100.0 * run / ena); 980d7e7a451SStephane Eranian } 981d7e7a451SStephane Eranian fputc('\n', output); 982d7e7a451SStephane Eranian } 983d7e7a451SStephane Eranian } 984d7e7a451SStephane Eranian } 985d7e7a451SStephane Eranian 98642202dd5SIngo Molnar /* 98742202dd5SIngo Molnar * Print out the results of a single counter: 988f5b4a9c3SStephane Eranian * aggregated counts in system-wide mode 98942202dd5SIngo Molnar */ 99013370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix) 99142202dd5SIngo Molnar { 99269aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 99369aad6f1SArnaldo Carvalho de Melo double avg = avg_stats(&ps->res_stats[0]); 994c52b12edSArnaldo Carvalho de Melo int scaled = counter->counts->scaled; 99542202dd5SIngo Molnar 99613370a9bSStephane Eranian if (prefix) 99713370a9bSStephane Eranian fprintf(output, "%s", prefix); 99813370a9bSStephane Eranian 99942202dd5SIngo Molnar if (scaled == -1) { 10004aa9015fSStephane Eranian fprintf(output, "%*s%s%*s", 1001d7470b6aSStephane Eranian csv_output ? 0 : 18, 10022cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 1003023695d9SStephane Eranian csv_sep, 1004023695d9SStephane Eranian csv_output ? 0 : -24, 10057289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 1006023695d9SStephane Eranian 1007023695d9SStephane Eranian if (counter->cgrp) 10084aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, counter->cgrp->name); 1009023695d9SStephane Eranian 10104aa9015fSStephane Eranian fputc('\n', output); 101142202dd5SIngo Molnar return; 101242202dd5SIngo Molnar } 101342202dd5SIngo Molnar 101442202dd5SIngo Molnar if (nsec_counter(counter)) 1015d7e7a451SStephane Eranian nsec_printout(-1, 0, counter, avg); 101642202dd5SIngo Molnar else 1017d7e7a451SStephane Eranian abs_printout(-1, 0, counter, avg); 1018849abde9SPeter Zijlstra 10193ae9a34dSZhengyu He print_noise(counter, avg); 10203ae9a34dSZhengyu He 1021d7470b6aSStephane Eranian if (csv_output) { 10224aa9015fSStephane Eranian fputc('\n', output); 1023d7470b6aSStephane Eranian return; 1024d7470b6aSStephane Eranian } 1025d7470b6aSStephane Eranian 1026506d4bc8SPeter Zijlstra if (scaled) { 1027506d4bc8SPeter Zijlstra double avg_enabled, avg_running; 1028506d4bc8SPeter Zijlstra 102969aad6f1SArnaldo Carvalho de Melo avg_enabled = avg_stats(&ps->res_stats[1]); 103069aad6f1SArnaldo Carvalho de Melo avg_running = avg_stats(&ps->res_stats[2]); 1031506d4bc8SPeter Zijlstra 10324aa9015fSStephane Eranian fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled); 1033506d4bc8SPeter Zijlstra } 10344aa9015fSStephane Eranian fprintf(output, "\n"); 103542202dd5SIngo Molnar } 103642202dd5SIngo Molnar 1037f5b4a9c3SStephane Eranian /* 1038f5b4a9c3SStephane Eranian * Print out the results of a single counter: 1039f5b4a9c3SStephane Eranian * does not use aggregated count in system-wide 1040f5b4a9c3SStephane Eranian */ 104113370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix) 1042f5b4a9c3SStephane Eranian { 1043f5b4a9c3SStephane Eranian u64 ena, run, val; 1044f5b4a9c3SStephane Eranian int cpu; 1045f5b4a9c3SStephane Eranian 10467ae92e74SYan, Zheng for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 1047c52b12edSArnaldo Carvalho de Melo val = counter->counts->cpu[cpu].val; 1048c52b12edSArnaldo Carvalho de Melo ena = counter->counts->cpu[cpu].ena; 1049c52b12edSArnaldo Carvalho de Melo run = counter->counts->cpu[cpu].run; 105013370a9bSStephane Eranian 105113370a9bSStephane Eranian if (prefix) 105213370a9bSStephane Eranian fprintf(output, "%s", prefix); 105313370a9bSStephane Eranian 1054f5b4a9c3SStephane Eranian if (run == 0 || ena == 0) { 10554aa9015fSStephane Eranian fprintf(output, "CPU%*d%s%*s%s%*s", 1056d7470b6aSStephane Eranian csv_output ? 0 : -4, 10577ae92e74SYan, Zheng perf_evsel__cpus(counter)->map[cpu], csv_sep, 1058d7470b6aSStephane Eranian csv_output ? 0 : 18, 10592cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 10602cee77c4SDavid Ahern csv_sep, 1061023695d9SStephane Eranian csv_output ? 0 : -24, 10627289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 1063f5b4a9c3SStephane Eranian 1064023695d9SStephane Eranian if (counter->cgrp) 10654aa9015fSStephane Eranian fprintf(output, "%s%s", 10664aa9015fSStephane Eranian csv_sep, counter->cgrp->name); 1067023695d9SStephane Eranian 10684aa9015fSStephane Eranian fputc('\n', output); 1069f5b4a9c3SStephane Eranian continue; 1070f5b4a9c3SStephane Eranian } 1071f5b4a9c3SStephane Eranian 1072f5b4a9c3SStephane Eranian if (nsec_counter(counter)) 1073d7e7a451SStephane Eranian nsec_printout(cpu, 0, counter, val); 1074f5b4a9c3SStephane Eranian else 1075d7e7a451SStephane Eranian abs_printout(cpu, 0, counter, val); 1076f5b4a9c3SStephane Eranian 1077d7470b6aSStephane Eranian if (!csv_output) { 1078f5b4a9c3SStephane Eranian print_noise(counter, 1.0); 1079f5b4a9c3SStephane Eranian 1080c6264defSIngo Molnar if (run != ena) 10814aa9015fSStephane Eranian fprintf(output, " (%.2f%%)", 10824aa9015fSStephane Eranian 100.0 * run / ena); 1083d7470b6aSStephane Eranian } 10844aa9015fSStephane Eranian fputc('\n', output); 1085f5b4a9c3SStephane Eranian } 1086f5b4a9c3SStephane Eranian } 1087f5b4a9c3SStephane Eranian 108842202dd5SIngo Molnar static void print_stat(int argc, const char **argv) 108942202dd5SIngo Molnar { 109069aad6f1SArnaldo Carvalho de Melo struct perf_evsel *counter; 109169aad6f1SArnaldo Carvalho de Melo int i; 109242202dd5SIngo Molnar 109386470930SIngo Molnar fflush(stdout); 109486470930SIngo Molnar 1095d7470b6aSStephane Eranian if (!csv_output) { 10964aa9015fSStephane Eranian fprintf(output, "\n"); 10974aa9015fSStephane Eranian fprintf(output, " Performance counter stats for "); 1098aa22dd49SNamhyung Kim if (!perf_target__has_task(&target)) { 10994aa9015fSStephane Eranian fprintf(output, "\'%s", argv[0]); 110086470930SIngo Molnar for (i = 1; i < argc; i++) 11014aa9015fSStephane Eranian fprintf(output, " %s", argv[i]); 110220f946b4SNamhyung Kim } else if (target.pid) 110320f946b4SNamhyung Kim fprintf(output, "process id \'%s", target.pid); 1104d6d901c2SZhang, Yanmin else 110520f946b4SNamhyung Kim fprintf(output, "thread id \'%s", target.tid); 110686470930SIngo Molnar 11074aa9015fSStephane Eranian fprintf(output, "\'"); 110842202dd5SIngo Molnar if (run_count > 1) 11094aa9015fSStephane Eranian fprintf(output, " (%d runs)", run_count); 11104aa9015fSStephane Eranian fprintf(output, ":\n\n"); 1111d7470b6aSStephane Eranian } 111286470930SIngo Molnar 111386ee6e18SStephane Eranian switch (aggr_mode) { 111412c08a9fSStephane Eranian case AGGR_CORE: 111586ee6e18SStephane Eranian case AGGR_SOCKET: 111686ee6e18SStephane Eranian print_aggr(NULL); 111786ee6e18SStephane Eranian break; 111886ee6e18SStephane Eranian case AGGR_GLOBAL: 1119361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) 112013370a9bSStephane Eranian print_counter_aggr(counter, NULL); 112186ee6e18SStephane Eranian break; 112286ee6e18SStephane Eranian case AGGR_NONE: 112386ee6e18SStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) 112486ee6e18SStephane Eranian print_counter(counter, NULL); 112586ee6e18SStephane Eranian break; 112686ee6e18SStephane Eranian default: 112786ee6e18SStephane Eranian break; 1128f5b4a9c3SStephane Eranian } 112986470930SIngo Molnar 1130d7470b6aSStephane Eranian if (!csv_output) { 1131c3305257SIngo Molnar if (!null_run) 11324aa9015fSStephane Eranian fprintf(output, "\n"); 11334aa9015fSStephane Eranian fprintf(output, " %17.9f seconds time elapsed", 1134506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)/1e9); 1135566747e6SIngo Molnar if (run_count > 1) { 11364aa9015fSStephane Eranian fprintf(output, " "); 1137f99844cbSIngo Molnar print_noise_pct(stddev_stats(&walltime_nsecs_stats), 1138506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)); 1139566747e6SIngo Molnar } 11404aa9015fSStephane Eranian fprintf(output, "\n\n"); 114186470930SIngo Molnar } 1142d7470b6aSStephane Eranian } 114386470930SIngo Molnar 1144f7b7c26eSPeter Zijlstra static volatile int signr = -1; 1145f7b7c26eSPeter Zijlstra 114686470930SIngo Molnar static void skip_signal(int signo) 114786470930SIngo Molnar { 114813370a9bSStephane Eranian if ((child_pid == -1) || interval) 114960666c63SLiming Wang done = 1; 115060666c63SLiming Wang 1151f7b7c26eSPeter Zijlstra signr = signo; 1152d07f0b12SStephane Eranian /* 1153d07f0b12SStephane Eranian * render child_pid harmless 1154d07f0b12SStephane Eranian * won't send SIGTERM to a random 1155d07f0b12SStephane Eranian * process in case of race condition 1156d07f0b12SStephane Eranian * and fast PID recycling 1157d07f0b12SStephane Eranian */ 1158d07f0b12SStephane Eranian child_pid = -1; 1159f7b7c26eSPeter Zijlstra } 1160f7b7c26eSPeter Zijlstra 1161f7b7c26eSPeter Zijlstra static void sig_atexit(void) 1162f7b7c26eSPeter Zijlstra { 1163d07f0b12SStephane Eranian sigset_t set, oset; 1164d07f0b12SStephane Eranian 1165d07f0b12SStephane Eranian /* 1166d07f0b12SStephane Eranian * avoid race condition with SIGCHLD handler 1167d07f0b12SStephane Eranian * in skip_signal() which is modifying child_pid 1168d07f0b12SStephane Eranian * goal is to avoid send SIGTERM to a random 1169d07f0b12SStephane Eranian * process 1170d07f0b12SStephane Eranian */ 1171d07f0b12SStephane Eranian sigemptyset(&set); 1172d07f0b12SStephane Eranian sigaddset(&set, SIGCHLD); 1173d07f0b12SStephane Eranian sigprocmask(SIG_BLOCK, &set, &oset); 1174d07f0b12SStephane Eranian 1175933da83aSChris Wilson if (child_pid != -1) 1176933da83aSChris Wilson kill(child_pid, SIGTERM); 1177933da83aSChris Wilson 1178d07f0b12SStephane Eranian sigprocmask(SIG_SETMASK, &oset, NULL); 1179d07f0b12SStephane Eranian 1180f7b7c26eSPeter Zijlstra if (signr == -1) 1181f7b7c26eSPeter Zijlstra return; 1182f7b7c26eSPeter Zijlstra 1183f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 1184f7b7c26eSPeter Zijlstra kill(getpid(), signr); 118586470930SIngo Molnar } 118686470930SIngo Molnar 11871d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused, 11881d037ca1SIrina Tirdea const char *s __maybe_unused, int unset) 1189d7470b6aSStephane Eranian { 1190d7470b6aSStephane Eranian big_num_opt = unset ? 0 : 1; 1191d7470b6aSStephane Eranian return 0; 1192d7470b6aSStephane Eranian } 1193d7470b6aSStephane Eranian 119486ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void) 119586ee6e18SStephane Eranian { 119686ee6e18SStephane Eranian switch (aggr_mode) { 119786ee6e18SStephane Eranian case AGGR_SOCKET: 119886ee6e18SStephane Eranian if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) { 119986ee6e18SStephane Eranian perror("cannot build socket map"); 120086ee6e18SStephane Eranian return -1; 120186ee6e18SStephane Eranian } 120286ee6e18SStephane Eranian aggr_get_id = cpu_map__get_socket; 120386ee6e18SStephane Eranian break; 120412c08a9fSStephane Eranian case AGGR_CORE: 120512c08a9fSStephane Eranian if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) { 120612c08a9fSStephane Eranian perror("cannot build core map"); 120712c08a9fSStephane Eranian return -1; 120812c08a9fSStephane Eranian } 120912c08a9fSStephane Eranian aggr_get_id = cpu_map__get_core; 121012c08a9fSStephane Eranian break; 121186ee6e18SStephane Eranian case AGGR_NONE: 121286ee6e18SStephane Eranian case AGGR_GLOBAL: 121386ee6e18SStephane Eranian default: 121486ee6e18SStephane Eranian break; 121586ee6e18SStephane Eranian } 121686ee6e18SStephane Eranian return 0; 121786ee6e18SStephane Eranian } 121886ee6e18SStephane Eranian 121986ee6e18SStephane Eranian 12202cba3ffbSIngo Molnar /* 12212cba3ffbSIngo Molnar * Add default attributes, if there were no attributes specified or 12222cba3ffbSIngo Molnar * if -d/--detailed, -d -d or -d -d -d is used: 12232cba3ffbSIngo Molnar */ 12242cba3ffbSIngo Molnar static int add_default_attributes(void) 12252cba3ffbSIngo Molnar { 1226b070a547SArnaldo Carvalho de Melo struct perf_event_attr default_attrs[] = { 1227b070a547SArnaldo Carvalho de Melo 1228b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 1229b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 1230b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 1231b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 1232b070a547SArnaldo Carvalho de Melo 1233b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 1234b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 1235b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 1236b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 1237b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 1238b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 1239b070a547SArnaldo Carvalho de Melo 1240b070a547SArnaldo Carvalho de Melo }; 1241b070a547SArnaldo Carvalho de Melo 1242b070a547SArnaldo Carvalho de Melo /* 1243b070a547SArnaldo Carvalho de Melo * Detailed stats (-d), covering the L1 and last level data caches: 1244b070a547SArnaldo Carvalho de Melo */ 1245b070a547SArnaldo Carvalho de Melo struct perf_event_attr detailed_attrs[] = { 1246b070a547SArnaldo Carvalho de Melo 1247b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1248b070a547SArnaldo Carvalho de Melo .config = 1249b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1250b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1251b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1252b070a547SArnaldo Carvalho de Melo 1253b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1254b070a547SArnaldo Carvalho de Melo .config = 1255b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1256b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1257b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1258b070a547SArnaldo Carvalho de Melo 1259b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1260b070a547SArnaldo Carvalho de Melo .config = 1261b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1262b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1263b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1264b070a547SArnaldo Carvalho de Melo 1265b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1266b070a547SArnaldo Carvalho de Melo .config = 1267b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1268b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1269b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1270b070a547SArnaldo Carvalho de Melo }; 1271b070a547SArnaldo Carvalho de Melo 1272b070a547SArnaldo Carvalho de Melo /* 1273b070a547SArnaldo Carvalho de Melo * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: 1274b070a547SArnaldo Carvalho de Melo */ 1275b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_detailed_attrs[] = { 1276b070a547SArnaldo Carvalho de Melo 1277b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1278b070a547SArnaldo Carvalho de Melo .config = 1279b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1280b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1281b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1282b070a547SArnaldo Carvalho de Melo 1283b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1284b070a547SArnaldo Carvalho de Melo .config = 1285b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1286b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1287b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1288b070a547SArnaldo Carvalho de Melo 1289b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1290b070a547SArnaldo Carvalho de Melo .config = 1291b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1292b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1293b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1294b070a547SArnaldo Carvalho de Melo 1295b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1296b070a547SArnaldo Carvalho de Melo .config = 1297b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1298b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1299b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1300b070a547SArnaldo Carvalho de Melo 1301b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1302b070a547SArnaldo Carvalho de Melo .config = 1303b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1304b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1305b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1306b070a547SArnaldo Carvalho de Melo 1307b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1308b070a547SArnaldo Carvalho de Melo .config = 1309b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1310b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1311b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1312b070a547SArnaldo Carvalho de Melo 1313b070a547SArnaldo Carvalho de Melo }; 1314b070a547SArnaldo Carvalho de Melo 1315b070a547SArnaldo Carvalho de Melo /* 1316b070a547SArnaldo Carvalho de Melo * Very, very detailed stats (-d -d -d), adding prefetch events: 1317b070a547SArnaldo Carvalho de Melo */ 1318b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_very_detailed_attrs[] = { 1319b070a547SArnaldo Carvalho de Melo 1320b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1321b070a547SArnaldo Carvalho de Melo .config = 1322b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1323b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1324b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1325b070a547SArnaldo Carvalho de Melo 1326b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1327b070a547SArnaldo Carvalho de Melo .config = 1328b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1329b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1330b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1331b070a547SArnaldo Carvalho de Melo }; 1332b070a547SArnaldo Carvalho de Melo 13332cba3ffbSIngo Molnar /* Set attrs if no event is selected and !null_run: */ 13342cba3ffbSIngo Molnar if (null_run) 13352cba3ffbSIngo Molnar return 0; 13362cba3ffbSIngo Molnar 13372cba3ffbSIngo Molnar if (!evsel_list->nr_entries) { 133879695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0) 13392cba3ffbSIngo Molnar return -1; 13402cba3ffbSIngo Molnar } 13412cba3ffbSIngo Molnar 13422cba3ffbSIngo Molnar /* Detailed events get appended to the event list: */ 13432cba3ffbSIngo Molnar 13442cba3ffbSIngo Molnar if (detailed_run < 1) 13452cba3ffbSIngo Molnar return 0; 13462cba3ffbSIngo Molnar 13472cba3ffbSIngo Molnar /* Append detailed run extra attributes: */ 134879695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) 13492cba3ffbSIngo Molnar return -1; 13502cba3ffbSIngo Molnar 13512cba3ffbSIngo Molnar if (detailed_run < 2) 13522cba3ffbSIngo Molnar return 0; 13532cba3ffbSIngo Molnar 13542cba3ffbSIngo Molnar /* Append very detailed run extra attributes: */ 135579695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) 13562cba3ffbSIngo Molnar return -1; 13572cba3ffbSIngo Molnar 13582cba3ffbSIngo Molnar if (detailed_run < 3) 13592cba3ffbSIngo Molnar return 0; 13602cba3ffbSIngo Molnar 13612cba3ffbSIngo Molnar /* Append very, very detailed run extra attributes: */ 136279695e1bSArnaldo Carvalho de Melo return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); 13632cba3ffbSIngo Molnar } 13642cba3ffbSIngo Molnar 13651d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) 136686470930SIngo Molnar { 13671f16c575SPeter Zijlstra bool append_file = false; 1368b070a547SArnaldo Carvalho de Melo int output_fd = 0; 1369b070a547SArnaldo Carvalho de Melo const char *output_name = NULL; 1370b070a547SArnaldo Carvalho de Melo const struct option options[] = { 1371b070a547SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &evsel_list, "event", 1372b070a547SArnaldo Carvalho de Melo "event selector. use 'perf list' to list available events", 1373b070a547SArnaldo Carvalho de Melo parse_events_option), 1374b070a547SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &evsel_list, "filter", 1375b070a547SArnaldo Carvalho de Melo "event filter", parse_filter), 1376b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('i', "no-inherit", &no_inherit, 1377b070a547SArnaldo Carvalho de Melo "child tasks do not inherit counters"), 1378b070a547SArnaldo Carvalho de Melo OPT_STRING('p', "pid", &target.pid, "pid", 1379b070a547SArnaldo Carvalho de Melo "stat events on existing process id"), 1380b070a547SArnaldo Carvalho de Melo OPT_STRING('t', "tid", &target.tid, "tid", 1381b070a547SArnaldo Carvalho de Melo "stat events on existing thread id"), 1382b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('a', "all-cpus", &target.system_wide, 1383b070a547SArnaldo Carvalho de Melo "system-wide collection from all CPUs"), 1384b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('g', "group", &group, 1385b070a547SArnaldo Carvalho de Melo "put the counters into a counter group"), 1386b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"), 1387b070a547SArnaldo Carvalho de Melo OPT_INCR('v', "verbose", &verbose, 1388b070a547SArnaldo Carvalho de Melo "be more verbose (show counter open errors, etc)"), 1389b070a547SArnaldo Carvalho de Melo OPT_INTEGER('r', "repeat", &run_count, 1390a7e191c3SFrederik Deweerdt "repeat command and print average + stddev (max: 100, forever: 0)"), 1391b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "null", &null_run, 1392b070a547SArnaldo Carvalho de Melo "null run - dont start any counters"), 1393b070a547SArnaldo Carvalho de Melo OPT_INCR('d', "detailed", &detailed_run, 1394b070a547SArnaldo Carvalho de Melo "detailed run - start a lot of events"), 1395b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('S', "sync", &sync_run, 1396b070a547SArnaldo Carvalho de Melo "call sync() before starting a run"), 1397b070a547SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 1398b070a547SArnaldo Carvalho de Melo "print large numbers with thousands\' separators", 1399b070a547SArnaldo Carvalho de Melo stat__set_big_num), 1400b070a547SArnaldo Carvalho de Melo OPT_STRING('C', "cpu", &target.cpu_list, "cpu", 1401b070a547SArnaldo Carvalho de Melo "list of cpus to monitor in system-wide"), 140286ee6e18SStephane Eranian OPT_SET_UINT('A', "no-aggr", &aggr_mode, 140386ee6e18SStephane Eranian "disable CPU count aggregation", AGGR_NONE), 1404b070a547SArnaldo Carvalho de Melo OPT_STRING('x', "field-separator", &csv_sep, "separator", 1405b070a547SArnaldo Carvalho de Melo "print counts with custom separator"), 1406b070a547SArnaldo Carvalho de Melo OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1407b070a547SArnaldo Carvalho de Melo "monitor event in cgroup name only", parse_cgroups), 1408b070a547SArnaldo Carvalho de Melo OPT_STRING('o', "output", &output_name, "file", "output file name"), 1409b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), 1410b070a547SArnaldo Carvalho de Melo OPT_INTEGER(0, "log-fd", &output_fd, 1411b070a547SArnaldo Carvalho de Melo "log output to fd, instead of stderr"), 14121f16c575SPeter Zijlstra OPT_STRING(0, "pre", &pre_cmd, "command", 14131f16c575SPeter Zijlstra "command to run prior to the measured command"), 14141f16c575SPeter Zijlstra OPT_STRING(0, "post", &post_cmd, "command", 14151f16c575SPeter Zijlstra "command to run after to the measured command"), 141613370a9bSStephane Eranian OPT_UINTEGER('I', "interval-print", &interval, 141713370a9bSStephane Eranian "print counts at regular interval in ms (>= 100)"), 1418d4304958SStephane Eranian OPT_SET_UINT(0, "per-socket", &aggr_mode, 141986ee6e18SStephane Eranian "aggregate counts per processor socket", AGGR_SOCKET), 142012c08a9fSStephane Eranian OPT_SET_UINT(0, "per-core", &aggr_mode, 142112c08a9fSStephane Eranian "aggregate counts per physical processor core", AGGR_CORE), 1422b070a547SArnaldo Carvalho de Melo OPT_END() 1423b070a547SArnaldo Carvalho de Melo }; 1424b070a547SArnaldo Carvalho de Melo const char * const stat_usage[] = { 1425b070a547SArnaldo Carvalho de Melo "perf stat [<options>] [<command>]", 1426b070a547SArnaldo Carvalho de Melo NULL 1427b070a547SArnaldo Carvalho de Melo }; 1428b070a547SArnaldo Carvalho de Melo int status = -ENOMEM, run_idx; 14294aa9015fSStephane Eranian const char *mode; 143042202dd5SIngo Molnar 14315af52b51SStephane Eranian setlocale(LC_ALL, ""); 14325af52b51SStephane Eranian 1433334fe7a3SNamhyung Kim evsel_list = perf_evlist__new(); 1434361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 1435361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1436361c99a6SArnaldo Carvalho de Melo 1437a0541234SAnton Blanchard argc = parse_options(argc, argv, options, stat_usage, 1438a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 1439d7470b6aSStephane Eranian 14404aa9015fSStephane Eranian output = stderr; 14414aa9015fSStephane Eranian if (output_name && strcmp(output_name, "-")) 14424aa9015fSStephane Eranian output = NULL; 14434aa9015fSStephane Eranian 144456f3bae7SJim Cromie if (output_name && output_fd) { 144556f3bae7SJim Cromie fprintf(stderr, "cannot use both --output and --log-fd\n"); 144656f3bae7SJim Cromie usage_with_options(stat_usage, options); 144756f3bae7SJim Cromie } 1448fc3e4d07SStephane Eranian 1449fc3e4d07SStephane Eranian if (output_fd < 0) { 1450fc3e4d07SStephane Eranian fprintf(stderr, "argument to --log-fd must be a > 0\n"); 1451fc3e4d07SStephane Eranian usage_with_options(stat_usage, options); 1452fc3e4d07SStephane Eranian } 1453fc3e4d07SStephane Eranian 14544aa9015fSStephane Eranian if (!output) { 14554aa9015fSStephane Eranian struct timespec tm; 14564aa9015fSStephane Eranian mode = append_file ? "a" : "w"; 14574aa9015fSStephane Eranian 14584aa9015fSStephane Eranian output = fopen(output_name, mode); 14594aa9015fSStephane Eranian if (!output) { 14604aa9015fSStephane Eranian perror("failed to create output file"); 1461fceda7feSDavid Ahern return -1; 14624aa9015fSStephane Eranian } 14634aa9015fSStephane Eranian clock_gettime(CLOCK_REALTIME, &tm); 14644aa9015fSStephane Eranian fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 1465fc3e4d07SStephane Eranian } else if (output_fd > 0) { 146656f3bae7SJim Cromie mode = append_file ? "a" : "w"; 146756f3bae7SJim Cromie output = fdopen(output_fd, mode); 146856f3bae7SJim Cromie if (!output) { 146956f3bae7SJim Cromie perror("Failed opening logfd"); 147056f3bae7SJim Cromie return -errno; 147156f3bae7SJim Cromie } 14724aa9015fSStephane Eranian } 14734aa9015fSStephane Eranian 1474d4ffd04dSJim Cromie if (csv_sep) { 1475d7470b6aSStephane Eranian csv_output = true; 1476d4ffd04dSJim Cromie if (!strcmp(csv_sep, "\\t")) 1477d4ffd04dSJim Cromie csv_sep = "\t"; 1478d4ffd04dSJim Cromie } else 1479d7470b6aSStephane Eranian csv_sep = DEFAULT_SEPARATOR; 1480d7470b6aSStephane Eranian 1481d7470b6aSStephane Eranian /* 1482d7470b6aSStephane Eranian * let the spreadsheet do the pretty-printing 1483d7470b6aSStephane Eranian */ 1484d7470b6aSStephane Eranian if (csv_output) { 148561a9f324SJim Cromie /* User explicitly passed -B? */ 1486d7470b6aSStephane Eranian if (big_num_opt == 1) { 1487d7470b6aSStephane Eranian fprintf(stderr, "-B option not supported with -x\n"); 1488d7470b6aSStephane Eranian usage_with_options(stat_usage, options); 1489d7470b6aSStephane Eranian } else /* Nope, so disable big number formatting */ 1490d7470b6aSStephane Eranian big_num = false; 1491d7470b6aSStephane Eranian } else if (big_num_opt == 0) /* User passed --no-big-num */ 1492d7470b6aSStephane Eranian big_num = false; 1493d7470b6aSStephane Eranian 1494aa22dd49SNamhyung Kim if (!argc && !perf_target__has_task(&target)) 149586470930SIngo Molnar usage_with_options(stat_usage, options); 1496a7e191c3SFrederik Deweerdt if (run_count < 0) { 149742202dd5SIngo Molnar usage_with_options(stat_usage, options); 1498a7e191c3SFrederik Deweerdt } else if (run_count == 0) { 1499a7e191c3SFrederik Deweerdt forever = true; 1500a7e191c3SFrederik Deweerdt run_count = 1; 1501a7e191c3SFrederik Deweerdt } 150286470930SIngo Molnar 1503023695d9SStephane Eranian /* no_aggr, cgroup are for system-wide only */ 150486ee6e18SStephane Eranian if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) 150586ee6e18SStephane Eranian && !perf_target__has_cpu(&target)) { 1506023695d9SStephane Eranian fprintf(stderr, "both cgroup and no-aggregation " 1507023695d9SStephane Eranian "modes only available in system-wide mode\n"); 1508023695d9SStephane Eranian 1509f5b4a9c3SStephane Eranian usage_with_options(stat_usage, options); 151086ee6e18SStephane Eranian return -1; 1511d7e7a451SStephane Eranian } 1512d7e7a451SStephane Eranian 15132cba3ffbSIngo Molnar if (add_default_attributes()) 1514c6264defSIngo Molnar goto out; 151586470930SIngo Molnar 15164bd0f2d2SNamhyung Kim perf_target__validate(&target); 15175c98d466SArnaldo Carvalho de Melo 151877a6f014SNamhyung Kim if (perf_evlist__create_maps(evsel_list, &target) < 0) { 1519aa22dd49SNamhyung Kim if (perf_target__has_task(&target)) 15205c98d466SArnaldo Carvalho de Melo pr_err("Problems finding threads of monitor\n"); 1521aa22dd49SNamhyung Kim if (perf_target__has_cpu(&target)) 152260d567e2SArnaldo Carvalho de Melo perror("failed to parse CPUs map"); 152377a6f014SNamhyung Kim 1524c45c6ea2SStephane Eranian usage_with_options(stat_usage, options); 152560d567e2SArnaldo Carvalho de Melo return -1; 152660d567e2SArnaldo Carvalho de Melo } 152713370a9bSStephane Eranian if (interval && interval < 100) { 152813370a9bSStephane Eranian pr_err("print interval must be >= 100ms\n"); 152913370a9bSStephane Eranian usage_with_options(stat_usage, options); 153013370a9bSStephane Eranian return -1; 153113370a9bSStephane Eranian } 1532c45c6ea2SStephane Eranian 1533d134ffb9SArnaldo Carvalho de Melo if (perf_evlist__alloc_stats(evsel_list, interval)) 1534d134ffb9SArnaldo Carvalho de Melo goto out_free_maps; 1535d6d901c2SZhang, Yanmin 153686ee6e18SStephane Eranian if (perf_stat_init_aggr_mode()) 153786ee6e18SStephane Eranian goto out; 153886ee6e18SStephane Eranian 153986470930SIngo Molnar /* 154086470930SIngo Molnar * We dont want to block the signals - that would cause 154186470930SIngo Molnar * child tasks to inherit that and Ctrl-C would not work. 154286470930SIngo Molnar * What we want is for Ctrl-C to work in the exec()-ed 154386470930SIngo Molnar * task, but being ignored by perf stat itself: 154486470930SIngo Molnar */ 1545f7b7c26eSPeter Zijlstra atexit(sig_atexit); 1546a7e191c3SFrederik Deweerdt if (!forever) 154786470930SIngo Molnar signal(SIGINT, skip_signal); 154813370a9bSStephane Eranian signal(SIGCHLD, skip_signal); 154986470930SIngo Molnar signal(SIGALRM, skip_signal); 155086470930SIngo Molnar signal(SIGABRT, skip_signal); 155186470930SIngo Molnar 155242202dd5SIngo Molnar status = 0; 1553a7e191c3SFrederik Deweerdt for (run_idx = 0; forever || run_idx < run_count; run_idx++) { 155442202dd5SIngo Molnar if (run_count != 1 && verbose) 15554aa9015fSStephane Eranian fprintf(output, "[ perf stat: executing run #%d ... ]\n", 15564aa9015fSStephane Eranian run_idx + 1); 1557f9cef0a9SIngo Molnar 155842202dd5SIngo Molnar status = run_perf_stat(argc, argv); 1559a7e191c3SFrederik Deweerdt if (forever && status != -1) { 1560a7e191c3SFrederik Deweerdt print_stat(argc, argv); 1561d134ffb9SArnaldo Carvalho de Melo perf_stat__reset_stats(evsel_list); 1562a7e191c3SFrederik Deweerdt } 156342202dd5SIngo Molnar } 156442202dd5SIngo Molnar 1565a7e191c3SFrederik Deweerdt if (!forever && status != -1 && !interval) 156642202dd5SIngo Molnar print_stat(argc, argv); 1567d134ffb9SArnaldo Carvalho de Melo 1568d134ffb9SArnaldo Carvalho de Melo perf_evlist__free_stats(evsel_list); 1569d134ffb9SArnaldo Carvalho de Melo out_free_maps: 15707e2ed097SArnaldo Carvalho de Melo perf_evlist__delete_maps(evsel_list); 15710015e2e1SArnaldo Carvalho de Melo out: 15720015e2e1SArnaldo Carvalho de Melo perf_evlist__delete(evsel_list); 157342202dd5SIngo Molnar return status; 157486470930SIngo Molnar } 1575