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" 5460666c63SLiming Wang #include "util/header.h" 55a12b51c4SPaul Mackerras #include "util/cpumap.h" 56d6d901c2SZhang, Yanmin #include "util/thread.h" 57fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 5886470930SIngo Molnar 5986470930SIngo Molnar #include <sys/prctl.h> 6042202dd5SIngo Molnar #include <math.h> 615af52b51SStephane Eranian #include <locale.h> 6286470930SIngo Molnar 63d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR " " 642cee77c4SDavid Ahern #define CNTR_NOT_SUPPORTED "<not supported>" 652cee77c4SDavid Ahern #define CNTR_NOT_COUNTED "<not counted>" 66d7470b6aSStephane Eranian 67cdd6c482SIngo Molnar static struct perf_event_attr default_attrs[] = { 6886470930SIngo Molnar 69f4dbfa8fSPeter Zijlstra { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 70f4dbfa8fSPeter Zijlstra { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 71f4dbfa8fSPeter Zijlstra { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 72f4dbfa8fSPeter Zijlstra { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 7386470930SIngo Molnar 74f4dbfa8fSPeter Zijlstra { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 75129c04cbSIngo Molnar { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 76129c04cbSIngo Molnar { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 77f4dbfa8fSPeter Zijlstra { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 7812133affSTim Blechmann { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 7912133affSTim Blechmann { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 80f4dbfa8fSPeter Zijlstra 8186470930SIngo Molnar }; 8286470930SIngo Molnar 83c6264defSIngo Molnar /* 842cba3ffbSIngo Molnar * Detailed stats (-d), covering the L1 and last level data caches: 85c6264defSIngo Molnar */ 86c6264defSIngo Molnar static struct perf_event_attr detailed_attrs[] = { 87c6264defSIngo Molnar 88c6264defSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 89c6264defSIngo Molnar .config = 90c6264defSIngo Molnar PERF_COUNT_HW_CACHE_L1D << 0 | 91c6264defSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 92c6264defSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 93c6264defSIngo Molnar 94c6264defSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 95c6264defSIngo Molnar .config = 96c6264defSIngo Molnar PERF_COUNT_HW_CACHE_L1D << 0 | 97c6264defSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 98c6264defSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 99c6264defSIngo Molnar 100c6264defSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 101c6264defSIngo Molnar .config = 102c6264defSIngo Molnar PERF_COUNT_HW_CACHE_LL << 0 | 103c6264defSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 104c6264defSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 105c6264defSIngo Molnar 106c6264defSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 107c6264defSIngo Molnar .config = 108c6264defSIngo Molnar PERF_COUNT_HW_CACHE_LL << 0 | 109c6264defSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 110c6264defSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 111c6264defSIngo Molnar }; 112c6264defSIngo Molnar 1132cba3ffbSIngo Molnar /* 1142cba3ffbSIngo Molnar * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: 1152cba3ffbSIngo Molnar */ 1162cba3ffbSIngo Molnar static struct perf_event_attr very_detailed_attrs[] = { 1172cba3ffbSIngo Molnar 1182cba3ffbSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 1192cba3ffbSIngo Molnar .config = 1202cba3ffbSIngo Molnar PERF_COUNT_HW_CACHE_L1I << 0 | 1212cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1222cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1232cba3ffbSIngo Molnar 1242cba3ffbSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 1252cba3ffbSIngo Molnar .config = 1262cba3ffbSIngo Molnar PERF_COUNT_HW_CACHE_L1I << 0 | 1272cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1282cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1292cba3ffbSIngo Molnar 1302cba3ffbSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 1312cba3ffbSIngo Molnar .config = 1322cba3ffbSIngo Molnar PERF_COUNT_HW_CACHE_DTLB << 0 | 1332cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1342cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1352cba3ffbSIngo Molnar 1362cba3ffbSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 1372cba3ffbSIngo Molnar .config = 1382cba3ffbSIngo Molnar PERF_COUNT_HW_CACHE_DTLB << 0 | 1392cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1402cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1412cba3ffbSIngo Molnar 1422cba3ffbSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 1432cba3ffbSIngo Molnar .config = 1442cba3ffbSIngo Molnar PERF_COUNT_HW_CACHE_ITLB << 0 | 1452cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1462cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1472cba3ffbSIngo Molnar 1482cba3ffbSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 1492cba3ffbSIngo Molnar .config = 1502cba3ffbSIngo Molnar PERF_COUNT_HW_CACHE_ITLB << 0 | 1512cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1522cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1532cba3ffbSIngo Molnar 1542cba3ffbSIngo Molnar }; 1552cba3ffbSIngo Molnar 1562cba3ffbSIngo Molnar /* 1572cba3ffbSIngo Molnar * Very, very detailed stats (-d -d -d), adding prefetch events: 1582cba3ffbSIngo Molnar */ 1592cba3ffbSIngo Molnar static struct perf_event_attr very_very_detailed_attrs[] = { 1602cba3ffbSIngo Molnar 1612cba3ffbSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 1622cba3ffbSIngo Molnar .config = 1632cba3ffbSIngo Molnar PERF_COUNT_HW_CACHE_L1D << 0 | 1642cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1652cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1662cba3ffbSIngo Molnar 1672cba3ffbSIngo Molnar { .type = PERF_TYPE_HW_CACHE, 1682cba3ffbSIngo Molnar .config = 1692cba3ffbSIngo Molnar PERF_COUNT_HW_CACHE_L1D << 0 | 1702cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1712cba3ffbSIngo Molnar (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1722cba3ffbSIngo Molnar }; 1732cba3ffbSIngo Molnar 1742cba3ffbSIngo Molnar 1752cba3ffbSIngo Molnar 176361c99a6SArnaldo Carvalho de Melo struct perf_evlist *evsel_list; 177361c99a6SArnaldo Carvalho de Melo 178c0555642SIan Munsie static bool system_wide = false; 17942202dd5SIngo Molnar static int run_idx = 0; 18042202dd5SIngo Molnar 1813d632595SJaswinder Singh Rajput static int run_count = 1; 1822e6cdf99SStephane Eranian static bool no_inherit = false; 183c0555642SIan Munsie static bool scale = true; 184f5b4a9c3SStephane Eranian static bool no_aggr = false; 185933da83aSChris Wilson static pid_t target_pid = -1; 186d6d901c2SZhang, Yanmin static pid_t target_tid = -1; 187933da83aSChris Wilson static pid_t child_pid = -1; 188c0555642SIan Munsie static bool null_run = false; 1892cba3ffbSIngo Molnar static int detailed_run = 0; 190f9cef0a9SIngo Molnar static bool sync_run = false; 191201e0b06SArnaldo Carvalho de Melo static bool big_num = true; 192d7470b6aSStephane Eranian static int big_num_opt = -1; 193c45c6ea2SStephane Eranian static const char *cpu_list; 194d7470b6aSStephane Eranian static const char *csv_sep = NULL; 195d7470b6aSStephane Eranian static bool csv_output = false; 19643bece79SLin Ming static bool group = false; 1974aa9015fSStephane Eranian static const char *output_name = NULL; 1984aa9015fSStephane Eranian static FILE *output = NULL; 19956f3bae7SJim Cromie static int output_fd; 2005af52b51SStephane Eranian 20160666c63SLiming Wang static volatile int done = 0; 20260666c63SLiming Wang 203506d4bc8SPeter Zijlstra struct stats 204506d4bc8SPeter Zijlstra { 2058a02631aSPeter Zijlstra double n, mean, M2; 206506d4bc8SPeter Zijlstra }; 20742202dd5SIngo Molnar 20869aad6f1SArnaldo Carvalho de Melo struct perf_stat { 20969aad6f1SArnaldo Carvalho de Melo struct stats res_stats[3]; 21069aad6f1SArnaldo Carvalho de Melo }; 21169aad6f1SArnaldo Carvalho de Melo 212c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) 21369aad6f1SArnaldo Carvalho de Melo { 214c52b12edSArnaldo Carvalho de Melo evsel->priv = zalloc(sizeof(struct perf_stat)); 21569aad6f1SArnaldo Carvalho de Melo return evsel->priv == NULL ? -ENOMEM : 0; 21669aad6f1SArnaldo Carvalho de Melo } 21769aad6f1SArnaldo Carvalho de Melo 21869aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) 21969aad6f1SArnaldo Carvalho de Melo { 22069aad6f1SArnaldo Carvalho de Melo free(evsel->priv); 22169aad6f1SArnaldo Carvalho de Melo evsel->priv = NULL; 22269aad6f1SArnaldo Carvalho de Melo } 22369aad6f1SArnaldo Carvalho de Melo 2249e9772c4SPeter Zijlstra static void update_stats(struct stats *stats, u64 val) 2259e9772c4SPeter Zijlstra { 2268a02631aSPeter Zijlstra double delta; 2279e9772c4SPeter Zijlstra 2288a02631aSPeter Zijlstra stats->n++; 2298a02631aSPeter Zijlstra delta = val - stats->mean; 2308a02631aSPeter Zijlstra stats->mean += delta / stats->n; 2318a02631aSPeter Zijlstra stats->M2 += delta*(val - stats->mean); 2329e9772c4SPeter Zijlstra } 2339e9772c4SPeter Zijlstra 234506d4bc8SPeter Zijlstra static double avg_stats(struct stats *stats) 235506d4bc8SPeter Zijlstra { 2368a02631aSPeter Zijlstra return stats->mean; 237506d4bc8SPeter Zijlstra } 23842202dd5SIngo Molnar 239506d4bc8SPeter Zijlstra /* 24063d40debSPeter Zijlstra * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance 24163d40debSPeter Zijlstra * 24263d40debSPeter Zijlstra * (\Sum n_i^2) - ((\Sum n_i)^2)/n 2438a02631aSPeter Zijlstra * s^2 = ------------------------------- 24463d40debSPeter Zijlstra * n - 1 24563d40debSPeter Zijlstra * 24663d40debSPeter Zijlstra * http://en.wikipedia.org/wiki/Stddev 24763d40debSPeter Zijlstra * 24863d40debSPeter Zijlstra * The std dev of the mean is related to the std dev by: 24963d40debSPeter Zijlstra * 25063d40debSPeter Zijlstra * s 25163d40debSPeter Zijlstra * s_mean = ------- 25263d40debSPeter Zijlstra * sqrt(n) 25363d40debSPeter Zijlstra * 254506d4bc8SPeter Zijlstra */ 255506d4bc8SPeter Zijlstra static double stddev_stats(struct stats *stats) 256506d4bc8SPeter Zijlstra { 25719f47402SJim Cromie double variance, variance_mean; 25819f47402SJim Cromie 25919f47402SJim Cromie if (!stats->n) 26019f47402SJim Cromie return 0.0; 26119f47402SJim Cromie 26219f47402SJim Cromie variance = stats->M2 / (stats->n - 1); 26319f47402SJim Cromie variance_mean = variance / stats->n; 26442202dd5SIngo Molnar 26563d40debSPeter Zijlstra return sqrt(variance_mean); 266506d4bc8SPeter Zijlstra } 26742202dd5SIngo Molnar 268f5b4a9c3SStephane Eranian struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 269f5b4a9c3SStephane Eranian struct stats runtime_cycles_stats[MAX_NR_CPUS]; 270d3d1e86dSIngo Molnar struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS]; 271d3d1e86dSIngo Molnar struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS]; 272f5b4a9c3SStephane Eranian struct stats runtime_branches_stats[MAX_NR_CPUS]; 273d58f4c82SIngo Molnar struct stats runtime_cacherefs_stats[MAX_NR_CPUS]; 2748bb6c79fSIngo Molnar struct stats runtime_l1_dcache_stats[MAX_NR_CPUS]; 275c3305257SIngo Molnar struct stats runtime_l1_icache_stats[MAX_NR_CPUS]; 276c3305257SIngo Molnar struct stats runtime_ll_cache_stats[MAX_NR_CPUS]; 277c3305257SIngo Molnar struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; 278c3305257SIngo Molnar struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; 279506d4bc8SPeter Zijlstra struct stats walltime_nsecs_stats; 28086470930SIngo Molnar 28148290609SArnaldo Carvalho de Melo static int create_perf_stat_counter(struct perf_evsel *evsel) 28286470930SIngo Molnar { 28369aad6f1SArnaldo Carvalho de Melo struct perf_event_attr *attr = &evsel->attr; 28486470930SIngo Molnar 28586470930SIngo Molnar if (scale) 28686470930SIngo Molnar attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 28786470930SIngo Molnar PERF_FORMAT_TOTAL_TIME_RUNNING; 28886470930SIngo Molnar 2892e6cdf99SStephane Eranian attr->inherit = !no_inherit; 2905d2cd909SArnaldo Carvalho de Melo 2915d2cd909SArnaldo Carvalho de Melo if (system_wide) 29243bece79SLin Ming return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, group); 2935d2cd909SArnaldo Carvalho de Melo 2942e6cdf99SStephane Eranian if (target_pid == -1 && target_tid == -1) { 29586470930SIngo Molnar attr->disabled = 1; 29657e7986eSPaul Mackerras attr->enable_on_exec = 1; 2976be2850eSZhang, Yanmin } 298084ab9f8SArnaldo Carvalho de Melo 29943bece79SLin Ming return perf_evsel__open_per_thread(evsel, evsel_list->threads, group); 30086470930SIngo Molnar } 30186470930SIngo Molnar 30286470930SIngo Molnar /* 30386470930SIngo Molnar * Does the counter have nsecs as a unit? 30486470930SIngo Molnar */ 305daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel) 30686470930SIngo Molnar { 307daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || 308daec78a0SArnaldo Carvalho de Melo perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 30986470930SIngo Molnar return 1; 31086470930SIngo Molnar 31186470930SIngo Molnar return 0; 31286470930SIngo Molnar } 31386470930SIngo Molnar 31486470930SIngo Molnar /* 315dcd9936aSIngo Molnar * Update various tracking values we maintain to print 316dcd9936aSIngo Molnar * more semantic information such as miss/hit ratios, 317dcd9936aSIngo Molnar * instruction rates, etc: 318dcd9936aSIngo Molnar */ 319dcd9936aSIngo Molnar static void update_shadow_stats(struct perf_evsel *counter, u64 *count) 320dcd9936aSIngo Molnar { 321dcd9936aSIngo Molnar if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 322dcd9936aSIngo Molnar update_stats(&runtime_nsecs_stats[0], count[0]); 323dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 324dcd9936aSIngo Molnar update_stats(&runtime_cycles_stats[0], count[0]); 325d3d1e86dSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) 326d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_front_stats[0], count[0]); 327129c04cbSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) 328d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_back_stats[0], count[0]); 329dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS)) 330dcd9936aSIngo Molnar update_stats(&runtime_branches_stats[0], count[0]); 331dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES)) 332dcd9936aSIngo Molnar update_stats(&runtime_cacherefs_stats[0], count[0]); 3338bb6c79fSIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D)) 3348bb6c79fSIngo Molnar update_stats(&runtime_l1_dcache_stats[0], count[0]); 335c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I)) 336c3305257SIngo Molnar update_stats(&runtime_l1_icache_stats[0], count[0]); 337c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL)) 338c3305257SIngo Molnar update_stats(&runtime_ll_cache_stats[0], count[0]); 339c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB)) 340c3305257SIngo Molnar update_stats(&runtime_dtlb_cache_stats[0], count[0]); 341c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) 342c3305257SIngo Molnar update_stats(&runtime_itlb_cache_stats[0], count[0]); 343dcd9936aSIngo Molnar } 344dcd9936aSIngo Molnar 345dcd9936aSIngo Molnar /* 34686470930SIngo Molnar * Read out the results of a single counter: 347f5b4a9c3SStephane Eranian * aggregate counts across CPUs in system-wide mode 34886470930SIngo Molnar */ 349c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter) 35086470930SIngo Molnar { 35169aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 352c52b12edSArnaldo Carvalho de Melo u64 *count = counter->counts->aggr.values; 353c52b12edSArnaldo Carvalho de Melo int i; 35486470930SIngo Molnar 3557e2ed097SArnaldo Carvalho de Melo if (__perf_evsel__read(counter, evsel_list->cpus->nr, 3567e2ed097SArnaldo Carvalho de Melo evsel_list->threads->nr, scale) < 0) 357c52b12edSArnaldo Carvalho de Melo return -1; 3589e9772c4SPeter Zijlstra 3599e9772c4SPeter Zijlstra for (i = 0; i < 3; i++) 36069aad6f1SArnaldo Carvalho de Melo update_stats(&ps->res_stats[i], count[i]); 3619e9772c4SPeter Zijlstra 3629e9772c4SPeter Zijlstra if (verbose) { 3634aa9015fSStephane Eranian fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 3649486aa38SArnaldo Carvalho de Melo event_name(counter), count[0], count[1], count[2]); 3659e9772c4SPeter Zijlstra } 3669e9772c4SPeter Zijlstra 36786470930SIngo Molnar /* 36886470930SIngo Molnar * Save the full runtime - to allow normalization during printout: 36986470930SIngo Molnar */ 370dcd9936aSIngo Molnar update_shadow_stats(counter, count); 371c52b12edSArnaldo Carvalho de Melo 372c52b12edSArnaldo Carvalho de Melo return 0; 373f5b4a9c3SStephane Eranian } 374f5b4a9c3SStephane Eranian 375f5b4a9c3SStephane Eranian /* 376f5b4a9c3SStephane Eranian * Read out the results of a single counter: 377f5b4a9c3SStephane Eranian * do not aggregate counts across CPUs in system-wide mode 378f5b4a9c3SStephane Eranian */ 379c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter) 380f5b4a9c3SStephane Eranian { 381c52b12edSArnaldo Carvalho de Melo u64 *count; 382f5b4a9c3SStephane Eranian int cpu; 383f5b4a9c3SStephane Eranian 3847e2ed097SArnaldo Carvalho de Melo for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) { 385c52b12edSArnaldo Carvalho de Melo if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) 386c52b12edSArnaldo Carvalho de Melo return -1; 387f5b4a9c3SStephane Eranian 388c52b12edSArnaldo Carvalho de Melo count = counter->counts->cpu[cpu].values; 389f5b4a9c3SStephane Eranian 390dcd9936aSIngo Molnar update_shadow_stats(counter, count); 391f5b4a9c3SStephane Eranian } 392c52b12edSArnaldo Carvalho de Melo 393c52b12edSArnaldo Carvalho de Melo return 0; 39486470930SIngo Molnar } 39586470930SIngo Molnar 396f37a291cSIngo Molnar static int run_perf_stat(int argc __used, const char **argv) 39786470930SIngo Molnar { 39886470930SIngo Molnar unsigned long long t0, t1; 39969aad6f1SArnaldo Carvalho de Melo struct perf_evsel *counter; 40042202dd5SIngo Molnar int status = 0; 401051ae7f7SPaul Mackerras int child_ready_pipe[2], go_pipe[2]; 4026be2850eSZhang, Yanmin const bool forks = (argc > 0); 403051ae7f7SPaul Mackerras char buf; 40486470930SIngo Molnar 40560666c63SLiming Wang if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { 406051ae7f7SPaul Mackerras perror("failed to create pipes"); 407051ae7f7SPaul Mackerras exit(1); 408051ae7f7SPaul Mackerras } 409051ae7f7SPaul Mackerras 41060666c63SLiming Wang if (forks) { 4116be2850eSZhang, Yanmin if ((child_pid = fork()) < 0) 412051ae7f7SPaul Mackerras perror("failed to fork"); 413051ae7f7SPaul Mackerras 4146be2850eSZhang, Yanmin if (!child_pid) { 415051ae7f7SPaul Mackerras close(child_ready_pipe[0]); 416051ae7f7SPaul Mackerras close(go_pipe[1]); 417051ae7f7SPaul Mackerras fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 418051ae7f7SPaul Mackerras 419051ae7f7SPaul Mackerras /* 420051ae7f7SPaul Mackerras * Do a dummy execvp to get the PLT entry resolved, 421051ae7f7SPaul Mackerras * so we avoid the resolver overhead on the real 422051ae7f7SPaul Mackerras * execvp call. 423051ae7f7SPaul Mackerras */ 424051ae7f7SPaul Mackerras execvp("", (char **)argv); 425051ae7f7SPaul Mackerras 426051ae7f7SPaul Mackerras /* 427051ae7f7SPaul Mackerras * Tell the parent we're ready to go 428051ae7f7SPaul Mackerras */ 429051ae7f7SPaul Mackerras close(child_ready_pipe[1]); 430051ae7f7SPaul Mackerras 431051ae7f7SPaul Mackerras /* 432051ae7f7SPaul Mackerras * Wait until the parent tells us to go. 433051ae7f7SPaul Mackerras */ 434a92bef0fSFrederic Weisbecker if (read(go_pipe[0], &buf, 1) == -1) 435a92bef0fSFrederic Weisbecker perror("unable to read pipe"); 436051ae7f7SPaul Mackerras 437051ae7f7SPaul Mackerras execvp(argv[0], (char **)argv); 438051ae7f7SPaul Mackerras 439051ae7f7SPaul Mackerras perror(argv[0]); 440051ae7f7SPaul Mackerras exit(-1); 441051ae7f7SPaul Mackerras } 442051ae7f7SPaul Mackerras 443d6d901c2SZhang, Yanmin if (target_tid == -1 && target_pid == -1 && !system_wide) 4447e2ed097SArnaldo Carvalho de Melo evsel_list->threads->map[0] = child_pid; 445d6d901c2SZhang, Yanmin 446051ae7f7SPaul Mackerras /* 447051ae7f7SPaul Mackerras * Wait for the child to be ready to exec. 448051ae7f7SPaul Mackerras */ 449051ae7f7SPaul Mackerras close(child_ready_pipe[1]); 450051ae7f7SPaul Mackerras close(go_pipe[0]); 451a92bef0fSFrederic Weisbecker if (read(child_ready_pipe[0], &buf, 1) == -1) 452a92bef0fSFrederic Weisbecker perror("unable to read pipe"); 453051ae7f7SPaul Mackerras close(child_ready_pipe[0]); 45460666c63SLiming Wang } 455051ae7f7SPaul Mackerras 456361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 45748290609SArnaldo Carvalho de Melo if (create_perf_stat_counter(counter) < 0) { 458c63ca0c0SDavid Ahern if (errno == EINVAL || errno == ENOSYS || errno == ENOENT) { 459c63ca0c0SDavid Ahern if (verbose) 460c63ca0c0SDavid Ahern ui__warning("%s event is not supported by the kernel.\n", 461c63ca0c0SDavid Ahern event_name(counter)); 4622cee77c4SDavid Ahern counter->supported = false; 463ede70290SIngo Molnar continue; 464c63ca0c0SDavid Ahern } 465ede70290SIngo Molnar 466ede70290SIngo Molnar if (errno == EPERM || errno == EACCES) { 467d9cf837eSCorey Ashford error("You may not have permission to collect %sstats.\n" 468d9cf837eSCorey Ashford "\t Consider tweaking" 469d9cf837eSCorey Ashford " /proc/sys/kernel/perf_event_paranoid or running as root.", 470084ab9f8SArnaldo Carvalho de Melo system_wide ? "system-wide " : ""); 47148290609SArnaldo Carvalho de Melo } else { 47248290609SArnaldo Carvalho de Melo error("open_counter returned with %d (%s). " 47348290609SArnaldo Carvalho de Melo "/bin/dmesg may provide additional information.\n", 47448290609SArnaldo Carvalho de Melo errno, strerror(errno)); 47548290609SArnaldo Carvalho de Melo } 476084ab9f8SArnaldo Carvalho de Melo if (child_pid != -1) 477084ab9f8SArnaldo Carvalho de Melo kill(child_pid, SIGTERM); 47848290609SArnaldo Carvalho de Melo die("Not all events could be opened.\n"); 479084ab9f8SArnaldo Carvalho de Melo return -1; 480084ab9f8SArnaldo Carvalho de Melo } 4812cee77c4SDavid Ahern counter->supported = true; 48248290609SArnaldo Carvalho de Melo } 48386470930SIngo Molnar 484cfd748aeSFrederic Weisbecker if (perf_evlist__set_filters(evsel_list)) { 485cfd748aeSFrederic Weisbecker error("failed to set filter with %d (%s)\n", errno, 486cfd748aeSFrederic Weisbecker strerror(errno)); 487cfd748aeSFrederic Weisbecker return -1; 488cfd748aeSFrederic Weisbecker } 489cfd748aeSFrederic Weisbecker 49086470930SIngo Molnar /* 49186470930SIngo Molnar * Enable counters and exec the command: 49286470930SIngo Molnar */ 49386470930SIngo Molnar t0 = rdclock(); 49486470930SIngo Molnar 49560666c63SLiming Wang if (forks) { 496051ae7f7SPaul Mackerras close(go_pipe[1]); 49742202dd5SIngo Molnar wait(&status); 49833e49ea7SAndi Kleen if (WIFSIGNALED(status)) 49933e49ea7SAndi Kleen psignal(WTERMSIG(status), argv[0]); 50060666c63SLiming Wang } else { 5016be2850eSZhang, Yanmin while(!done) sleep(1); 50260666c63SLiming Wang } 50386470930SIngo Molnar 50486470930SIngo Molnar t1 = rdclock(); 50586470930SIngo Molnar 5069e9772c4SPeter Zijlstra update_stats(&walltime_nsecs_stats, t1 - t0); 50742202dd5SIngo Molnar 508f5b4a9c3SStephane Eranian if (no_aggr) { 509361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 51042202dd5SIngo Molnar read_counter(counter); 5117e2ed097SArnaldo Carvalho de Melo perf_evsel__close_fd(counter, evsel_list->cpus->nr, 1); 512f5b4a9c3SStephane Eranian } 513c52b12edSArnaldo Carvalho de Melo } else { 514361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 515c52b12edSArnaldo Carvalho de Melo read_counter_aggr(counter); 5167e2ed097SArnaldo Carvalho de Melo perf_evsel__close_fd(counter, evsel_list->cpus->nr, 5177e2ed097SArnaldo Carvalho de Melo evsel_list->threads->nr); 518c52b12edSArnaldo Carvalho de Melo } 519c52b12edSArnaldo Carvalho de Melo } 520c52b12edSArnaldo Carvalho de Melo 52142202dd5SIngo Molnar return WEXITSTATUS(status); 52242202dd5SIngo Molnar } 52342202dd5SIngo Molnar 524f99844cbSIngo Molnar static void print_noise_pct(double total, double avg) 525f99844cbSIngo Molnar { 526f99844cbSIngo Molnar double pct = 0.0; 527f99844cbSIngo Molnar 528f99844cbSIngo Molnar if (avg) 529f99844cbSIngo Molnar pct = 100.0*total/avg; 530f99844cbSIngo Molnar 5313ae9a34dSZhengyu He if (csv_output) 5324aa9015fSStephane Eranian fprintf(output, "%s%.2f%%", csv_sep, pct); 533a1bca6ccSJim Cromie else if (pct) 5344aa9015fSStephane Eranian fprintf(output, " ( +-%6.2f%% )", pct); 535f99844cbSIngo Molnar } 536f99844cbSIngo Molnar 53769aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg) 53842202dd5SIngo Molnar { 53969aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps; 54069aad6f1SArnaldo Carvalho de Melo 541849abde9SPeter Zijlstra if (run_count == 1) 542849abde9SPeter Zijlstra return; 543849abde9SPeter Zijlstra 54469aad6f1SArnaldo Carvalho de Melo ps = evsel->priv; 545f99844cbSIngo Molnar print_noise_pct(stddev_stats(&ps->res_stats[0]), avg); 54642202dd5SIngo Molnar } 54742202dd5SIngo Molnar 548daec78a0SArnaldo Carvalho de Melo static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) 54942202dd5SIngo Molnar { 550506d4bc8SPeter Zijlstra double msecs = avg / 1e6; 551d7470b6aSStephane Eranian char cpustr[16] = { '\0', }; 5522cba3ffbSIngo Molnar const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-25s"; 55342202dd5SIngo Molnar 554f5b4a9c3SStephane Eranian if (no_aggr) 555d7470b6aSStephane Eranian sprintf(cpustr, "CPU%*d%s", 556d7470b6aSStephane Eranian csv_output ? 0 : -4, 5577e2ed097SArnaldo Carvalho de Melo evsel_list->cpus->map[cpu], csv_sep); 558d7470b6aSStephane Eranian 5594aa9015fSStephane Eranian fprintf(output, fmt, cpustr, msecs, csv_sep, event_name(evsel)); 560d7470b6aSStephane Eranian 561023695d9SStephane Eranian if (evsel->cgrp) 5624aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 563023695d9SStephane Eranian 564d7470b6aSStephane Eranian if (csv_output) 565d7470b6aSStephane Eranian return; 56642202dd5SIngo Molnar 567daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 5684aa9015fSStephane Eranian fprintf(output, " # %8.3f CPUs utilized ", 5694aa9015fSStephane Eranian avg / avg_stats(&walltime_nsecs_stats)); 57042202dd5SIngo Molnar } 57142202dd5SIngo Molnar 572d3d1e86dSIngo Molnar static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __used, double avg) 573d3d1e86dSIngo Molnar { 574d3d1e86dSIngo Molnar double total, ratio = 0.0; 575d3d1e86dSIngo Molnar const char *color; 576d3d1e86dSIngo Molnar 577d3d1e86dSIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 578d3d1e86dSIngo Molnar 579d3d1e86dSIngo Molnar if (total) 580d3d1e86dSIngo Molnar ratio = avg / total * 100.0; 581d3d1e86dSIngo Molnar 582d3d1e86dSIngo Molnar color = PERF_COLOR_NORMAL; 5832b427e14SIngo Molnar if (ratio > 50.0) 584d3d1e86dSIngo Molnar color = PERF_COLOR_RED; 5852b427e14SIngo Molnar else if (ratio > 30.0) 586d3d1e86dSIngo Molnar color = PERF_COLOR_MAGENTA; 5872b427e14SIngo Molnar else if (ratio > 10.0) 588d3d1e86dSIngo Molnar color = PERF_COLOR_YELLOW; 589d3d1e86dSIngo Molnar 5904aa9015fSStephane Eranian fprintf(output, " # "); 5914aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 5924aa9015fSStephane Eranian fprintf(output, " frontend cycles idle "); 593d3d1e86dSIngo Molnar } 594d3d1e86dSIngo Molnar 595d3d1e86dSIngo Molnar static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __used, double avg) 596a5d243d0SIngo Molnar { 597a5d243d0SIngo Molnar double total, ratio = 0.0; 598a5d243d0SIngo Molnar const char *color; 599a5d243d0SIngo Molnar 600a5d243d0SIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 601a5d243d0SIngo Molnar 602a5d243d0SIngo Molnar if (total) 603a5d243d0SIngo Molnar ratio = avg / total * 100.0; 604a5d243d0SIngo Molnar 605a5d243d0SIngo Molnar color = PERF_COLOR_NORMAL; 606a5d243d0SIngo Molnar if (ratio > 75.0) 607a5d243d0SIngo Molnar color = PERF_COLOR_RED; 608a5d243d0SIngo Molnar else if (ratio > 50.0) 609a5d243d0SIngo Molnar color = PERF_COLOR_MAGENTA; 6102b427e14SIngo Molnar else if (ratio > 20.0) 611a5d243d0SIngo Molnar color = PERF_COLOR_YELLOW; 612a5d243d0SIngo Molnar 6134aa9015fSStephane Eranian fprintf(output, " # "); 6144aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6154aa9015fSStephane Eranian fprintf(output, " backend cycles idle "); 616a5d243d0SIngo Molnar } 617a5d243d0SIngo Molnar 618c78df6c1SIngo Molnar static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double avg) 619c78df6c1SIngo Molnar { 620c78df6c1SIngo Molnar double total, ratio = 0.0; 621c78df6c1SIngo Molnar const char *color; 622c78df6c1SIngo Molnar 623c78df6c1SIngo Molnar total = avg_stats(&runtime_branches_stats[cpu]); 624c78df6c1SIngo Molnar 625c78df6c1SIngo Molnar if (total) 626c78df6c1SIngo Molnar ratio = avg / total * 100.0; 627c78df6c1SIngo Molnar 628c78df6c1SIngo Molnar color = PERF_COLOR_NORMAL; 629c78df6c1SIngo Molnar if (ratio > 20.0) 630c78df6c1SIngo Molnar color = PERF_COLOR_RED; 631c78df6c1SIngo Molnar else if (ratio > 10.0) 632c78df6c1SIngo Molnar color = PERF_COLOR_MAGENTA; 633c78df6c1SIngo Molnar else if (ratio > 5.0) 634c78df6c1SIngo Molnar color = PERF_COLOR_YELLOW; 635c78df6c1SIngo Molnar 6364aa9015fSStephane Eranian fprintf(output, " # "); 6374aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6384aa9015fSStephane Eranian fprintf(output, " of all branches "); 639c78df6c1SIngo Molnar } 640c78df6c1SIngo Molnar 6418bb6c79fSIngo Molnar static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 6428bb6c79fSIngo Molnar { 6438bb6c79fSIngo Molnar double total, ratio = 0.0; 6448bb6c79fSIngo Molnar const char *color; 6458bb6c79fSIngo Molnar 6468bb6c79fSIngo Molnar total = avg_stats(&runtime_l1_dcache_stats[cpu]); 6478bb6c79fSIngo Molnar 6488bb6c79fSIngo Molnar if (total) 6498bb6c79fSIngo Molnar ratio = avg / total * 100.0; 6508bb6c79fSIngo Molnar 6518bb6c79fSIngo Molnar color = PERF_COLOR_NORMAL; 6528bb6c79fSIngo Molnar if (ratio > 20.0) 6538bb6c79fSIngo Molnar color = PERF_COLOR_RED; 6548bb6c79fSIngo Molnar else if (ratio > 10.0) 6558bb6c79fSIngo Molnar color = PERF_COLOR_MAGENTA; 6568bb6c79fSIngo Molnar else if (ratio > 5.0) 6578bb6c79fSIngo Molnar color = PERF_COLOR_YELLOW; 6588bb6c79fSIngo Molnar 6594aa9015fSStephane Eranian fprintf(output, " # "); 6604aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6614aa9015fSStephane Eranian fprintf(output, " of all L1-dcache hits "); 6628bb6c79fSIngo Molnar } 6638bb6c79fSIngo Molnar 664c3305257SIngo Molnar static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 665c3305257SIngo Molnar { 666c3305257SIngo Molnar double total, ratio = 0.0; 667c3305257SIngo Molnar const char *color; 668c3305257SIngo Molnar 669c3305257SIngo Molnar total = avg_stats(&runtime_l1_icache_stats[cpu]); 670c3305257SIngo Molnar 671c3305257SIngo Molnar if (total) 672c3305257SIngo Molnar ratio = avg / total * 100.0; 673c3305257SIngo Molnar 674c3305257SIngo Molnar color = PERF_COLOR_NORMAL; 675c3305257SIngo Molnar if (ratio > 20.0) 676c3305257SIngo Molnar color = PERF_COLOR_RED; 677c3305257SIngo Molnar else if (ratio > 10.0) 678c3305257SIngo Molnar color = PERF_COLOR_MAGENTA; 679c3305257SIngo Molnar else if (ratio > 5.0) 680c3305257SIngo Molnar color = PERF_COLOR_YELLOW; 681c3305257SIngo Molnar 6824aa9015fSStephane Eranian fprintf(output, " # "); 6834aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 6844aa9015fSStephane Eranian fprintf(output, " of all L1-icache hits "); 685c3305257SIngo Molnar } 686c3305257SIngo Molnar 687c3305257SIngo Molnar static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 688c3305257SIngo Molnar { 689c3305257SIngo Molnar double total, ratio = 0.0; 690c3305257SIngo Molnar const char *color; 691c3305257SIngo Molnar 692c3305257SIngo Molnar total = avg_stats(&runtime_dtlb_cache_stats[cpu]); 693c3305257SIngo Molnar 694c3305257SIngo Molnar if (total) 695c3305257SIngo Molnar ratio = avg / total * 100.0; 696c3305257SIngo Molnar 697c3305257SIngo Molnar color = PERF_COLOR_NORMAL; 698c3305257SIngo Molnar if (ratio > 20.0) 699c3305257SIngo Molnar color = PERF_COLOR_RED; 700c3305257SIngo Molnar else if (ratio > 10.0) 701c3305257SIngo Molnar color = PERF_COLOR_MAGENTA; 702c3305257SIngo Molnar else if (ratio > 5.0) 703c3305257SIngo Molnar color = PERF_COLOR_YELLOW; 704c3305257SIngo Molnar 7054aa9015fSStephane Eranian fprintf(output, " # "); 7064aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7074aa9015fSStephane Eranian fprintf(output, " of all dTLB cache hits "); 708c3305257SIngo Molnar } 709c3305257SIngo Molnar 710c3305257SIngo Molnar static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 711c3305257SIngo Molnar { 712c3305257SIngo Molnar double total, ratio = 0.0; 713c3305257SIngo Molnar const char *color; 714c3305257SIngo Molnar 715c3305257SIngo Molnar total = avg_stats(&runtime_itlb_cache_stats[cpu]); 716c3305257SIngo Molnar 717c3305257SIngo Molnar if (total) 718c3305257SIngo Molnar ratio = avg / total * 100.0; 719c3305257SIngo Molnar 720c3305257SIngo Molnar color = PERF_COLOR_NORMAL; 721c3305257SIngo Molnar if (ratio > 20.0) 722c3305257SIngo Molnar color = PERF_COLOR_RED; 723c3305257SIngo Molnar else if (ratio > 10.0) 724c3305257SIngo Molnar color = PERF_COLOR_MAGENTA; 725c3305257SIngo Molnar else if (ratio > 5.0) 726c3305257SIngo Molnar color = PERF_COLOR_YELLOW; 727c3305257SIngo Molnar 7284aa9015fSStephane Eranian fprintf(output, " # "); 7294aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7304aa9015fSStephane Eranian fprintf(output, " of all iTLB cache hits "); 731c3305257SIngo Molnar } 732c3305257SIngo Molnar 733c3305257SIngo Molnar static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 734c3305257SIngo Molnar { 735c3305257SIngo Molnar double total, ratio = 0.0; 736c3305257SIngo Molnar const char *color; 737c3305257SIngo Molnar 738c3305257SIngo Molnar total = avg_stats(&runtime_ll_cache_stats[cpu]); 739c3305257SIngo Molnar 740c3305257SIngo Molnar if (total) 741c3305257SIngo Molnar ratio = avg / total * 100.0; 742c3305257SIngo Molnar 743c3305257SIngo Molnar color = PERF_COLOR_NORMAL; 744c3305257SIngo Molnar if (ratio > 20.0) 745c3305257SIngo Molnar color = PERF_COLOR_RED; 746c3305257SIngo Molnar else if (ratio > 10.0) 747c3305257SIngo Molnar color = PERF_COLOR_MAGENTA; 748c3305257SIngo Molnar else if (ratio > 5.0) 749c3305257SIngo Molnar color = PERF_COLOR_YELLOW; 750c3305257SIngo Molnar 7514aa9015fSStephane Eranian fprintf(output, " # "); 7524aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7534aa9015fSStephane Eranian fprintf(output, " of all LL-cache hits "); 754c3305257SIngo Molnar } 755c3305257SIngo Molnar 756daec78a0SArnaldo Carvalho de Melo static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) 75742202dd5SIngo Molnar { 758c7f7fea3SIngo Molnar double total, ratio = 0.0; 759f5b4a9c3SStephane Eranian char cpustr[16] = { '\0', }; 760d7470b6aSStephane Eranian const char *fmt; 761d7470b6aSStephane Eranian 762d7470b6aSStephane Eranian if (csv_output) 763d7470b6aSStephane Eranian fmt = "%s%.0f%s%s"; 764d7470b6aSStephane Eranian else if (big_num) 7652cba3ffbSIngo Molnar fmt = "%s%'18.0f%s%-25s"; 766d7470b6aSStephane Eranian else 7672cba3ffbSIngo Molnar fmt = "%s%18.0f%s%-25s"; 768f5b4a9c3SStephane Eranian 769f5b4a9c3SStephane Eranian if (no_aggr) 770d7470b6aSStephane Eranian sprintf(cpustr, "CPU%*d%s", 771d7470b6aSStephane Eranian csv_output ? 0 : -4, 7727e2ed097SArnaldo Carvalho de Melo evsel_list->cpus->map[cpu], csv_sep); 773f5b4a9c3SStephane Eranian else 774f5b4a9c3SStephane Eranian cpu = 0; 775c7f7fea3SIngo Molnar 7764aa9015fSStephane Eranian fprintf(output, fmt, cpustr, avg, csv_sep, event_name(evsel)); 777d7470b6aSStephane Eranian 778023695d9SStephane Eranian if (evsel->cgrp) 7794aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 780023695d9SStephane Eranian 781d7470b6aSStephane Eranian if (csv_output) 782d7470b6aSStephane Eranian return; 78342202dd5SIngo Molnar 784daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 785f5b4a9c3SStephane Eranian total = avg_stats(&runtime_cycles_stats[cpu]); 786c7f7fea3SIngo Molnar 787c7f7fea3SIngo Molnar if (total) 788c7f7fea3SIngo Molnar ratio = avg / total; 789c7f7fea3SIngo Molnar 7904aa9015fSStephane Eranian fprintf(output, " # %5.2f insns per cycle ", ratio); 791481f988aSIngo Molnar 792d3d1e86dSIngo Molnar total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]); 793d3d1e86dSIngo Molnar total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu])); 794481f988aSIngo Molnar 795481f988aSIngo Molnar if (total && avg) { 796481f988aSIngo Molnar ratio = total / avg; 7974aa9015fSStephane Eranian fprintf(output, "\n # %5.2f stalled cycles per insn", ratio); 798481f988aSIngo Molnar } 799481f988aSIngo Molnar 800daec78a0SArnaldo Carvalho de Melo } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 801f5b4a9c3SStephane Eranian runtime_branches_stats[cpu].n != 0) { 802c78df6c1SIngo Molnar print_branch_misses(cpu, evsel, avg); 8038bb6c79fSIngo Molnar } else if ( 8048bb6c79fSIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 8058bb6c79fSIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D | 8068bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 8078bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 808c6264defSIngo Molnar runtime_l1_dcache_stats[cpu].n != 0) { 8098bb6c79fSIngo Molnar print_l1_dcache_misses(cpu, evsel, avg); 810c3305257SIngo Molnar } else if ( 811c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 812c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I | 813c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 814c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 815c3305257SIngo Molnar runtime_l1_icache_stats[cpu].n != 0) { 816c3305257SIngo Molnar print_l1_icache_misses(cpu, evsel, avg); 817c3305257SIngo Molnar } else if ( 818c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 819c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB | 820c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 821c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 822c3305257SIngo Molnar runtime_dtlb_cache_stats[cpu].n != 0) { 823c3305257SIngo Molnar print_dtlb_cache_misses(cpu, evsel, avg); 824c3305257SIngo Molnar } else if ( 825c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 826c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB | 827c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 828c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 829c3305257SIngo Molnar runtime_itlb_cache_stats[cpu].n != 0) { 830c3305257SIngo Molnar print_itlb_cache_misses(cpu, evsel, avg); 831c3305257SIngo Molnar } else if ( 832c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 833c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL | 834c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 835c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 836c3305257SIngo Molnar runtime_ll_cache_stats[cpu].n != 0) { 837c3305257SIngo Molnar print_ll_cache_misses(cpu, evsel, avg); 838d58f4c82SIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) && 839d58f4c82SIngo Molnar runtime_cacherefs_stats[cpu].n != 0) { 840d58f4c82SIngo Molnar total = avg_stats(&runtime_cacherefs_stats[cpu]); 841d58f4c82SIngo Molnar 842d58f4c82SIngo Molnar if (total) 843d58f4c82SIngo Molnar ratio = avg * 100 / total; 844d58f4c82SIngo Molnar 8454aa9015fSStephane Eranian fprintf(output, " # %8.3f %% of all cache refs ", ratio); 846d58f4c82SIngo Molnar 847d3d1e86dSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 848d3d1e86dSIngo Molnar print_stalled_cycles_frontend(cpu, evsel, avg); 849129c04cbSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) { 850d3d1e86dSIngo Molnar print_stalled_cycles_backend(cpu, evsel, avg); 851481f988aSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) { 852481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 853481f988aSIngo Molnar 854481f988aSIngo Molnar if (total) 855481f988aSIngo Molnar ratio = 1.0 * avg / total; 856481f988aSIngo Molnar 8574aa9015fSStephane Eranian fprintf(output, " # %8.3f GHz ", ratio); 858481f988aSIngo Molnar } else if (runtime_nsecs_stats[cpu].n != 0) { 859481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 860481f988aSIngo Molnar 861481f988aSIngo Molnar if (total) 862481f988aSIngo Molnar ratio = 1000.0 * avg / total; 863481f988aSIngo Molnar 8644aa9015fSStephane Eranian fprintf(output, " # %8.3f M/sec ", ratio); 865a5d243d0SIngo Molnar } else { 8664aa9015fSStephane Eranian fprintf(output, " "); 86742202dd5SIngo Molnar } 86842202dd5SIngo Molnar } 86942202dd5SIngo Molnar 87042202dd5SIngo Molnar /* 87142202dd5SIngo Molnar * Print out the results of a single counter: 872f5b4a9c3SStephane Eranian * aggregated counts in system-wide mode 87342202dd5SIngo Molnar */ 87469aad6f1SArnaldo Carvalho de Melo static void print_counter_aggr(struct perf_evsel *counter) 87542202dd5SIngo Molnar { 87669aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 87769aad6f1SArnaldo Carvalho de Melo double avg = avg_stats(&ps->res_stats[0]); 878c52b12edSArnaldo Carvalho de Melo int scaled = counter->counts->scaled; 87942202dd5SIngo Molnar 88042202dd5SIngo Molnar if (scaled == -1) { 8814aa9015fSStephane Eranian fprintf(output, "%*s%s%*s", 882d7470b6aSStephane Eranian csv_output ? 0 : 18, 8832cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 884023695d9SStephane Eranian csv_sep, 885023695d9SStephane Eranian csv_output ? 0 : -24, 886023695d9SStephane Eranian event_name(counter)); 887023695d9SStephane Eranian 888023695d9SStephane Eranian if (counter->cgrp) 8894aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, counter->cgrp->name); 890023695d9SStephane Eranian 8914aa9015fSStephane Eranian fputc('\n', output); 89242202dd5SIngo Molnar return; 89342202dd5SIngo Molnar } 89442202dd5SIngo Molnar 89542202dd5SIngo Molnar if (nsec_counter(counter)) 896f5b4a9c3SStephane Eranian nsec_printout(-1, counter, avg); 89742202dd5SIngo Molnar else 898f5b4a9c3SStephane Eranian abs_printout(-1, counter, avg); 899849abde9SPeter Zijlstra 9003ae9a34dSZhengyu He print_noise(counter, avg); 9013ae9a34dSZhengyu He 902d7470b6aSStephane Eranian if (csv_output) { 9034aa9015fSStephane Eranian fputc('\n', output); 904d7470b6aSStephane Eranian return; 905d7470b6aSStephane Eranian } 906d7470b6aSStephane Eranian 907506d4bc8SPeter Zijlstra if (scaled) { 908506d4bc8SPeter Zijlstra double avg_enabled, avg_running; 909506d4bc8SPeter Zijlstra 91069aad6f1SArnaldo Carvalho de Melo avg_enabled = avg_stats(&ps->res_stats[1]); 91169aad6f1SArnaldo Carvalho de Melo avg_running = avg_stats(&ps->res_stats[2]); 912506d4bc8SPeter Zijlstra 9134aa9015fSStephane Eranian fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled); 914506d4bc8SPeter Zijlstra } 9154aa9015fSStephane Eranian fprintf(output, "\n"); 91642202dd5SIngo Molnar } 91742202dd5SIngo Molnar 918f5b4a9c3SStephane Eranian /* 919f5b4a9c3SStephane Eranian * Print out the results of a single counter: 920f5b4a9c3SStephane Eranian * does not use aggregated count in system-wide 921f5b4a9c3SStephane Eranian */ 92269aad6f1SArnaldo Carvalho de Melo static void print_counter(struct perf_evsel *counter) 923f5b4a9c3SStephane Eranian { 924f5b4a9c3SStephane Eranian u64 ena, run, val; 925f5b4a9c3SStephane Eranian int cpu; 926f5b4a9c3SStephane Eranian 9277e2ed097SArnaldo Carvalho de Melo for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) { 928c52b12edSArnaldo Carvalho de Melo val = counter->counts->cpu[cpu].val; 929c52b12edSArnaldo Carvalho de Melo ena = counter->counts->cpu[cpu].ena; 930c52b12edSArnaldo Carvalho de Melo run = counter->counts->cpu[cpu].run; 931f5b4a9c3SStephane Eranian if (run == 0 || ena == 0) { 9324aa9015fSStephane Eranian fprintf(output, "CPU%*d%s%*s%s%*s", 933d7470b6aSStephane Eranian csv_output ? 0 : -4, 9347e2ed097SArnaldo Carvalho de Melo evsel_list->cpus->map[cpu], csv_sep, 935d7470b6aSStephane Eranian csv_output ? 0 : 18, 9362cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 9372cee77c4SDavid Ahern csv_sep, 938023695d9SStephane Eranian csv_output ? 0 : -24, 939d7470b6aSStephane Eranian event_name(counter)); 940f5b4a9c3SStephane Eranian 941023695d9SStephane Eranian if (counter->cgrp) 9424aa9015fSStephane Eranian fprintf(output, "%s%s", 9434aa9015fSStephane Eranian csv_sep, counter->cgrp->name); 944023695d9SStephane Eranian 9454aa9015fSStephane Eranian fputc('\n', output); 946f5b4a9c3SStephane Eranian continue; 947f5b4a9c3SStephane Eranian } 948f5b4a9c3SStephane Eranian 949f5b4a9c3SStephane Eranian if (nsec_counter(counter)) 950f5b4a9c3SStephane Eranian nsec_printout(cpu, counter, val); 951f5b4a9c3SStephane Eranian else 952f5b4a9c3SStephane Eranian abs_printout(cpu, counter, val); 953f5b4a9c3SStephane Eranian 954d7470b6aSStephane Eranian if (!csv_output) { 955f5b4a9c3SStephane Eranian print_noise(counter, 1.0); 956f5b4a9c3SStephane Eranian 957c6264defSIngo Molnar if (run != ena) 9584aa9015fSStephane Eranian fprintf(output, " (%.2f%%)", 9594aa9015fSStephane Eranian 100.0 * run / ena); 960d7470b6aSStephane Eranian } 9614aa9015fSStephane Eranian fputc('\n', output); 962f5b4a9c3SStephane Eranian } 963f5b4a9c3SStephane Eranian } 964f5b4a9c3SStephane Eranian 96542202dd5SIngo Molnar static void print_stat(int argc, const char **argv) 96642202dd5SIngo Molnar { 96769aad6f1SArnaldo Carvalho de Melo struct perf_evsel *counter; 96869aad6f1SArnaldo Carvalho de Melo int i; 96942202dd5SIngo Molnar 97086470930SIngo Molnar fflush(stdout); 97186470930SIngo Molnar 972d7470b6aSStephane Eranian if (!csv_output) { 9734aa9015fSStephane Eranian fprintf(output, "\n"); 9744aa9015fSStephane Eranian fprintf(output, " Performance counter stats for "); 975d6d901c2SZhang, Yanmin if(target_pid == -1 && target_tid == -1) { 9764aa9015fSStephane Eranian fprintf(output, "\'%s", argv[0]); 97786470930SIngo Molnar for (i = 1; i < argc; i++) 9784aa9015fSStephane Eranian fprintf(output, " %s", argv[i]); 979d6d901c2SZhang, Yanmin } else if (target_pid != -1) 9804aa9015fSStephane Eranian fprintf(output, "process id \'%d", target_pid); 981d6d901c2SZhang, Yanmin else 9824aa9015fSStephane Eranian fprintf(output, "thread id \'%d", target_tid); 98386470930SIngo Molnar 9844aa9015fSStephane Eranian fprintf(output, "\'"); 98542202dd5SIngo Molnar if (run_count > 1) 9864aa9015fSStephane Eranian fprintf(output, " (%d runs)", run_count); 9874aa9015fSStephane Eranian fprintf(output, ":\n\n"); 988d7470b6aSStephane Eranian } 98986470930SIngo Molnar 990f5b4a9c3SStephane Eranian if (no_aggr) { 991361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) 99286470930SIngo Molnar print_counter(counter); 993f5b4a9c3SStephane Eranian } else { 994361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) 995f5b4a9c3SStephane Eranian print_counter_aggr(counter); 996f5b4a9c3SStephane Eranian } 99786470930SIngo Molnar 998d7470b6aSStephane Eranian if (!csv_output) { 999c3305257SIngo Molnar if (!null_run) 10004aa9015fSStephane Eranian fprintf(output, "\n"); 10014aa9015fSStephane Eranian fprintf(output, " %17.9f seconds time elapsed", 1002506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)/1e9); 1003566747e6SIngo Molnar if (run_count > 1) { 10044aa9015fSStephane Eranian fprintf(output, " "); 1005f99844cbSIngo Molnar print_noise_pct(stddev_stats(&walltime_nsecs_stats), 1006506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)); 1007566747e6SIngo Molnar } 10084aa9015fSStephane Eranian fprintf(output, "\n\n"); 100986470930SIngo Molnar } 1010d7470b6aSStephane Eranian } 101186470930SIngo Molnar 1012f7b7c26eSPeter Zijlstra static volatile int signr = -1; 1013f7b7c26eSPeter Zijlstra 101486470930SIngo Molnar static void skip_signal(int signo) 101586470930SIngo Molnar { 10166be2850eSZhang, Yanmin if(child_pid == -1) 101760666c63SLiming Wang done = 1; 101860666c63SLiming Wang 1019f7b7c26eSPeter Zijlstra signr = signo; 1020f7b7c26eSPeter Zijlstra } 1021f7b7c26eSPeter Zijlstra 1022f7b7c26eSPeter Zijlstra static void sig_atexit(void) 1023f7b7c26eSPeter Zijlstra { 1024933da83aSChris Wilson if (child_pid != -1) 1025933da83aSChris Wilson kill(child_pid, SIGTERM); 1026933da83aSChris Wilson 1027f7b7c26eSPeter Zijlstra if (signr == -1) 1028f7b7c26eSPeter Zijlstra return; 1029f7b7c26eSPeter Zijlstra 1030f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 1031f7b7c26eSPeter Zijlstra kill(getpid(), signr); 103286470930SIngo Molnar } 103386470930SIngo Molnar 103486470930SIngo Molnar static const char * const stat_usage[] = { 103560666c63SLiming Wang "perf stat [<options>] [<command>]", 103686470930SIngo Molnar NULL 103786470930SIngo Molnar }; 103886470930SIngo Molnar 1039d7470b6aSStephane Eranian static int stat__set_big_num(const struct option *opt __used, 1040d7470b6aSStephane Eranian const char *s __used, int unset) 1041d7470b6aSStephane Eranian { 1042d7470b6aSStephane Eranian big_num_opt = unset ? 0 : 1; 1043d7470b6aSStephane Eranian return 0; 1044d7470b6aSStephane Eranian } 1045d7470b6aSStephane Eranian 10464aa9015fSStephane Eranian static bool append_file; 10474aa9015fSStephane Eranian 104886470930SIngo Molnar static const struct option options[] = { 1049361c99a6SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &evsel_list, "event", 105086470930SIngo Molnar "event selector. use 'perf list' to list available events", 1051f120f9d5SJiri Olsa parse_events_option), 1052cfd748aeSFrederic Weisbecker OPT_CALLBACK(0, "filter", &evsel_list, "filter", 1053cfd748aeSFrederic Weisbecker "event filter", parse_filter), 10542e6cdf99SStephane Eranian OPT_BOOLEAN('i', "no-inherit", &no_inherit, 10552e6cdf99SStephane Eranian "child tasks do not inherit counters"), 105686470930SIngo Molnar OPT_INTEGER('p', "pid", &target_pid, 1057d6d901c2SZhang, Yanmin "stat events on existing process id"), 1058d6d901c2SZhang, Yanmin OPT_INTEGER('t', "tid", &target_tid, 1059d6d901c2SZhang, Yanmin "stat events on existing thread id"), 106086470930SIngo Molnar OPT_BOOLEAN('a', "all-cpus", &system_wide, 106186470930SIngo Molnar "system-wide collection from all CPUs"), 106243bece79SLin Ming OPT_BOOLEAN('g', "group", &group, 106343bece79SLin Ming "put the counters into a counter group"), 1064b26bc5a7SBrice Goglin OPT_BOOLEAN('c', "scale", &scale, 106586470930SIngo Molnar "scale/normalize counters"), 1066c0555642SIan Munsie OPT_INCR('v', "verbose", &verbose, 1067743ee1f8SIngo Molnar "be more verbose (show counter open errors, etc)"), 106842202dd5SIngo Molnar OPT_INTEGER('r', "repeat", &run_count, 106942202dd5SIngo Molnar "repeat command and print average + stddev (max: 100)"), 10700cfb7a13SIngo Molnar OPT_BOOLEAN('n', "null", &null_run, 10710cfb7a13SIngo Molnar "null run - dont start any counters"), 10722cba3ffbSIngo Molnar OPT_INCR('d', "detailed", &detailed_run, 1073c6264defSIngo Molnar "detailed run - start a lot of events"), 1074f9cef0a9SIngo Molnar OPT_BOOLEAN('S', "sync", &sync_run, 1075f9cef0a9SIngo Molnar "call sync() before starting a run"), 1076d7470b6aSStephane Eranian OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 1077d7470b6aSStephane Eranian "print large numbers with thousands\' separators", 1078d7470b6aSStephane Eranian stat__set_big_num), 1079c45c6ea2SStephane Eranian OPT_STRING('C', "cpu", &cpu_list, "cpu", 1080c45c6ea2SStephane Eranian "list of cpus to monitor in system-wide"), 1081f5b4a9c3SStephane Eranian OPT_BOOLEAN('A', "no-aggr", &no_aggr, 1082f5b4a9c3SStephane Eranian "disable CPU count aggregation"), 1083d7470b6aSStephane Eranian OPT_STRING('x', "field-separator", &csv_sep, "separator", 1084d7470b6aSStephane Eranian "print counts with custom separator"), 1085023695d9SStephane Eranian OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1086023695d9SStephane Eranian "monitor event in cgroup name only", 1087023695d9SStephane Eranian parse_cgroups), 10884aa9015fSStephane Eranian OPT_STRING('o', "output", &output_name, "file", 10894aa9015fSStephane Eranian "output file name"), 10904aa9015fSStephane Eranian OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), 109156f3bae7SJim Cromie OPT_INTEGER(0, "log-fd", &output_fd, 109256f3bae7SJim Cromie "log output to fd, instead of stderr"), 109386470930SIngo Molnar OPT_END() 109486470930SIngo Molnar }; 109586470930SIngo Molnar 10962cba3ffbSIngo Molnar /* 10972cba3ffbSIngo Molnar * Add default attributes, if there were no attributes specified or 10982cba3ffbSIngo Molnar * if -d/--detailed, -d -d or -d -d -d is used: 10992cba3ffbSIngo Molnar */ 11002cba3ffbSIngo Molnar static int add_default_attributes(void) 11012cba3ffbSIngo Molnar { 11022cba3ffbSIngo Molnar struct perf_evsel *pos; 11032cba3ffbSIngo Molnar size_t attr_nr = 0; 11042cba3ffbSIngo Molnar size_t c; 11052cba3ffbSIngo Molnar 11062cba3ffbSIngo Molnar /* Set attrs if no event is selected and !null_run: */ 11072cba3ffbSIngo Molnar if (null_run) 11082cba3ffbSIngo Molnar return 0; 11092cba3ffbSIngo Molnar 11102cba3ffbSIngo Molnar if (!evsel_list->nr_entries) { 11112cba3ffbSIngo Molnar for (c = 0; c < ARRAY_SIZE(default_attrs); c++) { 11122cba3ffbSIngo Molnar pos = perf_evsel__new(default_attrs + c, c + attr_nr); 11132cba3ffbSIngo Molnar if (pos == NULL) 11142cba3ffbSIngo Molnar return -1; 11152cba3ffbSIngo Molnar perf_evlist__add(evsel_list, pos); 11162cba3ffbSIngo Molnar } 11172cba3ffbSIngo Molnar attr_nr += c; 11182cba3ffbSIngo Molnar } 11192cba3ffbSIngo Molnar 11202cba3ffbSIngo Molnar /* Detailed events get appended to the event list: */ 11212cba3ffbSIngo Molnar 11222cba3ffbSIngo Molnar if (detailed_run < 1) 11232cba3ffbSIngo Molnar return 0; 11242cba3ffbSIngo Molnar 11252cba3ffbSIngo Molnar /* Append detailed run extra attributes: */ 11262cba3ffbSIngo Molnar for (c = 0; c < ARRAY_SIZE(detailed_attrs); c++) { 11272cba3ffbSIngo Molnar pos = perf_evsel__new(detailed_attrs + c, c + attr_nr); 11282cba3ffbSIngo Molnar if (pos == NULL) 11292cba3ffbSIngo Molnar return -1; 11302cba3ffbSIngo Molnar perf_evlist__add(evsel_list, pos); 11312cba3ffbSIngo Molnar } 11322cba3ffbSIngo Molnar attr_nr += c; 11332cba3ffbSIngo Molnar 11342cba3ffbSIngo Molnar if (detailed_run < 2) 11352cba3ffbSIngo Molnar return 0; 11362cba3ffbSIngo Molnar 11372cba3ffbSIngo Molnar /* Append very detailed run extra attributes: */ 11382cba3ffbSIngo Molnar for (c = 0; c < ARRAY_SIZE(very_detailed_attrs); c++) { 11392cba3ffbSIngo Molnar pos = perf_evsel__new(very_detailed_attrs + c, c + attr_nr); 11402cba3ffbSIngo Molnar if (pos == NULL) 11412cba3ffbSIngo Molnar return -1; 11422cba3ffbSIngo Molnar perf_evlist__add(evsel_list, pos); 11432cba3ffbSIngo Molnar } 11442cba3ffbSIngo Molnar 11452cba3ffbSIngo Molnar if (detailed_run < 3) 11462cba3ffbSIngo Molnar return 0; 11472cba3ffbSIngo Molnar 11482cba3ffbSIngo Molnar /* Append very, very detailed run extra attributes: */ 11492cba3ffbSIngo Molnar for (c = 0; c < ARRAY_SIZE(very_very_detailed_attrs); c++) { 11502cba3ffbSIngo Molnar pos = perf_evsel__new(very_very_detailed_attrs + c, c + attr_nr); 11512cba3ffbSIngo Molnar if (pos == NULL) 11522cba3ffbSIngo Molnar return -1; 11532cba3ffbSIngo Molnar perf_evlist__add(evsel_list, pos); 11542cba3ffbSIngo Molnar } 11552cba3ffbSIngo Molnar 11562cba3ffbSIngo Molnar 11572cba3ffbSIngo Molnar return 0; 11582cba3ffbSIngo Molnar } 11592cba3ffbSIngo Molnar 1160f37a291cSIngo Molnar int cmd_stat(int argc, const char **argv, const char *prefix __used) 116186470930SIngo Molnar { 116269aad6f1SArnaldo Carvalho de Melo struct perf_evsel *pos; 116369aad6f1SArnaldo Carvalho de Melo int status = -ENOMEM; 11644aa9015fSStephane Eranian const char *mode; 116542202dd5SIngo Molnar 11665af52b51SStephane Eranian setlocale(LC_ALL, ""); 11675af52b51SStephane Eranian 11687e2ed097SArnaldo Carvalho de Melo evsel_list = perf_evlist__new(NULL, NULL); 1169361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 1170361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1171361c99a6SArnaldo Carvalho de Melo 1172a0541234SAnton Blanchard argc = parse_options(argc, argv, options, stat_usage, 1173a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 1174d7470b6aSStephane Eranian 11754aa9015fSStephane Eranian output = stderr; 11764aa9015fSStephane Eranian if (output_name && strcmp(output_name, "-")) 11774aa9015fSStephane Eranian output = NULL; 11784aa9015fSStephane Eranian 117956f3bae7SJim Cromie if (output_name && output_fd) { 118056f3bae7SJim Cromie fprintf(stderr, "cannot use both --output and --log-fd\n"); 118156f3bae7SJim Cromie usage_with_options(stat_usage, options); 118256f3bae7SJim Cromie } 11834aa9015fSStephane Eranian if (!output) { 11844aa9015fSStephane Eranian struct timespec tm; 11854aa9015fSStephane Eranian mode = append_file ? "a" : "w"; 11864aa9015fSStephane Eranian 11874aa9015fSStephane Eranian output = fopen(output_name, mode); 11884aa9015fSStephane Eranian if (!output) { 11894aa9015fSStephane Eranian perror("failed to create output file"); 11904aa9015fSStephane Eranian exit(-1); 11914aa9015fSStephane Eranian } 11924aa9015fSStephane Eranian clock_gettime(CLOCK_REALTIME, &tm); 11934aa9015fSStephane Eranian fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 119456f3bae7SJim Cromie } else if (output_fd != 2) { 119556f3bae7SJim Cromie mode = append_file ? "a" : "w"; 119656f3bae7SJim Cromie output = fdopen(output_fd, mode); 119756f3bae7SJim Cromie if (!output) { 119856f3bae7SJim Cromie perror("Failed opening logfd"); 119956f3bae7SJim Cromie return -errno; 120056f3bae7SJim Cromie } 12014aa9015fSStephane Eranian } 12024aa9015fSStephane Eranian 1203d4ffd04dSJim Cromie if (csv_sep) { 1204d7470b6aSStephane Eranian csv_output = true; 1205d4ffd04dSJim Cromie if (!strcmp(csv_sep, "\\t")) 1206d4ffd04dSJim Cromie csv_sep = "\t"; 1207d4ffd04dSJim Cromie } else 1208d7470b6aSStephane Eranian csv_sep = DEFAULT_SEPARATOR; 1209d7470b6aSStephane Eranian 1210d7470b6aSStephane Eranian /* 1211d7470b6aSStephane Eranian * let the spreadsheet do the pretty-printing 1212d7470b6aSStephane Eranian */ 1213d7470b6aSStephane Eranian if (csv_output) { 121461a9f324SJim Cromie /* User explicitly passed -B? */ 1215d7470b6aSStephane Eranian if (big_num_opt == 1) { 1216d7470b6aSStephane Eranian fprintf(stderr, "-B option not supported with -x\n"); 1217d7470b6aSStephane Eranian usage_with_options(stat_usage, options); 1218d7470b6aSStephane Eranian } else /* Nope, so disable big number formatting */ 1219d7470b6aSStephane Eranian big_num = false; 1220d7470b6aSStephane Eranian } else if (big_num_opt == 0) /* User passed --no-big-num */ 1221d7470b6aSStephane Eranian big_num = false; 1222d7470b6aSStephane Eranian 1223d6d901c2SZhang, Yanmin if (!argc && target_pid == -1 && target_tid == -1) 122486470930SIngo Molnar usage_with_options(stat_usage, options); 12259e9772c4SPeter Zijlstra if (run_count <= 0) 122642202dd5SIngo Molnar usage_with_options(stat_usage, options); 122786470930SIngo Molnar 1228023695d9SStephane Eranian /* no_aggr, cgroup are for system-wide only */ 1229023695d9SStephane Eranian if ((no_aggr || nr_cgroups) && !system_wide) { 1230023695d9SStephane Eranian fprintf(stderr, "both cgroup and no-aggregation " 1231023695d9SStephane Eranian "modes only available in system-wide mode\n"); 1232023695d9SStephane Eranian 1233f5b4a9c3SStephane Eranian usage_with_options(stat_usage, options); 1234023695d9SStephane Eranian } 1235f5b4a9c3SStephane Eranian 12362cba3ffbSIngo Molnar if (add_default_attributes()) 1237c6264defSIngo Molnar goto out; 123886470930SIngo Molnar 12395c98d466SArnaldo Carvalho de Melo if (target_pid != -1) 12405c98d466SArnaldo Carvalho de Melo target_tid = target_pid; 12415c98d466SArnaldo Carvalho de Melo 12427e2ed097SArnaldo Carvalho de Melo evsel_list->threads = thread_map__new(target_pid, target_tid); 12437e2ed097SArnaldo Carvalho de Melo if (evsel_list->threads == NULL) { 12445c98d466SArnaldo Carvalho de Melo pr_err("Problems finding threads of monitor\n"); 12455c98d466SArnaldo Carvalho de Melo usage_with_options(stat_usage, options); 12465c98d466SArnaldo Carvalho de Melo } 12475c98d466SArnaldo Carvalho de Melo 1248a12b51c4SPaul Mackerras if (system_wide) 12497e2ed097SArnaldo Carvalho de Melo evsel_list->cpus = cpu_map__new(cpu_list); 1250a12b51c4SPaul Mackerras else 12517e2ed097SArnaldo Carvalho de Melo evsel_list->cpus = cpu_map__dummy_new(); 125286470930SIngo Molnar 12537e2ed097SArnaldo Carvalho de Melo if (evsel_list->cpus == NULL) { 125460d567e2SArnaldo Carvalho de Melo perror("failed to parse CPUs map"); 1255c45c6ea2SStephane Eranian usage_with_options(stat_usage, options); 125660d567e2SArnaldo Carvalho de Melo return -1; 125760d567e2SArnaldo Carvalho de Melo } 1258c45c6ea2SStephane Eranian 1259361c99a6SArnaldo Carvalho de Melo list_for_each_entry(pos, &evsel_list->entries, node) { 1260c52b12edSArnaldo Carvalho de Melo if (perf_evsel__alloc_stat_priv(pos) < 0 || 12617e2ed097SArnaldo Carvalho de Melo perf_evsel__alloc_counts(pos, evsel_list->cpus->nr) < 0 || 12627e2ed097SArnaldo Carvalho de Melo perf_evsel__alloc_fd(pos, evsel_list->cpus->nr, evsel_list->threads->nr) < 0) 126369aad6f1SArnaldo Carvalho de Melo goto out_free_fd; 1264d6d901c2SZhang, Yanmin } 1265d6d901c2SZhang, Yanmin 126686470930SIngo Molnar /* 126786470930SIngo Molnar * We dont want to block the signals - that would cause 126886470930SIngo Molnar * child tasks to inherit that and Ctrl-C would not work. 126986470930SIngo Molnar * What we want is for Ctrl-C to work in the exec()-ed 127086470930SIngo Molnar * task, but being ignored by perf stat itself: 127186470930SIngo Molnar */ 1272f7b7c26eSPeter Zijlstra atexit(sig_atexit); 127386470930SIngo Molnar signal(SIGINT, skip_signal); 127486470930SIngo Molnar signal(SIGALRM, skip_signal); 127586470930SIngo Molnar signal(SIGABRT, skip_signal); 127686470930SIngo Molnar 127742202dd5SIngo Molnar status = 0; 127842202dd5SIngo Molnar for (run_idx = 0; run_idx < run_count; run_idx++) { 127942202dd5SIngo Molnar if (run_count != 1 && verbose) 12804aa9015fSStephane Eranian fprintf(output, "[ perf stat: executing run #%d ... ]\n", 12814aa9015fSStephane Eranian run_idx + 1); 1282f9cef0a9SIngo Molnar 1283f9cef0a9SIngo Molnar if (sync_run) 1284f9cef0a9SIngo Molnar sync(); 1285f9cef0a9SIngo Molnar 128642202dd5SIngo Molnar status = run_perf_stat(argc, argv); 128742202dd5SIngo Molnar } 128842202dd5SIngo Molnar 1289084ab9f8SArnaldo Carvalho de Melo if (status != -1) 129042202dd5SIngo Molnar print_stat(argc, argv); 129169aad6f1SArnaldo Carvalho de Melo out_free_fd: 1292361c99a6SArnaldo Carvalho de Melo list_for_each_entry(pos, &evsel_list->entries, node) 129369aad6f1SArnaldo Carvalho de Melo perf_evsel__free_stat_priv(pos); 12947e2ed097SArnaldo Carvalho de Melo perf_evlist__delete_maps(evsel_list); 12950015e2e1SArnaldo Carvalho de Melo out: 12960015e2e1SArnaldo Carvalho de Melo perf_evlist__delete(evsel_list); 129742202dd5SIngo Molnar return status; 129886470930SIngo Molnar } 1299