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 68666e6d48SRobert Richter static struct perf_evlist *evsel_list; 69361c99a6SArnaldo Carvalho de Melo 7077a6f014SNamhyung Kim static struct perf_target target = { 7177a6f014SNamhyung Kim .uid = UINT_MAX, 7277a6f014SNamhyung Kim }; 7342202dd5SIngo Molnar 743d632595SJaswinder Singh Rajput static int run_count = 1; 752e6cdf99SStephane Eranian static bool no_inherit = false; 76c0555642SIan Munsie static bool scale = true; 77f5b4a9c3SStephane Eranian static bool no_aggr = false; 78933da83aSChris Wilson static pid_t child_pid = -1; 79c0555642SIan Munsie static bool null_run = false; 802cba3ffbSIngo Molnar static int detailed_run = 0; 81201e0b06SArnaldo Carvalho de Melo static bool big_num = true; 82d7470b6aSStephane Eranian static int big_num_opt = -1; 83d7470b6aSStephane Eranian static const char *csv_sep = NULL; 84d7470b6aSStephane Eranian static bool csv_output = false; 8543bece79SLin Ming static bool group = false; 864aa9015fSStephane Eranian static FILE *output = NULL; 871f16c575SPeter Zijlstra static const char *pre_cmd = NULL; 881f16c575SPeter Zijlstra static const char *post_cmd = NULL; 891f16c575SPeter Zijlstra static bool sync_run = false; 905af52b51SStephane Eranian 9160666c63SLiming Wang static volatile int done = 0; 9260666c63SLiming Wang 9369aad6f1SArnaldo Carvalho de Melo struct perf_stat { 9469aad6f1SArnaldo Carvalho de Melo struct stats res_stats[3]; 9569aad6f1SArnaldo Carvalho de Melo }; 9669aad6f1SArnaldo Carvalho de Melo 97c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) 9869aad6f1SArnaldo Carvalho de Melo { 99c52b12edSArnaldo Carvalho de Melo evsel->priv = zalloc(sizeof(struct perf_stat)); 10069aad6f1SArnaldo Carvalho de Melo return evsel->priv == NULL ? -ENOMEM : 0; 10169aad6f1SArnaldo Carvalho de Melo } 10269aad6f1SArnaldo Carvalho de Melo 10369aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) 10469aad6f1SArnaldo Carvalho de Melo { 10569aad6f1SArnaldo Carvalho de Melo free(evsel->priv); 10669aad6f1SArnaldo Carvalho de Melo evsel->priv = NULL; 10769aad6f1SArnaldo Carvalho de Melo } 10869aad6f1SArnaldo Carvalho de Melo 1097ae92e74SYan, Zheng static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) 1107ae92e74SYan, Zheng { 1117ae92e74SYan, Zheng return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus; 1127ae92e74SYan, Zheng } 1137ae92e74SYan, Zheng 1147ae92e74SYan, Zheng static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) 1157ae92e74SYan, Zheng { 1167ae92e74SYan, Zheng return perf_evsel__cpus(evsel)->nr; 1177ae92e74SYan, Zheng } 1187ae92e74SYan, Zheng 119666e6d48SRobert Richter static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 120666e6d48SRobert Richter static struct stats runtime_cycles_stats[MAX_NR_CPUS]; 121666e6d48SRobert Richter static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS]; 122666e6d48SRobert Richter static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS]; 123666e6d48SRobert Richter static struct stats runtime_branches_stats[MAX_NR_CPUS]; 124666e6d48SRobert Richter static struct stats runtime_cacherefs_stats[MAX_NR_CPUS]; 125666e6d48SRobert Richter static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS]; 126666e6d48SRobert Richter static struct stats runtime_l1_icache_stats[MAX_NR_CPUS]; 127666e6d48SRobert Richter static struct stats runtime_ll_cache_stats[MAX_NR_CPUS]; 128666e6d48SRobert Richter static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; 129666e6d48SRobert Richter static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; 130666e6d48SRobert Richter static struct stats walltime_nsecs_stats; 13186470930SIngo Molnar 132cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel) 13386470930SIngo Molnar { 13469aad6f1SArnaldo Carvalho de Melo struct perf_event_attr *attr = &evsel->attr; 1355622c07bSStephane Eranian bool exclude_guest_missing = false; 1365622c07bSStephane Eranian int ret; 137727ab04eSArnaldo Carvalho de Melo 13886470930SIngo Molnar if (scale) 13986470930SIngo Molnar attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 14086470930SIngo Molnar PERF_FORMAT_TOTAL_TIME_RUNNING; 14186470930SIngo Molnar 1422e6cdf99SStephane Eranian attr->inherit = !no_inherit; 1435d2cd909SArnaldo Carvalho de Melo 1445622c07bSStephane Eranian retry: 1455622c07bSStephane Eranian if (exclude_guest_missing) 1465622c07bSStephane Eranian evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; 1475622c07bSStephane Eranian 14816ee6576SArnaldo Carvalho de Melo if (perf_target__has_cpu(&target)) { 1497ae92e74SYan, Zheng ret = perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); 1505622c07bSStephane Eranian if (ret) 1515622c07bSStephane Eranian goto check_ret; 1525622c07bSStephane Eranian return 0; 1535622c07bSStephane Eranian } 1545622c07bSStephane Eranian 15507ac002fSArnaldo Carvalho de Melo if (!perf_target__has_task(&target) && 156823254edSNamhyung Kim perf_evsel__is_group_leader(evsel)) { 15786470930SIngo Molnar attr->disabled = 1; 15857e7986eSPaul Mackerras attr->enable_on_exec = 1; 1596be2850eSZhang, Yanmin } 160084ab9f8SArnaldo Carvalho de Melo 1616a4bb04cSJiri Olsa ret = perf_evsel__open_per_thread(evsel, evsel_list->threads); 1625622c07bSStephane Eranian if (!ret) 1635622c07bSStephane Eranian return 0; 1645622c07bSStephane Eranian /* fall through */ 1655622c07bSStephane Eranian check_ret: 1665622c07bSStephane Eranian if (ret && errno == EINVAL) { 1675622c07bSStephane Eranian if (!exclude_guest_missing && 1685622c07bSStephane Eranian (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { 1695622c07bSStephane Eranian pr_debug("Old kernel, cannot exclude " 1705622c07bSStephane Eranian "guest or host samples.\n"); 1715622c07bSStephane Eranian exclude_guest_missing = true; 1725622c07bSStephane Eranian goto retry; 1735622c07bSStephane Eranian } 1745622c07bSStephane Eranian } 1755622c07bSStephane Eranian return ret; 17686470930SIngo Molnar } 17786470930SIngo Molnar 17886470930SIngo Molnar /* 17986470930SIngo Molnar * Does the counter have nsecs as a unit? 18086470930SIngo Molnar */ 181daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel) 18286470930SIngo Molnar { 183daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || 184daec78a0SArnaldo Carvalho de Melo perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 18586470930SIngo Molnar return 1; 18686470930SIngo Molnar 18786470930SIngo Molnar return 0; 18886470930SIngo Molnar } 18986470930SIngo Molnar 19086470930SIngo Molnar /* 191dcd9936aSIngo Molnar * Update various tracking values we maintain to print 192dcd9936aSIngo Molnar * more semantic information such as miss/hit ratios, 193dcd9936aSIngo Molnar * instruction rates, etc: 194dcd9936aSIngo Molnar */ 195dcd9936aSIngo Molnar static void update_shadow_stats(struct perf_evsel *counter, u64 *count) 196dcd9936aSIngo Molnar { 197dcd9936aSIngo Molnar if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 198dcd9936aSIngo Molnar update_stats(&runtime_nsecs_stats[0], count[0]); 199dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 200dcd9936aSIngo Molnar update_stats(&runtime_cycles_stats[0], count[0]); 201d3d1e86dSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) 202d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_front_stats[0], count[0]); 203129c04cbSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) 204d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_back_stats[0], count[0]); 205dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS)) 206dcd9936aSIngo Molnar update_stats(&runtime_branches_stats[0], count[0]); 207dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES)) 208dcd9936aSIngo Molnar update_stats(&runtime_cacherefs_stats[0], count[0]); 2098bb6c79fSIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D)) 2108bb6c79fSIngo Molnar update_stats(&runtime_l1_dcache_stats[0], count[0]); 211c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I)) 212c3305257SIngo Molnar update_stats(&runtime_l1_icache_stats[0], count[0]); 213c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL)) 214c3305257SIngo Molnar update_stats(&runtime_ll_cache_stats[0], count[0]); 215c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB)) 216c3305257SIngo Molnar update_stats(&runtime_dtlb_cache_stats[0], count[0]); 217c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) 218c3305257SIngo Molnar update_stats(&runtime_itlb_cache_stats[0], count[0]); 219dcd9936aSIngo Molnar } 220dcd9936aSIngo Molnar 221dcd9936aSIngo Molnar /* 22286470930SIngo Molnar * Read out the results of a single counter: 223f5b4a9c3SStephane Eranian * aggregate counts across CPUs in system-wide mode 22486470930SIngo Molnar */ 225c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter) 22686470930SIngo Molnar { 22769aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 228c52b12edSArnaldo Carvalho de Melo u64 *count = counter->counts->aggr.values; 229c52b12edSArnaldo Carvalho de Melo int i; 23086470930SIngo Molnar 2317ae92e74SYan, Zheng if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter), 2327e2ed097SArnaldo Carvalho de Melo evsel_list->threads->nr, scale) < 0) 233c52b12edSArnaldo Carvalho de Melo return -1; 2349e9772c4SPeter Zijlstra 2359e9772c4SPeter Zijlstra for (i = 0; i < 3; i++) 23669aad6f1SArnaldo Carvalho de Melo update_stats(&ps->res_stats[i], count[i]); 2379e9772c4SPeter Zijlstra 2389e9772c4SPeter Zijlstra if (verbose) { 2394aa9015fSStephane Eranian fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 2407289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter), count[0], count[1], count[2]); 2419e9772c4SPeter Zijlstra } 2429e9772c4SPeter Zijlstra 24386470930SIngo Molnar /* 24486470930SIngo Molnar * Save the full runtime - to allow normalization during printout: 24586470930SIngo Molnar */ 246dcd9936aSIngo Molnar update_shadow_stats(counter, count); 247c52b12edSArnaldo Carvalho de Melo 248c52b12edSArnaldo Carvalho de Melo return 0; 249f5b4a9c3SStephane Eranian } 250f5b4a9c3SStephane Eranian 251f5b4a9c3SStephane Eranian /* 252f5b4a9c3SStephane Eranian * Read out the results of a single counter: 253f5b4a9c3SStephane Eranian * do not aggregate counts across CPUs in system-wide mode 254f5b4a9c3SStephane Eranian */ 255c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter) 256f5b4a9c3SStephane Eranian { 257c52b12edSArnaldo Carvalho de Melo u64 *count; 258f5b4a9c3SStephane Eranian int cpu; 259f5b4a9c3SStephane Eranian 2607ae92e74SYan, Zheng for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 261c52b12edSArnaldo Carvalho de Melo if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) 262c52b12edSArnaldo Carvalho de Melo return -1; 263f5b4a9c3SStephane Eranian 264c52b12edSArnaldo Carvalho de Melo count = counter->counts->cpu[cpu].values; 265f5b4a9c3SStephane Eranian 266dcd9936aSIngo Molnar update_shadow_stats(counter, count); 267f5b4a9c3SStephane Eranian } 268c52b12edSArnaldo Carvalho de Melo 269c52b12edSArnaldo Carvalho de Melo return 0; 27086470930SIngo Molnar } 27186470930SIngo Molnar 2721f16c575SPeter Zijlstra static int __run_perf_stat(int argc __maybe_unused, const char **argv) 27386470930SIngo Molnar { 27486470930SIngo Molnar unsigned long long t0, t1; 275cac21425SJiri Olsa struct perf_evsel *counter; 27642202dd5SIngo Molnar int status = 0; 277051ae7f7SPaul Mackerras int child_ready_pipe[2], go_pipe[2]; 2786be2850eSZhang, Yanmin const bool forks = (argc > 0); 279051ae7f7SPaul Mackerras char buf; 28086470930SIngo Molnar 28160666c63SLiming Wang if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { 282051ae7f7SPaul Mackerras perror("failed to create pipes"); 283fceda7feSDavid Ahern return -1; 284051ae7f7SPaul Mackerras } 285051ae7f7SPaul Mackerras 28660666c63SLiming Wang if (forks) { 2876be2850eSZhang, Yanmin if ((child_pid = fork()) < 0) 288051ae7f7SPaul Mackerras perror("failed to fork"); 289051ae7f7SPaul Mackerras 2906be2850eSZhang, Yanmin if (!child_pid) { 291051ae7f7SPaul Mackerras close(child_ready_pipe[0]); 292051ae7f7SPaul Mackerras close(go_pipe[1]); 293051ae7f7SPaul Mackerras fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 294051ae7f7SPaul Mackerras 295051ae7f7SPaul Mackerras /* 296051ae7f7SPaul Mackerras * Do a dummy execvp to get the PLT entry resolved, 297051ae7f7SPaul Mackerras * so we avoid the resolver overhead on the real 298051ae7f7SPaul Mackerras * execvp call. 299051ae7f7SPaul Mackerras */ 300051ae7f7SPaul Mackerras execvp("", (char **)argv); 301051ae7f7SPaul Mackerras 302051ae7f7SPaul Mackerras /* 303051ae7f7SPaul Mackerras * Tell the parent we're ready to go 304051ae7f7SPaul Mackerras */ 305051ae7f7SPaul Mackerras close(child_ready_pipe[1]); 306051ae7f7SPaul Mackerras 307051ae7f7SPaul Mackerras /* 308051ae7f7SPaul Mackerras * Wait until the parent tells us to go. 309051ae7f7SPaul Mackerras */ 310a92bef0fSFrederic Weisbecker if (read(go_pipe[0], &buf, 1) == -1) 311a92bef0fSFrederic Weisbecker perror("unable to read pipe"); 312051ae7f7SPaul Mackerras 313051ae7f7SPaul Mackerras execvp(argv[0], (char **)argv); 314051ae7f7SPaul Mackerras 315051ae7f7SPaul Mackerras perror(argv[0]); 316051ae7f7SPaul Mackerras exit(-1); 317051ae7f7SPaul Mackerras } 318051ae7f7SPaul Mackerras 319d67356e7SNamhyung Kim if (perf_target__none(&target)) 3207e2ed097SArnaldo Carvalho de Melo evsel_list->threads->map[0] = child_pid; 321d6d901c2SZhang, Yanmin 322051ae7f7SPaul Mackerras /* 323051ae7f7SPaul Mackerras * Wait for the child to be ready to exec. 324051ae7f7SPaul Mackerras */ 325051ae7f7SPaul Mackerras close(child_ready_pipe[1]); 326051ae7f7SPaul Mackerras close(go_pipe[0]); 327a92bef0fSFrederic Weisbecker if (read(child_ready_pipe[0], &buf, 1) == -1) 328a92bef0fSFrederic Weisbecker perror("unable to read pipe"); 329051ae7f7SPaul Mackerras close(child_ready_pipe[0]); 33060666c63SLiming Wang } 331051ae7f7SPaul Mackerras 3326a4bb04cSJiri Olsa if (group) 33363dab225SArnaldo Carvalho de Melo perf_evlist__set_leader(evsel_list); 3346a4bb04cSJiri Olsa 335361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 336cac21425SJiri Olsa if (create_perf_stat_counter(counter) < 0) { 337979987a5SDavid Ahern /* 338979987a5SDavid Ahern * PPC returns ENXIO for HW counters until 2.6.37 339979987a5SDavid Ahern * (behavior changed with commit b0a873e). 340979987a5SDavid Ahern */ 34138f6ae1eSAnton Blanchard if (errno == EINVAL || errno == ENOSYS || 342979987a5SDavid Ahern errno == ENOENT || errno == EOPNOTSUPP || 343979987a5SDavid Ahern errno == ENXIO) { 344c63ca0c0SDavid Ahern if (verbose) 345c63ca0c0SDavid Ahern ui__warning("%s event is not supported by the kernel.\n", 3467289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 3472cee77c4SDavid Ahern counter->supported = false; 348ede70290SIngo Molnar continue; 349c63ca0c0SDavid Ahern } 350ede70290SIngo Molnar 351ede70290SIngo Molnar if (errno == EPERM || errno == EACCES) { 352d9cf837eSCorey Ashford error("You may not have permission to collect %sstats.\n" 353d9cf837eSCorey Ashford "\t Consider tweaking" 354d9cf837eSCorey Ashford " /proc/sys/kernel/perf_event_paranoid or running as root.", 35520f946b4SNamhyung Kim target.system_wide ? "system-wide " : ""); 35648290609SArnaldo Carvalho de Melo } else { 35748290609SArnaldo Carvalho de Melo error("open_counter returned with %d (%s). " 35848290609SArnaldo Carvalho de Melo "/bin/dmesg may provide additional information.\n", 35948290609SArnaldo Carvalho de Melo errno, strerror(errno)); 36048290609SArnaldo Carvalho de Melo } 361084ab9f8SArnaldo Carvalho de Melo if (child_pid != -1) 362084ab9f8SArnaldo Carvalho de Melo kill(child_pid, SIGTERM); 363fceda7feSDavid Ahern 364fceda7feSDavid Ahern pr_err("Not all events could be opened.\n"); 365084ab9f8SArnaldo Carvalho de Melo return -1; 366084ab9f8SArnaldo Carvalho de Melo } 3672cee77c4SDavid Ahern counter->supported = true; 36848290609SArnaldo Carvalho de Melo } 36986470930SIngo Molnar 3701491a632SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evsel_list)) { 371cfd748aeSFrederic Weisbecker error("failed to set filter with %d (%s)\n", errno, 372cfd748aeSFrederic Weisbecker strerror(errno)); 373cfd748aeSFrederic Weisbecker return -1; 374cfd748aeSFrederic Weisbecker } 375cfd748aeSFrederic Weisbecker 37686470930SIngo Molnar /* 37786470930SIngo Molnar * Enable counters and exec the command: 37886470930SIngo Molnar */ 37986470930SIngo Molnar t0 = rdclock(); 38086470930SIngo Molnar 38160666c63SLiming Wang if (forks) { 382051ae7f7SPaul Mackerras close(go_pipe[1]); 38342202dd5SIngo Molnar wait(&status); 38433e49ea7SAndi Kleen if (WIFSIGNALED(status)) 38533e49ea7SAndi Kleen psignal(WTERMSIG(status), argv[0]); 38660666c63SLiming Wang } else { 3876be2850eSZhang, Yanmin while(!done) sleep(1); 38860666c63SLiming Wang } 38986470930SIngo Molnar 39086470930SIngo Molnar t1 = rdclock(); 39186470930SIngo Molnar 3929e9772c4SPeter Zijlstra update_stats(&walltime_nsecs_stats, t1 - t0); 39342202dd5SIngo Molnar 394f5b4a9c3SStephane Eranian if (no_aggr) { 395361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 39642202dd5SIngo Molnar read_counter(counter); 3977ae92e74SYan, Zheng perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1); 398f5b4a9c3SStephane Eranian } 399c52b12edSArnaldo Carvalho de Melo } else { 400361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 401c52b12edSArnaldo Carvalho de Melo read_counter_aggr(counter); 4027ae92e74SYan, Zheng perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 4037e2ed097SArnaldo Carvalho de Melo evsel_list->threads->nr); 404c52b12edSArnaldo Carvalho de Melo } 405c52b12edSArnaldo Carvalho de Melo } 406c52b12edSArnaldo Carvalho de Melo 40742202dd5SIngo Molnar return WEXITSTATUS(status); 40842202dd5SIngo Molnar } 40942202dd5SIngo Molnar 4101f16c575SPeter Zijlstra static int run_perf_stat(int argc __maybe_unused, const char **argv) 4111f16c575SPeter Zijlstra { 4121f16c575SPeter Zijlstra int ret; 4131f16c575SPeter Zijlstra 4141f16c575SPeter Zijlstra if (pre_cmd) { 4151f16c575SPeter Zijlstra ret = system(pre_cmd); 4161f16c575SPeter Zijlstra if (ret) 4171f16c575SPeter Zijlstra return ret; 4181f16c575SPeter Zijlstra } 4191f16c575SPeter Zijlstra 4201f16c575SPeter Zijlstra if (sync_run) 4211f16c575SPeter Zijlstra sync(); 4221f16c575SPeter Zijlstra 4231f16c575SPeter Zijlstra ret = __run_perf_stat(argc, argv); 4241f16c575SPeter Zijlstra if (ret) 4251f16c575SPeter Zijlstra return ret; 4261f16c575SPeter Zijlstra 4271f16c575SPeter Zijlstra if (post_cmd) { 4281f16c575SPeter Zijlstra ret = system(post_cmd); 4291f16c575SPeter Zijlstra if (ret) 4301f16c575SPeter Zijlstra return ret; 4311f16c575SPeter Zijlstra } 4321f16c575SPeter Zijlstra 4331f16c575SPeter Zijlstra return ret; 4341f16c575SPeter Zijlstra } 4351f16c575SPeter Zijlstra 436f99844cbSIngo Molnar static void print_noise_pct(double total, double avg) 437f99844cbSIngo Molnar { 4380007eceaSXiao Guangrong double pct = rel_stddev_stats(total, avg); 439f99844cbSIngo Molnar 4403ae9a34dSZhengyu He if (csv_output) 4414aa9015fSStephane Eranian fprintf(output, "%s%.2f%%", csv_sep, pct); 442a1bca6ccSJim Cromie else if (pct) 4434aa9015fSStephane Eranian fprintf(output, " ( +-%6.2f%% )", pct); 444f99844cbSIngo Molnar } 445f99844cbSIngo Molnar 44669aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg) 44742202dd5SIngo Molnar { 44869aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps; 44969aad6f1SArnaldo Carvalho de Melo 450849abde9SPeter Zijlstra if (run_count == 1) 451849abde9SPeter Zijlstra return; 452849abde9SPeter Zijlstra 45369aad6f1SArnaldo Carvalho de Melo ps = evsel->priv; 454f99844cbSIngo Molnar print_noise_pct(stddev_stats(&ps->res_stats[0]), avg); 45542202dd5SIngo Molnar } 45642202dd5SIngo Molnar 457daec78a0SArnaldo Carvalho de Melo static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) 45842202dd5SIngo Molnar { 459506d4bc8SPeter Zijlstra double msecs = avg / 1e6; 460d7470b6aSStephane Eranian char cpustr[16] = { '\0', }; 4612cba3ffbSIngo Molnar const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-25s"; 46242202dd5SIngo Molnar 463f5b4a9c3SStephane Eranian if (no_aggr) 464d7470b6aSStephane Eranian sprintf(cpustr, "CPU%*d%s", 465d7470b6aSStephane Eranian csv_output ? 0 : -4, 4667ae92e74SYan, Zheng perf_evsel__cpus(evsel)->map[cpu], csv_sep); 467d7470b6aSStephane Eranian 4687289f83cSArnaldo Carvalho de Melo fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel)); 469d7470b6aSStephane Eranian 470023695d9SStephane Eranian if (evsel->cgrp) 4714aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 472023695d9SStephane Eranian 473d7470b6aSStephane Eranian if (csv_output) 474d7470b6aSStephane Eranian return; 47542202dd5SIngo Molnar 476daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 4774aa9015fSStephane Eranian fprintf(output, " # %8.3f CPUs utilized ", 4784aa9015fSStephane Eranian avg / avg_stats(&walltime_nsecs_stats)); 4799dac6a29SNamhyung Kim else 4809dac6a29SNamhyung Kim fprintf(output, " "); 48142202dd5SIngo Molnar } 48242202dd5SIngo Molnar 48315e6392fSNamhyung Kim /* used for get_ratio_color() */ 48415e6392fSNamhyung Kim enum grc_type { 48515e6392fSNamhyung Kim GRC_STALLED_CYCLES_FE, 48615e6392fSNamhyung Kim GRC_STALLED_CYCLES_BE, 48715e6392fSNamhyung Kim GRC_CACHE_MISSES, 48815e6392fSNamhyung Kim GRC_MAX_NR 48915e6392fSNamhyung Kim }; 49015e6392fSNamhyung Kim 49115e6392fSNamhyung Kim static const char *get_ratio_color(enum grc_type type, double ratio) 49215e6392fSNamhyung Kim { 49315e6392fSNamhyung Kim static const double grc_table[GRC_MAX_NR][3] = { 49415e6392fSNamhyung Kim [GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 }, 49515e6392fSNamhyung Kim [GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 }, 49615e6392fSNamhyung Kim [GRC_CACHE_MISSES] = { 20.0, 10.0, 5.0 }, 49715e6392fSNamhyung Kim }; 49815e6392fSNamhyung Kim const char *color = PERF_COLOR_NORMAL; 49915e6392fSNamhyung Kim 50015e6392fSNamhyung Kim if (ratio > grc_table[type][0]) 50115e6392fSNamhyung Kim color = PERF_COLOR_RED; 50215e6392fSNamhyung Kim else if (ratio > grc_table[type][1]) 50315e6392fSNamhyung Kim color = PERF_COLOR_MAGENTA; 50415e6392fSNamhyung Kim else if (ratio > grc_table[type][2]) 50515e6392fSNamhyung Kim color = PERF_COLOR_YELLOW; 50615e6392fSNamhyung Kim 50715e6392fSNamhyung Kim return color; 50815e6392fSNamhyung Kim } 50915e6392fSNamhyung Kim 5101d037ca1SIrina Tirdea static void print_stalled_cycles_frontend(int cpu, 5111d037ca1SIrina Tirdea struct perf_evsel *evsel 5121d037ca1SIrina Tirdea __maybe_unused, double avg) 513d3d1e86dSIngo Molnar { 514d3d1e86dSIngo Molnar double total, ratio = 0.0; 515d3d1e86dSIngo Molnar const char *color; 516d3d1e86dSIngo Molnar 517d3d1e86dSIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 518d3d1e86dSIngo Molnar 519d3d1e86dSIngo Molnar if (total) 520d3d1e86dSIngo Molnar ratio = avg / total * 100.0; 521d3d1e86dSIngo Molnar 52215e6392fSNamhyung Kim color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio); 523d3d1e86dSIngo Molnar 5244aa9015fSStephane Eranian fprintf(output, " # "); 5254aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 5264aa9015fSStephane Eranian fprintf(output, " frontend cycles idle "); 527d3d1e86dSIngo Molnar } 528d3d1e86dSIngo Molnar 5291d037ca1SIrina Tirdea static void print_stalled_cycles_backend(int cpu, 5301d037ca1SIrina Tirdea struct perf_evsel *evsel 5311d037ca1SIrina Tirdea __maybe_unused, double avg) 532a5d243d0SIngo Molnar { 533a5d243d0SIngo Molnar double total, ratio = 0.0; 534a5d243d0SIngo Molnar const char *color; 535a5d243d0SIngo Molnar 536a5d243d0SIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 537a5d243d0SIngo Molnar 538a5d243d0SIngo Molnar if (total) 539a5d243d0SIngo Molnar ratio = avg / total * 100.0; 540a5d243d0SIngo Molnar 54115e6392fSNamhyung Kim color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio); 542a5d243d0SIngo Molnar 5434aa9015fSStephane Eranian fprintf(output, " # "); 5444aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 5454aa9015fSStephane Eranian fprintf(output, " backend cycles idle "); 546a5d243d0SIngo Molnar } 547a5d243d0SIngo Molnar 5481d037ca1SIrina Tirdea static void print_branch_misses(int cpu, 5491d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 5501d037ca1SIrina Tirdea double avg) 551c78df6c1SIngo Molnar { 552c78df6c1SIngo Molnar double total, ratio = 0.0; 553c78df6c1SIngo Molnar const char *color; 554c78df6c1SIngo Molnar 555c78df6c1SIngo Molnar total = avg_stats(&runtime_branches_stats[cpu]); 556c78df6c1SIngo Molnar 557c78df6c1SIngo Molnar if (total) 558c78df6c1SIngo Molnar ratio = avg / total * 100.0; 559c78df6c1SIngo Molnar 56015e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 561c78df6c1SIngo Molnar 5624aa9015fSStephane Eranian fprintf(output, " # "); 5634aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 5644aa9015fSStephane Eranian fprintf(output, " of all branches "); 565c78df6c1SIngo Molnar } 566c78df6c1SIngo Molnar 5671d037ca1SIrina Tirdea static void print_l1_dcache_misses(int cpu, 5681d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 5691d037ca1SIrina Tirdea double avg) 5708bb6c79fSIngo Molnar { 5718bb6c79fSIngo Molnar double total, ratio = 0.0; 5728bb6c79fSIngo Molnar const char *color; 5738bb6c79fSIngo Molnar 5748bb6c79fSIngo Molnar total = avg_stats(&runtime_l1_dcache_stats[cpu]); 5758bb6c79fSIngo Molnar 5768bb6c79fSIngo Molnar if (total) 5778bb6c79fSIngo Molnar ratio = avg / total * 100.0; 5788bb6c79fSIngo Molnar 57915e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 5808bb6c79fSIngo Molnar 5814aa9015fSStephane Eranian fprintf(output, " # "); 5824aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 5834aa9015fSStephane Eranian fprintf(output, " of all L1-dcache hits "); 5848bb6c79fSIngo Molnar } 5858bb6c79fSIngo Molnar 5861d037ca1SIrina Tirdea static void print_l1_icache_misses(int cpu, 5871d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 5881d037ca1SIrina Tirdea double avg) 589c3305257SIngo Molnar { 590c3305257SIngo Molnar double total, ratio = 0.0; 591c3305257SIngo Molnar const char *color; 592c3305257SIngo Molnar 593c3305257SIngo Molnar total = avg_stats(&runtime_l1_icache_stats[cpu]); 594c3305257SIngo Molnar 595c3305257SIngo Molnar if (total) 596c3305257SIngo Molnar ratio = avg / total * 100.0; 597c3305257SIngo Molnar 59815e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 599c3305257SIngo Molnar 6004aa9015fSStephane Eranian fprintf(output, " # "); 6014aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6024aa9015fSStephane Eranian fprintf(output, " of all L1-icache hits "); 603c3305257SIngo Molnar } 604c3305257SIngo Molnar 6051d037ca1SIrina Tirdea static void print_dtlb_cache_misses(int cpu, 6061d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 6071d037ca1SIrina Tirdea double avg) 608c3305257SIngo Molnar { 609c3305257SIngo Molnar double total, ratio = 0.0; 610c3305257SIngo Molnar const char *color; 611c3305257SIngo Molnar 612c3305257SIngo Molnar total = avg_stats(&runtime_dtlb_cache_stats[cpu]); 613c3305257SIngo Molnar 614c3305257SIngo Molnar if (total) 615c3305257SIngo Molnar ratio = avg / total * 100.0; 616c3305257SIngo Molnar 61715e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 618c3305257SIngo Molnar 6194aa9015fSStephane Eranian fprintf(output, " # "); 6204aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6214aa9015fSStephane Eranian fprintf(output, " of all dTLB cache hits "); 622c3305257SIngo Molnar } 623c3305257SIngo Molnar 6241d037ca1SIrina Tirdea static void print_itlb_cache_misses(int cpu, 6251d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 6261d037ca1SIrina Tirdea double avg) 627c3305257SIngo Molnar { 628c3305257SIngo Molnar double total, ratio = 0.0; 629c3305257SIngo Molnar const char *color; 630c3305257SIngo Molnar 631c3305257SIngo Molnar total = avg_stats(&runtime_itlb_cache_stats[cpu]); 632c3305257SIngo Molnar 633c3305257SIngo Molnar if (total) 634c3305257SIngo Molnar ratio = avg / total * 100.0; 635c3305257SIngo Molnar 63615e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 637c3305257SIngo Molnar 6384aa9015fSStephane Eranian fprintf(output, " # "); 6394aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6404aa9015fSStephane Eranian fprintf(output, " of all iTLB cache hits "); 641c3305257SIngo Molnar } 642c3305257SIngo Molnar 6431d037ca1SIrina Tirdea static void print_ll_cache_misses(int cpu, 6441d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 6451d037ca1SIrina Tirdea double avg) 646c3305257SIngo Molnar { 647c3305257SIngo Molnar double total, ratio = 0.0; 648c3305257SIngo Molnar const char *color; 649c3305257SIngo Molnar 650c3305257SIngo Molnar total = avg_stats(&runtime_ll_cache_stats[cpu]); 651c3305257SIngo Molnar 652c3305257SIngo Molnar if (total) 653c3305257SIngo Molnar ratio = avg / total * 100.0; 654c3305257SIngo Molnar 65515e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 656c3305257SIngo Molnar 6574aa9015fSStephane Eranian fprintf(output, " # "); 6584aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6594aa9015fSStephane Eranian fprintf(output, " of all LL-cache hits "); 660c3305257SIngo Molnar } 661c3305257SIngo Molnar 662daec78a0SArnaldo Carvalho de Melo static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) 66342202dd5SIngo Molnar { 664c7f7fea3SIngo Molnar double total, ratio = 0.0; 665f5b4a9c3SStephane Eranian char cpustr[16] = { '\0', }; 666d7470b6aSStephane Eranian const char *fmt; 667d7470b6aSStephane Eranian 668d7470b6aSStephane Eranian if (csv_output) 669d7470b6aSStephane Eranian fmt = "%s%.0f%s%s"; 670d7470b6aSStephane Eranian else if (big_num) 6712cba3ffbSIngo Molnar fmt = "%s%'18.0f%s%-25s"; 672d7470b6aSStephane Eranian else 6732cba3ffbSIngo Molnar fmt = "%s%18.0f%s%-25s"; 674f5b4a9c3SStephane Eranian 675f5b4a9c3SStephane Eranian if (no_aggr) 676d7470b6aSStephane Eranian sprintf(cpustr, "CPU%*d%s", 677d7470b6aSStephane Eranian csv_output ? 0 : -4, 6787ae92e74SYan, Zheng perf_evsel__cpus(evsel)->map[cpu], csv_sep); 679f5b4a9c3SStephane Eranian else 680f5b4a9c3SStephane Eranian cpu = 0; 681c7f7fea3SIngo Molnar 6827289f83cSArnaldo Carvalho de Melo fprintf(output, fmt, cpustr, avg, csv_sep, perf_evsel__name(evsel)); 683d7470b6aSStephane Eranian 684023695d9SStephane Eranian if (evsel->cgrp) 6854aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 686023695d9SStephane Eranian 687d7470b6aSStephane Eranian if (csv_output) 688d7470b6aSStephane Eranian return; 68942202dd5SIngo Molnar 690daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 691f5b4a9c3SStephane Eranian total = avg_stats(&runtime_cycles_stats[cpu]); 692c7f7fea3SIngo Molnar 693c7f7fea3SIngo Molnar if (total) 694c7f7fea3SIngo Molnar ratio = avg / total; 695c7f7fea3SIngo Molnar 6964aa9015fSStephane Eranian fprintf(output, " # %5.2f insns per cycle ", ratio); 697481f988aSIngo Molnar 698d3d1e86dSIngo Molnar total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]); 699d3d1e86dSIngo Molnar total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu])); 700481f988aSIngo Molnar 701481f988aSIngo Molnar if (total && avg) { 702481f988aSIngo Molnar ratio = total / avg; 7034aa9015fSStephane Eranian fprintf(output, "\n # %5.2f stalled cycles per insn", ratio); 704481f988aSIngo Molnar } 705481f988aSIngo Molnar 706daec78a0SArnaldo Carvalho de Melo } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 707f5b4a9c3SStephane Eranian runtime_branches_stats[cpu].n != 0) { 708c78df6c1SIngo Molnar print_branch_misses(cpu, evsel, avg); 7098bb6c79fSIngo Molnar } else if ( 7108bb6c79fSIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 7118bb6c79fSIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D | 7128bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 7138bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 714c6264defSIngo Molnar runtime_l1_dcache_stats[cpu].n != 0) { 7158bb6c79fSIngo Molnar print_l1_dcache_misses(cpu, evsel, avg); 716c3305257SIngo Molnar } else if ( 717c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 718c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I | 719c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 720c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 721c3305257SIngo Molnar runtime_l1_icache_stats[cpu].n != 0) { 722c3305257SIngo Molnar print_l1_icache_misses(cpu, evsel, avg); 723c3305257SIngo Molnar } else if ( 724c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 725c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB | 726c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 727c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 728c3305257SIngo Molnar runtime_dtlb_cache_stats[cpu].n != 0) { 729c3305257SIngo Molnar print_dtlb_cache_misses(cpu, evsel, avg); 730c3305257SIngo Molnar } else if ( 731c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 732c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB | 733c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 734c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 735c3305257SIngo Molnar runtime_itlb_cache_stats[cpu].n != 0) { 736c3305257SIngo Molnar print_itlb_cache_misses(cpu, evsel, avg); 737c3305257SIngo Molnar } else if ( 738c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 739c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL | 740c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 741c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 742c3305257SIngo Molnar runtime_ll_cache_stats[cpu].n != 0) { 743c3305257SIngo Molnar print_ll_cache_misses(cpu, evsel, avg); 744d58f4c82SIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) && 745d58f4c82SIngo Molnar runtime_cacherefs_stats[cpu].n != 0) { 746d58f4c82SIngo Molnar total = avg_stats(&runtime_cacherefs_stats[cpu]); 747d58f4c82SIngo Molnar 748d58f4c82SIngo Molnar if (total) 749d58f4c82SIngo Molnar ratio = avg * 100 / total; 750d58f4c82SIngo Molnar 7514aa9015fSStephane Eranian fprintf(output, " # %8.3f %% of all cache refs ", ratio); 752d58f4c82SIngo Molnar 753d3d1e86dSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 754d3d1e86dSIngo Molnar print_stalled_cycles_frontend(cpu, evsel, avg); 755129c04cbSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) { 756d3d1e86dSIngo Molnar print_stalled_cycles_backend(cpu, evsel, avg); 757481f988aSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) { 758481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 759481f988aSIngo Molnar 760481f988aSIngo Molnar if (total) 761481f988aSIngo Molnar ratio = 1.0 * avg / total; 762481f988aSIngo Molnar 7634aa9015fSStephane Eranian fprintf(output, " # %8.3f GHz ", ratio); 764481f988aSIngo Molnar } else if (runtime_nsecs_stats[cpu].n != 0) { 7655fde2523SNamhyung Kim char unit = 'M'; 7665fde2523SNamhyung Kim 767481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 768481f988aSIngo Molnar 769481f988aSIngo Molnar if (total) 770481f988aSIngo Molnar ratio = 1000.0 * avg / total; 7715fde2523SNamhyung Kim if (ratio < 0.001) { 7725fde2523SNamhyung Kim ratio *= 1000; 7735fde2523SNamhyung Kim unit = 'K'; 7745fde2523SNamhyung Kim } 775481f988aSIngo Molnar 7765fde2523SNamhyung Kim fprintf(output, " # %8.3f %c/sec ", ratio, unit); 777a5d243d0SIngo Molnar } else { 7784aa9015fSStephane Eranian fprintf(output, " "); 77942202dd5SIngo Molnar } 78042202dd5SIngo Molnar } 78142202dd5SIngo Molnar 78242202dd5SIngo Molnar /* 78342202dd5SIngo Molnar * Print out the results of a single counter: 784f5b4a9c3SStephane Eranian * aggregated counts in system-wide mode 78542202dd5SIngo Molnar */ 78669aad6f1SArnaldo Carvalho de Melo static void print_counter_aggr(struct perf_evsel *counter) 78742202dd5SIngo Molnar { 78869aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 78969aad6f1SArnaldo Carvalho de Melo double avg = avg_stats(&ps->res_stats[0]); 790c52b12edSArnaldo Carvalho de Melo int scaled = counter->counts->scaled; 79142202dd5SIngo Molnar 79242202dd5SIngo Molnar if (scaled == -1) { 7934aa9015fSStephane Eranian fprintf(output, "%*s%s%*s", 794d7470b6aSStephane Eranian csv_output ? 0 : 18, 7952cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 796023695d9SStephane Eranian csv_sep, 797023695d9SStephane Eranian csv_output ? 0 : -24, 7987289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 799023695d9SStephane Eranian 800023695d9SStephane Eranian if (counter->cgrp) 8014aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, counter->cgrp->name); 802023695d9SStephane Eranian 8034aa9015fSStephane Eranian fputc('\n', output); 80442202dd5SIngo Molnar return; 80542202dd5SIngo Molnar } 80642202dd5SIngo Molnar 80742202dd5SIngo Molnar if (nsec_counter(counter)) 808f5b4a9c3SStephane Eranian nsec_printout(-1, counter, avg); 80942202dd5SIngo Molnar else 810f5b4a9c3SStephane Eranian abs_printout(-1, counter, avg); 811849abde9SPeter Zijlstra 8123ae9a34dSZhengyu He print_noise(counter, avg); 8133ae9a34dSZhengyu He 814d7470b6aSStephane Eranian if (csv_output) { 8154aa9015fSStephane Eranian fputc('\n', output); 816d7470b6aSStephane Eranian return; 817d7470b6aSStephane Eranian } 818d7470b6aSStephane Eranian 819506d4bc8SPeter Zijlstra if (scaled) { 820506d4bc8SPeter Zijlstra double avg_enabled, avg_running; 821506d4bc8SPeter Zijlstra 82269aad6f1SArnaldo Carvalho de Melo avg_enabled = avg_stats(&ps->res_stats[1]); 82369aad6f1SArnaldo Carvalho de Melo avg_running = avg_stats(&ps->res_stats[2]); 824506d4bc8SPeter Zijlstra 8254aa9015fSStephane Eranian fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled); 826506d4bc8SPeter Zijlstra } 8274aa9015fSStephane Eranian fprintf(output, "\n"); 82842202dd5SIngo Molnar } 82942202dd5SIngo Molnar 830f5b4a9c3SStephane Eranian /* 831f5b4a9c3SStephane Eranian * Print out the results of a single counter: 832f5b4a9c3SStephane Eranian * does not use aggregated count in system-wide 833f5b4a9c3SStephane Eranian */ 83469aad6f1SArnaldo Carvalho de Melo static void print_counter(struct perf_evsel *counter) 835f5b4a9c3SStephane Eranian { 836f5b4a9c3SStephane Eranian u64 ena, run, val; 837f5b4a9c3SStephane Eranian int cpu; 838f5b4a9c3SStephane Eranian 8397ae92e74SYan, Zheng for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 840c52b12edSArnaldo Carvalho de Melo val = counter->counts->cpu[cpu].val; 841c52b12edSArnaldo Carvalho de Melo ena = counter->counts->cpu[cpu].ena; 842c52b12edSArnaldo Carvalho de Melo run = counter->counts->cpu[cpu].run; 843f5b4a9c3SStephane Eranian if (run == 0 || ena == 0) { 8444aa9015fSStephane Eranian fprintf(output, "CPU%*d%s%*s%s%*s", 845d7470b6aSStephane Eranian csv_output ? 0 : -4, 8467ae92e74SYan, Zheng perf_evsel__cpus(counter)->map[cpu], csv_sep, 847d7470b6aSStephane Eranian csv_output ? 0 : 18, 8482cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 8492cee77c4SDavid Ahern csv_sep, 850023695d9SStephane Eranian csv_output ? 0 : -24, 8517289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 852f5b4a9c3SStephane Eranian 853023695d9SStephane Eranian if (counter->cgrp) 8544aa9015fSStephane Eranian fprintf(output, "%s%s", 8554aa9015fSStephane Eranian csv_sep, counter->cgrp->name); 856023695d9SStephane Eranian 8574aa9015fSStephane Eranian fputc('\n', output); 858f5b4a9c3SStephane Eranian continue; 859f5b4a9c3SStephane Eranian } 860f5b4a9c3SStephane Eranian 861f5b4a9c3SStephane Eranian if (nsec_counter(counter)) 862f5b4a9c3SStephane Eranian nsec_printout(cpu, counter, val); 863f5b4a9c3SStephane Eranian else 864f5b4a9c3SStephane Eranian abs_printout(cpu, counter, val); 865f5b4a9c3SStephane Eranian 866d7470b6aSStephane Eranian if (!csv_output) { 867f5b4a9c3SStephane Eranian print_noise(counter, 1.0); 868f5b4a9c3SStephane Eranian 869c6264defSIngo Molnar if (run != ena) 8704aa9015fSStephane Eranian fprintf(output, " (%.2f%%)", 8714aa9015fSStephane Eranian 100.0 * run / ena); 872d7470b6aSStephane Eranian } 8734aa9015fSStephane Eranian fputc('\n', output); 874f5b4a9c3SStephane Eranian } 875f5b4a9c3SStephane Eranian } 876f5b4a9c3SStephane Eranian 87742202dd5SIngo Molnar static void print_stat(int argc, const char **argv) 87842202dd5SIngo Molnar { 87969aad6f1SArnaldo Carvalho de Melo struct perf_evsel *counter; 88069aad6f1SArnaldo Carvalho de Melo int i; 88142202dd5SIngo Molnar 88286470930SIngo Molnar fflush(stdout); 88386470930SIngo Molnar 884d7470b6aSStephane Eranian if (!csv_output) { 8854aa9015fSStephane Eranian fprintf(output, "\n"); 8864aa9015fSStephane Eranian fprintf(output, " Performance counter stats for "); 887aa22dd49SNamhyung Kim if (!perf_target__has_task(&target)) { 8884aa9015fSStephane Eranian fprintf(output, "\'%s", argv[0]); 88986470930SIngo Molnar for (i = 1; i < argc; i++) 8904aa9015fSStephane Eranian fprintf(output, " %s", argv[i]); 89120f946b4SNamhyung Kim } else if (target.pid) 89220f946b4SNamhyung Kim fprintf(output, "process id \'%s", target.pid); 893d6d901c2SZhang, Yanmin else 89420f946b4SNamhyung Kim fprintf(output, "thread id \'%s", target.tid); 89586470930SIngo Molnar 8964aa9015fSStephane Eranian fprintf(output, "\'"); 89742202dd5SIngo Molnar if (run_count > 1) 8984aa9015fSStephane Eranian fprintf(output, " (%d runs)", run_count); 8994aa9015fSStephane Eranian fprintf(output, ":\n\n"); 900d7470b6aSStephane Eranian } 90186470930SIngo Molnar 902f5b4a9c3SStephane Eranian if (no_aggr) { 903361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) 90486470930SIngo Molnar print_counter(counter); 905f5b4a9c3SStephane Eranian } else { 906361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) 907f5b4a9c3SStephane Eranian print_counter_aggr(counter); 908f5b4a9c3SStephane Eranian } 90986470930SIngo Molnar 910d7470b6aSStephane Eranian if (!csv_output) { 911c3305257SIngo Molnar if (!null_run) 9124aa9015fSStephane Eranian fprintf(output, "\n"); 9134aa9015fSStephane Eranian fprintf(output, " %17.9f seconds time elapsed", 914506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)/1e9); 915566747e6SIngo Molnar if (run_count > 1) { 9164aa9015fSStephane Eranian fprintf(output, " "); 917f99844cbSIngo Molnar print_noise_pct(stddev_stats(&walltime_nsecs_stats), 918506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)); 919566747e6SIngo Molnar } 9204aa9015fSStephane Eranian fprintf(output, "\n\n"); 92186470930SIngo Molnar } 922d7470b6aSStephane Eranian } 92386470930SIngo Molnar 924f7b7c26eSPeter Zijlstra static volatile int signr = -1; 925f7b7c26eSPeter Zijlstra 92686470930SIngo Molnar static void skip_signal(int signo) 92786470930SIngo Molnar { 9286be2850eSZhang, Yanmin if(child_pid == -1) 92960666c63SLiming Wang done = 1; 93060666c63SLiming Wang 931f7b7c26eSPeter Zijlstra signr = signo; 932f7b7c26eSPeter Zijlstra } 933f7b7c26eSPeter Zijlstra 934f7b7c26eSPeter Zijlstra static void sig_atexit(void) 935f7b7c26eSPeter Zijlstra { 936933da83aSChris Wilson if (child_pid != -1) 937933da83aSChris Wilson kill(child_pid, SIGTERM); 938933da83aSChris Wilson 939f7b7c26eSPeter Zijlstra if (signr == -1) 940f7b7c26eSPeter Zijlstra return; 941f7b7c26eSPeter Zijlstra 942f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 943f7b7c26eSPeter Zijlstra kill(getpid(), signr); 94486470930SIngo Molnar } 94586470930SIngo Molnar 9461d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused, 9471d037ca1SIrina Tirdea const char *s __maybe_unused, int unset) 948d7470b6aSStephane Eranian { 949d7470b6aSStephane Eranian big_num_opt = unset ? 0 : 1; 950d7470b6aSStephane Eranian return 0; 951d7470b6aSStephane Eranian } 952d7470b6aSStephane Eranian 9532cba3ffbSIngo Molnar /* 9542cba3ffbSIngo Molnar * Add default attributes, if there were no attributes specified or 9552cba3ffbSIngo Molnar * if -d/--detailed, -d -d or -d -d -d is used: 9562cba3ffbSIngo Molnar */ 9572cba3ffbSIngo Molnar static int add_default_attributes(void) 9582cba3ffbSIngo Molnar { 959b070a547SArnaldo Carvalho de Melo struct perf_event_attr default_attrs[] = { 960b070a547SArnaldo Carvalho de Melo 961b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 962b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 963b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 964b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 965b070a547SArnaldo Carvalho de Melo 966b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 967b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 968b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 969b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 970b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 971b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 972b070a547SArnaldo Carvalho de Melo 973b070a547SArnaldo Carvalho de Melo }; 974b070a547SArnaldo Carvalho de Melo 975b070a547SArnaldo Carvalho de Melo /* 976b070a547SArnaldo Carvalho de Melo * Detailed stats (-d), covering the L1 and last level data caches: 977b070a547SArnaldo Carvalho de Melo */ 978b070a547SArnaldo Carvalho de Melo struct perf_event_attr detailed_attrs[] = { 979b070a547SArnaldo Carvalho de Melo 980b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 981b070a547SArnaldo Carvalho de Melo .config = 982b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 983b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 984b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 985b070a547SArnaldo Carvalho de Melo 986b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 987b070a547SArnaldo Carvalho de Melo .config = 988b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 989b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 990b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 991b070a547SArnaldo Carvalho de Melo 992b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 993b070a547SArnaldo Carvalho de Melo .config = 994b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 995b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 996b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 997b070a547SArnaldo Carvalho de Melo 998b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 999b070a547SArnaldo Carvalho de Melo .config = 1000b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1001b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1002b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1003b070a547SArnaldo Carvalho de Melo }; 1004b070a547SArnaldo Carvalho de Melo 1005b070a547SArnaldo Carvalho de Melo /* 1006b070a547SArnaldo Carvalho de Melo * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: 1007b070a547SArnaldo Carvalho de Melo */ 1008b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_detailed_attrs[] = { 1009b070a547SArnaldo Carvalho de Melo 1010b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1011b070a547SArnaldo Carvalho de Melo .config = 1012b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1013b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1014b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1015b070a547SArnaldo Carvalho de Melo 1016b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1017b070a547SArnaldo Carvalho de Melo .config = 1018b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1019b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1020b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1021b070a547SArnaldo Carvalho de Melo 1022b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1023b070a547SArnaldo Carvalho de Melo .config = 1024b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1025b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1026b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1027b070a547SArnaldo Carvalho de Melo 1028b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1029b070a547SArnaldo Carvalho de Melo .config = 1030b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1031b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1032b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1033b070a547SArnaldo Carvalho de Melo 1034b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1035b070a547SArnaldo Carvalho de Melo .config = 1036b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1037b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1038b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1039b070a547SArnaldo Carvalho de Melo 1040b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1041b070a547SArnaldo Carvalho de Melo .config = 1042b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1043b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1044b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1045b070a547SArnaldo Carvalho de Melo 1046b070a547SArnaldo Carvalho de Melo }; 1047b070a547SArnaldo Carvalho de Melo 1048b070a547SArnaldo Carvalho de Melo /* 1049b070a547SArnaldo Carvalho de Melo * Very, very detailed stats (-d -d -d), adding prefetch events: 1050b070a547SArnaldo Carvalho de Melo */ 1051b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_very_detailed_attrs[] = { 1052b070a547SArnaldo Carvalho de Melo 1053b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1054b070a547SArnaldo Carvalho de Melo .config = 1055b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1056b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1057b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1058b070a547SArnaldo Carvalho de Melo 1059b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1060b070a547SArnaldo Carvalho de Melo .config = 1061b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1062b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1063b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1064b070a547SArnaldo Carvalho de Melo }; 1065b070a547SArnaldo Carvalho de Melo 10662cba3ffbSIngo Molnar /* Set attrs if no event is selected and !null_run: */ 10672cba3ffbSIngo Molnar if (null_run) 10682cba3ffbSIngo Molnar return 0; 10692cba3ffbSIngo Molnar 10702cba3ffbSIngo Molnar if (!evsel_list->nr_entries) { 107179695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0) 10722cba3ffbSIngo Molnar return -1; 10732cba3ffbSIngo Molnar } 10742cba3ffbSIngo Molnar 10752cba3ffbSIngo Molnar /* Detailed events get appended to the event list: */ 10762cba3ffbSIngo Molnar 10772cba3ffbSIngo Molnar if (detailed_run < 1) 10782cba3ffbSIngo Molnar return 0; 10792cba3ffbSIngo Molnar 10802cba3ffbSIngo Molnar /* Append detailed run extra attributes: */ 108179695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) 10822cba3ffbSIngo Molnar return -1; 10832cba3ffbSIngo Molnar 10842cba3ffbSIngo Molnar if (detailed_run < 2) 10852cba3ffbSIngo Molnar return 0; 10862cba3ffbSIngo Molnar 10872cba3ffbSIngo Molnar /* Append very detailed run extra attributes: */ 108879695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) 10892cba3ffbSIngo Molnar return -1; 10902cba3ffbSIngo Molnar 10912cba3ffbSIngo Molnar if (detailed_run < 3) 10922cba3ffbSIngo Molnar return 0; 10932cba3ffbSIngo Molnar 10942cba3ffbSIngo Molnar /* Append very, very detailed run extra attributes: */ 109579695e1bSArnaldo Carvalho de Melo return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); 10962cba3ffbSIngo Molnar } 10972cba3ffbSIngo Molnar 10981d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) 109986470930SIngo Molnar { 11001f16c575SPeter Zijlstra bool append_file = false; 1101b070a547SArnaldo Carvalho de Melo int output_fd = 0; 1102b070a547SArnaldo Carvalho de Melo const char *output_name = NULL; 1103b070a547SArnaldo Carvalho de Melo const struct option options[] = { 1104b070a547SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &evsel_list, "event", 1105b070a547SArnaldo Carvalho de Melo "event selector. use 'perf list' to list available events", 1106b070a547SArnaldo Carvalho de Melo parse_events_option), 1107b070a547SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &evsel_list, "filter", 1108b070a547SArnaldo Carvalho de Melo "event filter", parse_filter), 1109b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('i', "no-inherit", &no_inherit, 1110b070a547SArnaldo Carvalho de Melo "child tasks do not inherit counters"), 1111b070a547SArnaldo Carvalho de Melo OPT_STRING('p', "pid", &target.pid, "pid", 1112b070a547SArnaldo Carvalho de Melo "stat events on existing process id"), 1113b070a547SArnaldo Carvalho de Melo OPT_STRING('t', "tid", &target.tid, "tid", 1114b070a547SArnaldo Carvalho de Melo "stat events on existing thread id"), 1115b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('a', "all-cpus", &target.system_wide, 1116b070a547SArnaldo Carvalho de Melo "system-wide collection from all CPUs"), 1117b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('g', "group", &group, 1118b070a547SArnaldo Carvalho de Melo "put the counters into a counter group"), 1119b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"), 1120b070a547SArnaldo Carvalho de Melo OPT_INCR('v', "verbose", &verbose, 1121b070a547SArnaldo Carvalho de Melo "be more verbose (show counter open errors, etc)"), 1122b070a547SArnaldo Carvalho de Melo OPT_INTEGER('r', "repeat", &run_count, 1123b070a547SArnaldo Carvalho de Melo "repeat command and print average + stddev (max: 100)"), 1124b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "null", &null_run, 1125b070a547SArnaldo Carvalho de Melo "null run - dont start any counters"), 1126b070a547SArnaldo Carvalho de Melo OPT_INCR('d', "detailed", &detailed_run, 1127b070a547SArnaldo Carvalho de Melo "detailed run - start a lot of events"), 1128b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('S', "sync", &sync_run, 1129b070a547SArnaldo Carvalho de Melo "call sync() before starting a run"), 1130b070a547SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 1131b070a547SArnaldo Carvalho de Melo "print large numbers with thousands\' separators", 1132b070a547SArnaldo Carvalho de Melo stat__set_big_num), 1133b070a547SArnaldo Carvalho de Melo OPT_STRING('C', "cpu", &target.cpu_list, "cpu", 1134b070a547SArnaldo Carvalho de Melo "list of cpus to monitor in system-wide"), 1135b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('A', "no-aggr", &no_aggr, "disable CPU count aggregation"), 1136b070a547SArnaldo Carvalho de Melo OPT_STRING('x', "field-separator", &csv_sep, "separator", 1137b070a547SArnaldo Carvalho de Melo "print counts with custom separator"), 1138b070a547SArnaldo Carvalho de Melo OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1139b070a547SArnaldo Carvalho de Melo "monitor event in cgroup name only", parse_cgroups), 1140b070a547SArnaldo Carvalho de Melo OPT_STRING('o', "output", &output_name, "file", "output file name"), 1141b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), 1142b070a547SArnaldo Carvalho de Melo OPT_INTEGER(0, "log-fd", &output_fd, 1143b070a547SArnaldo Carvalho de Melo "log output to fd, instead of stderr"), 11441f16c575SPeter Zijlstra OPT_STRING(0, "pre", &pre_cmd, "command", 11451f16c575SPeter Zijlstra "command to run prior to the measured command"), 11461f16c575SPeter Zijlstra OPT_STRING(0, "post", &post_cmd, "command", 11471f16c575SPeter Zijlstra "command to run after to the measured command"), 1148b070a547SArnaldo Carvalho de Melo OPT_END() 1149b070a547SArnaldo Carvalho de Melo }; 1150b070a547SArnaldo Carvalho de Melo const char * const stat_usage[] = { 1151b070a547SArnaldo Carvalho de Melo "perf stat [<options>] [<command>]", 1152b070a547SArnaldo Carvalho de Melo NULL 1153b070a547SArnaldo Carvalho de Melo }; 115469aad6f1SArnaldo Carvalho de Melo struct perf_evsel *pos; 1155b070a547SArnaldo Carvalho de Melo int status = -ENOMEM, run_idx; 11564aa9015fSStephane Eranian const char *mode; 115742202dd5SIngo Molnar 11585af52b51SStephane Eranian setlocale(LC_ALL, ""); 11595af52b51SStephane Eranian 11607e2ed097SArnaldo Carvalho de Melo evsel_list = perf_evlist__new(NULL, NULL); 1161361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 1162361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1163361c99a6SArnaldo Carvalho de Melo 1164a0541234SAnton Blanchard argc = parse_options(argc, argv, options, stat_usage, 1165a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 1166d7470b6aSStephane Eranian 11674aa9015fSStephane Eranian output = stderr; 11684aa9015fSStephane Eranian if (output_name && strcmp(output_name, "-")) 11694aa9015fSStephane Eranian output = NULL; 11704aa9015fSStephane Eranian 117156f3bae7SJim Cromie if (output_name && output_fd) { 117256f3bae7SJim Cromie fprintf(stderr, "cannot use both --output and --log-fd\n"); 117356f3bae7SJim Cromie usage_with_options(stat_usage, options); 117456f3bae7SJim Cromie } 1175fc3e4d07SStephane Eranian 1176fc3e4d07SStephane Eranian if (output_fd < 0) { 1177fc3e4d07SStephane Eranian fprintf(stderr, "argument to --log-fd must be a > 0\n"); 1178fc3e4d07SStephane Eranian usage_with_options(stat_usage, options); 1179fc3e4d07SStephane Eranian } 1180fc3e4d07SStephane Eranian 11814aa9015fSStephane Eranian if (!output) { 11824aa9015fSStephane Eranian struct timespec tm; 11834aa9015fSStephane Eranian mode = append_file ? "a" : "w"; 11844aa9015fSStephane Eranian 11854aa9015fSStephane Eranian output = fopen(output_name, mode); 11864aa9015fSStephane Eranian if (!output) { 11874aa9015fSStephane Eranian perror("failed to create output file"); 1188fceda7feSDavid Ahern return -1; 11894aa9015fSStephane Eranian } 11904aa9015fSStephane Eranian clock_gettime(CLOCK_REALTIME, &tm); 11914aa9015fSStephane Eranian fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 1192fc3e4d07SStephane Eranian } else if (output_fd > 0) { 119356f3bae7SJim Cromie mode = append_file ? "a" : "w"; 119456f3bae7SJim Cromie output = fdopen(output_fd, mode); 119556f3bae7SJim Cromie if (!output) { 119656f3bae7SJim Cromie perror("Failed opening logfd"); 119756f3bae7SJim Cromie return -errno; 119856f3bae7SJim Cromie } 11994aa9015fSStephane Eranian } 12004aa9015fSStephane Eranian 1201d4ffd04dSJim Cromie if (csv_sep) { 1202d7470b6aSStephane Eranian csv_output = true; 1203d4ffd04dSJim Cromie if (!strcmp(csv_sep, "\\t")) 1204d4ffd04dSJim Cromie csv_sep = "\t"; 1205d4ffd04dSJim Cromie } else 1206d7470b6aSStephane Eranian csv_sep = DEFAULT_SEPARATOR; 1207d7470b6aSStephane Eranian 1208d7470b6aSStephane Eranian /* 1209d7470b6aSStephane Eranian * let the spreadsheet do the pretty-printing 1210d7470b6aSStephane Eranian */ 1211d7470b6aSStephane Eranian if (csv_output) { 121261a9f324SJim Cromie /* User explicitly passed -B? */ 1213d7470b6aSStephane Eranian if (big_num_opt == 1) { 1214d7470b6aSStephane Eranian fprintf(stderr, "-B option not supported with -x\n"); 1215d7470b6aSStephane Eranian usage_with_options(stat_usage, options); 1216d7470b6aSStephane Eranian } else /* Nope, so disable big number formatting */ 1217d7470b6aSStephane Eranian big_num = false; 1218d7470b6aSStephane Eranian } else if (big_num_opt == 0) /* User passed --no-big-num */ 1219d7470b6aSStephane Eranian big_num = false; 1220d7470b6aSStephane Eranian 1221aa22dd49SNamhyung Kim if (!argc && !perf_target__has_task(&target)) 122286470930SIngo Molnar usage_with_options(stat_usage, options); 12239e9772c4SPeter Zijlstra if (run_count <= 0) 122442202dd5SIngo Molnar usage_with_options(stat_usage, options); 122586470930SIngo Molnar 1226023695d9SStephane Eranian /* no_aggr, cgroup are for system-wide only */ 1227aa22dd49SNamhyung Kim if ((no_aggr || nr_cgroups) && !perf_target__has_cpu(&target)) { 1228023695d9SStephane Eranian fprintf(stderr, "both cgroup and no-aggregation " 1229023695d9SStephane Eranian "modes only available in system-wide mode\n"); 1230023695d9SStephane Eranian 1231f5b4a9c3SStephane Eranian usage_with_options(stat_usage, options); 1232023695d9SStephane Eranian } 1233f5b4a9c3SStephane Eranian 12342cba3ffbSIngo Molnar if (add_default_attributes()) 1235c6264defSIngo Molnar goto out; 123686470930SIngo Molnar 12374bd0f2d2SNamhyung Kim perf_target__validate(&target); 12385c98d466SArnaldo Carvalho de Melo 123977a6f014SNamhyung Kim if (perf_evlist__create_maps(evsel_list, &target) < 0) { 1240aa22dd49SNamhyung Kim if (perf_target__has_task(&target)) 12415c98d466SArnaldo Carvalho de Melo pr_err("Problems finding threads of monitor\n"); 1242aa22dd49SNamhyung Kim if (perf_target__has_cpu(&target)) 124360d567e2SArnaldo Carvalho de Melo perror("failed to parse CPUs map"); 124477a6f014SNamhyung Kim 1245c45c6ea2SStephane Eranian usage_with_options(stat_usage, options); 124660d567e2SArnaldo Carvalho de Melo return -1; 124760d567e2SArnaldo Carvalho de Melo } 1248c45c6ea2SStephane Eranian 1249361c99a6SArnaldo Carvalho de Melo list_for_each_entry(pos, &evsel_list->entries, node) { 1250c52b12edSArnaldo Carvalho de Melo if (perf_evsel__alloc_stat_priv(pos) < 0 || 12517ae92e74SYan, Zheng perf_evsel__alloc_counts(pos, perf_evsel__nr_cpus(pos)) < 0) 125269aad6f1SArnaldo Carvalho de Melo goto out_free_fd; 1253d6d901c2SZhang, Yanmin } 1254d6d901c2SZhang, Yanmin 125586470930SIngo Molnar /* 125686470930SIngo Molnar * We dont want to block the signals - that would cause 125786470930SIngo Molnar * child tasks to inherit that and Ctrl-C would not work. 125886470930SIngo Molnar * What we want is for Ctrl-C to work in the exec()-ed 125986470930SIngo Molnar * task, but being ignored by perf stat itself: 126086470930SIngo Molnar */ 1261f7b7c26eSPeter Zijlstra atexit(sig_atexit); 126286470930SIngo Molnar signal(SIGINT, skip_signal); 126386470930SIngo Molnar signal(SIGALRM, skip_signal); 126486470930SIngo Molnar signal(SIGABRT, skip_signal); 126586470930SIngo Molnar 126642202dd5SIngo Molnar status = 0; 126742202dd5SIngo Molnar for (run_idx = 0; run_idx < run_count; run_idx++) { 126842202dd5SIngo Molnar if (run_count != 1 && verbose) 12694aa9015fSStephane Eranian fprintf(output, "[ perf stat: executing run #%d ... ]\n", 12704aa9015fSStephane Eranian run_idx + 1); 1271f9cef0a9SIngo Molnar 127242202dd5SIngo Molnar status = run_perf_stat(argc, argv); 127342202dd5SIngo Molnar } 127442202dd5SIngo Molnar 1275084ab9f8SArnaldo Carvalho de Melo if (status != -1) 127642202dd5SIngo Molnar print_stat(argc, argv); 127769aad6f1SArnaldo Carvalho de Melo out_free_fd: 1278361c99a6SArnaldo Carvalho de Melo list_for_each_entry(pos, &evsel_list->entries, node) 127969aad6f1SArnaldo Carvalho de Melo perf_evsel__free_stat_priv(pos); 12807e2ed097SArnaldo Carvalho de Melo perf_evlist__delete_maps(evsel_list); 12810015e2e1SArnaldo Carvalho de Melo out: 12820015e2e1SArnaldo Carvalho de Melo perf_evlist__delete(evsel_list); 128342202dd5SIngo Molnar return status; 128486470930SIngo Molnar } 1285