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" 46f14d5707SArnaldo Carvalho de Melo #include "util/cgroup.h" 4786470930SIngo Molnar #include "util/util.h" 4886470930SIngo Molnar #include "util/parse-options.h" 4986470930SIngo Molnar #include "util/parse-events.h" 504cabc3d1SAndi Kleen #include "util/pmu.h" 518f28827aSFrederic Weisbecker #include "util/event.h" 52361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 5369aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 548f28827aSFrederic Weisbecker #include "util/debug.h" 55a5d243d0SIngo Molnar #include "util/color.h" 560007eceaSXiao Guangrong #include "util/stat.h" 5760666c63SLiming Wang #include "util/header.h" 58a12b51c4SPaul Mackerras #include "util/cpumap.h" 59d6d901c2SZhang, Yanmin #include "util/thread.h" 60fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 6186470930SIngo Molnar 621f16c575SPeter Zijlstra #include <stdlib.h> 6386470930SIngo Molnar #include <sys/prctl.h> 645af52b51SStephane Eranian #include <locale.h> 6586470930SIngo Molnar 66d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR " " 672cee77c4SDavid Ahern #define CNTR_NOT_SUPPORTED "<not supported>" 682cee77c4SDavid Ahern #define CNTR_NOT_COUNTED "<not counted>" 69d7470b6aSStephane Eranian 7013370a9bSStephane Eranian static void print_stat(int argc, const char **argv); 7113370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix); 7213370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix); 7386ee6e18SStephane Eranian static void print_aggr(char *prefix); 7413370a9bSStephane Eranian 754cabc3d1SAndi Kleen /* Default events used for perf stat -T */ 764cabc3d1SAndi Kleen static const char * const transaction_attrs[] = { 774cabc3d1SAndi Kleen "task-clock", 784cabc3d1SAndi Kleen "{" 794cabc3d1SAndi Kleen "instructions," 804cabc3d1SAndi Kleen "cycles," 814cabc3d1SAndi Kleen "cpu/cycles-t/," 824cabc3d1SAndi Kleen "cpu/tx-start/," 834cabc3d1SAndi Kleen "cpu/el-start/," 844cabc3d1SAndi Kleen "cpu/cycles-ct/" 854cabc3d1SAndi Kleen "}" 864cabc3d1SAndi Kleen }; 874cabc3d1SAndi Kleen 884cabc3d1SAndi Kleen /* More limited version when the CPU does not have all events. */ 894cabc3d1SAndi Kleen static const char * const transaction_limited_attrs[] = { 904cabc3d1SAndi Kleen "task-clock", 914cabc3d1SAndi Kleen "{" 924cabc3d1SAndi Kleen "instructions," 934cabc3d1SAndi Kleen "cycles," 944cabc3d1SAndi Kleen "cpu/cycles-t/," 954cabc3d1SAndi Kleen "cpu/tx-start/" 964cabc3d1SAndi Kleen "}" 974cabc3d1SAndi Kleen }; 984cabc3d1SAndi Kleen 994cabc3d1SAndi Kleen /* must match transaction_attrs and the beginning limited_attrs */ 1004cabc3d1SAndi Kleen enum { 1014cabc3d1SAndi Kleen T_TASK_CLOCK, 1024cabc3d1SAndi Kleen T_INSTRUCTIONS, 1034cabc3d1SAndi Kleen T_CYCLES, 1044cabc3d1SAndi Kleen T_CYCLES_IN_TX, 1054cabc3d1SAndi Kleen T_TRANSACTION_START, 1064cabc3d1SAndi Kleen T_ELISION_START, 1074cabc3d1SAndi Kleen T_CYCLES_IN_TX_CP, 1084cabc3d1SAndi Kleen }; 1094cabc3d1SAndi Kleen 110666e6d48SRobert Richter static struct perf_evlist *evsel_list; 111361c99a6SArnaldo Carvalho de Melo 112602ad878SArnaldo Carvalho de Melo static struct target target = { 11377a6f014SNamhyung Kim .uid = UINT_MAX, 11477a6f014SNamhyung Kim }; 11542202dd5SIngo Molnar 11686ee6e18SStephane Eranian enum aggr_mode { 11786ee6e18SStephane Eranian AGGR_NONE, 11886ee6e18SStephane Eranian AGGR_GLOBAL, 11986ee6e18SStephane Eranian AGGR_SOCKET, 12012c08a9fSStephane Eranian AGGR_CORE, 12186ee6e18SStephane Eranian }; 12286ee6e18SStephane Eranian 1233d632595SJaswinder Singh Rajput static int run_count = 1; 1242e6cdf99SStephane Eranian static bool no_inherit = false; 125c0555642SIan Munsie static bool scale = true; 12686ee6e18SStephane Eranian static enum aggr_mode aggr_mode = AGGR_GLOBAL; 127d07f0b12SStephane Eranian static volatile pid_t child_pid = -1; 128c0555642SIan Munsie static bool null_run = false; 1292cba3ffbSIngo Molnar static int detailed_run = 0; 1304cabc3d1SAndi Kleen static bool transaction_run; 131201e0b06SArnaldo Carvalho de Melo static bool big_num = true; 132d7470b6aSStephane Eranian static int big_num_opt = -1; 133d7470b6aSStephane Eranian static const char *csv_sep = NULL; 134d7470b6aSStephane Eranian static bool csv_output = false; 13543bece79SLin Ming static bool group = false; 1364aa9015fSStephane Eranian static FILE *output = NULL; 1371f16c575SPeter Zijlstra static const char *pre_cmd = NULL; 1381f16c575SPeter Zijlstra static const char *post_cmd = NULL; 1391f16c575SPeter Zijlstra static bool sync_run = false; 14013370a9bSStephane Eranian static unsigned int interval = 0; 14141191688SAndi Kleen static unsigned int initial_delay = 0; 142410136f5SStephane Eranian static unsigned int unit_width = 4; /* strlen("unit") */ 143a7e191c3SFrederik Deweerdt static bool forever = false; 14413370a9bSStephane Eranian static struct timespec ref_time; 14586ee6e18SStephane Eranian static struct cpu_map *aggr_map; 14686ee6e18SStephane Eranian static int (*aggr_get_id)(struct cpu_map *m, int cpu); 1475af52b51SStephane Eranian 14860666c63SLiming Wang static volatile int done = 0; 14960666c63SLiming Wang 15069aad6f1SArnaldo Carvalho de Melo struct perf_stat { 15169aad6f1SArnaldo Carvalho de Melo struct stats res_stats[3]; 15269aad6f1SArnaldo Carvalho de Melo }; 15369aad6f1SArnaldo Carvalho de Melo 15413370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a, 15513370a9bSStephane Eranian struct timespec *b) 15613370a9bSStephane Eranian { 15713370a9bSStephane Eranian r->tv_sec = a->tv_sec - b->tv_sec; 15813370a9bSStephane Eranian if (a->tv_nsec < b->tv_nsec) { 15913370a9bSStephane Eranian r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec; 16013370a9bSStephane Eranian r->tv_sec--; 16113370a9bSStephane Eranian } else { 16213370a9bSStephane Eranian r->tv_nsec = a->tv_nsec - b->tv_nsec ; 16313370a9bSStephane Eranian } 16413370a9bSStephane Eranian } 16513370a9bSStephane Eranian 16613370a9bSStephane Eranian static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) 16713370a9bSStephane Eranian { 16813370a9bSStephane Eranian return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus; 16913370a9bSStephane Eranian } 17013370a9bSStephane Eranian 17113370a9bSStephane Eranian static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) 17213370a9bSStephane Eranian { 17313370a9bSStephane Eranian return perf_evsel__cpus(evsel)->nr; 17413370a9bSStephane Eranian } 17513370a9bSStephane Eranian 176a7e191c3SFrederik Deweerdt static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) 177a7e191c3SFrederik Deweerdt { 17890f6bb6cSAndi Kleen int i; 17990f6bb6cSAndi Kleen struct perf_stat *ps = evsel->priv; 18090f6bb6cSAndi Kleen 18190f6bb6cSAndi Kleen for (i = 0; i < 3; i++) 18290f6bb6cSAndi Kleen init_stats(&ps->res_stats[i]); 183a7e191c3SFrederik Deweerdt } 184a7e191c3SFrederik Deweerdt 185c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) 18669aad6f1SArnaldo Carvalho de Melo { 187c52b12edSArnaldo Carvalho de Melo evsel->priv = zalloc(sizeof(struct perf_stat)); 188d180ac14SJiri Olsa if (evsel->priv == NULL) 18990f6bb6cSAndi Kleen return -ENOMEM; 19090f6bb6cSAndi Kleen perf_evsel__reset_stat_priv(evsel); 19190f6bb6cSAndi Kleen return 0; 19269aad6f1SArnaldo Carvalho de Melo } 19369aad6f1SArnaldo Carvalho de Melo 19469aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) 19569aad6f1SArnaldo Carvalho de Melo { 19604662523SArnaldo Carvalho de Melo zfree(&evsel->priv); 19769aad6f1SArnaldo Carvalho de Melo } 19869aad6f1SArnaldo Carvalho de Melo 19913370a9bSStephane Eranian static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) 2007ae92e74SYan, Zheng { 20113370a9bSStephane Eranian void *addr; 20213370a9bSStephane Eranian size_t sz; 20313370a9bSStephane Eranian 20413370a9bSStephane Eranian sz = sizeof(*evsel->counts) + 20513370a9bSStephane Eranian (perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values)); 20613370a9bSStephane Eranian 20713370a9bSStephane Eranian addr = zalloc(sz); 20813370a9bSStephane Eranian if (!addr) 20913370a9bSStephane Eranian return -ENOMEM; 21013370a9bSStephane Eranian 21113370a9bSStephane Eranian evsel->prev_raw_counts = addr; 21213370a9bSStephane Eranian 21313370a9bSStephane Eranian return 0; 2147ae92e74SYan, Zheng } 2157ae92e74SYan, Zheng 21613370a9bSStephane Eranian static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) 2177ae92e74SYan, Zheng { 21804662523SArnaldo Carvalho de Melo zfree(&evsel->prev_raw_counts); 2197ae92e74SYan, Zheng } 2207ae92e74SYan, Zheng 221d134ffb9SArnaldo Carvalho de Melo static void perf_evlist__free_stats(struct perf_evlist *evlist) 222d134ffb9SArnaldo Carvalho de Melo { 223d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 224d134ffb9SArnaldo Carvalho de Melo 2250050f7aaSArnaldo Carvalho de Melo evlist__for_each(evlist, evsel) { 226d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_stat_priv(evsel); 227d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_counts(evsel); 228d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_prev_raw_counts(evsel); 229d134ffb9SArnaldo Carvalho de Melo } 230d134ffb9SArnaldo Carvalho de Melo } 231d134ffb9SArnaldo Carvalho de Melo 232d134ffb9SArnaldo Carvalho de Melo static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw) 233d134ffb9SArnaldo Carvalho de Melo { 234d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 235d134ffb9SArnaldo Carvalho de Melo 2360050f7aaSArnaldo Carvalho de Melo evlist__for_each(evlist, evsel) { 237d134ffb9SArnaldo Carvalho de Melo if (perf_evsel__alloc_stat_priv(evsel) < 0 || 238d134ffb9SArnaldo Carvalho de Melo perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 || 239d134ffb9SArnaldo Carvalho de Melo (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0)) 240d134ffb9SArnaldo Carvalho de Melo goto out_free; 241d134ffb9SArnaldo Carvalho de Melo } 242d134ffb9SArnaldo Carvalho de Melo 243d134ffb9SArnaldo Carvalho de Melo return 0; 244d134ffb9SArnaldo Carvalho de Melo 245d134ffb9SArnaldo Carvalho de Melo out_free: 246d134ffb9SArnaldo Carvalho de Melo perf_evlist__free_stats(evlist); 247d134ffb9SArnaldo Carvalho de Melo return -1; 248d134ffb9SArnaldo Carvalho de Melo } 249d134ffb9SArnaldo Carvalho de Melo 250666e6d48SRobert Richter static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 251666e6d48SRobert Richter static struct stats runtime_cycles_stats[MAX_NR_CPUS]; 252666e6d48SRobert Richter static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS]; 253666e6d48SRobert Richter static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS]; 254666e6d48SRobert Richter static struct stats runtime_branches_stats[MAX_NR_CPUS]; 255666e6d48SRobert Richter static struct stats runtime_cacherefs_stats[MAX_NR_CPUS]; 256666e6d48SRobert Richter static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS]; 257666e6d48SRobert Richter static struct stats runtime_l1_icache_stats[MAX_NR_CPUS]; 258666e6d48SRobert Richter static struct stats runtime_ll_cache_stats[MAX_NR_CPUS]; 259666e6d48SRobert Richter static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; 260666e6d48SRobert Richter static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; 2614cabc3d1SAndi Kleen static struct stats runtime_cycles_in_tx_stats[MAX_NR_CPUS]; 262666e6d48SRobert Richter static struct stats walltime_nsecs_stats; 2634cabc3d1SAndi Kleen static struct stats runtime_transaction_stats[MAX_NR_CPUS]; 2644cabc3d1SAndi Kleen static struct stats runtime_elision_stats[MAX_NR_CPUS]; 26586470930SIngo Molnar 266d134ffb9SArnaldo Carvalho de Melo static void perf_stat__reset_stats(struct perf_evlist *evlist) 267a7e191c3SFrederik Deweerdt { 268d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 269d134ffb9SArnaldo Carvalho de Melo 2700050f7aaSArnaldo Carvalho de Melo evlist__for_each(evlist, evsel) { 271d134ffb9SArnaldo Carvalho de Melo perf_evsel__reset_stat_priv(evsel); 272d134ffb9SArnaldo Carvalho de Melo perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel)); 273d134ffb9SArnaldo Carvalho de Melo } 274d134ffb9SArnaldo Carvalho de Melo 275a7e191c3SFrederik Deweerdt memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats)); 276a7e191c3SFrederik Deweerdt memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats)); 277a7e191c3SFrederik Deweerdt memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats)); 278a7e191c3SFrederik Deweerdt memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats)); 279a7e191c3SFrederik Deweerdt memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats)); 280a7e191c3SFrederik Deweerdt memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats)); 281a7e191c3SFrederik Deweerdt memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats)); 282a7e191c3SFrederik Deweerdt memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats)); 283a7e191c3SFrederik Deweerdt memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats)); 284a7e191c3SFrederik Deweerdt memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats)); 285a7e191c3SFrederik Deweerdt memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats)); 2864cabc3d1SAndi Kleen memset(runtime_cycles_in_tx_stats, 0, 2874cabc3d1SAndi Kleen sizeof(runtime_cycles_in_tx_stats)); 2884cabc3d1SAndi Kleen memset(runtime_transaction_stats, 0, 2894cabc3d1SAndi Kleen sizeof(runtime_transaction_stats)); 2904cabc3d1SAndi Kleen memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats)); 291a7e191c3SFrederik Deweerdt memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats)); 292a7e191c3SFrederik Deweerdt } 293a7e191c3SFrederik Deweerdt 294cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel) 29586470930SIngo Molnar { 29669aad6f1SArnaldo Carvalho de Melo struct perf_event_attr *attr = &evsel->attr; 297727ab04eSArnaldo Carvalho de Melo 29886470930SIngo Molnar if (scale) 29986470930SIngo Molnar attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 30086470930SIngo Molnar PERF_FORMAT_TOTAL_TIME_RUNNING; 30186470930SIngo Molnar 3022e6cdf99SStephane Eranian attr->inherit = !no_inherit; 3035d2cd909SArnaldo Carvalho de Melo 304602ad878SArnaldo Carvalho de Melo if (target__has_cpu(&target)) 305594ac61aSArnaldo Carvalho de Melo return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); 3065622c07bSStephane Eranian 307602ad878SArnaldo Carvalho de Melo if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) { 30886470930SIngo Molnar attr->disabled = 1; 30941191688SAndi Kleen if (!initial_delay) 31057e7986eSPaul Mackerras attr->enable_on_exec = 1; 3116be2850eSZhang, Yanmin } 312084ab9f8SArnaldo Carvalho de Melo 313594ac61aSArnaldo Carvalho de Melo return perf_evsel__open_per_thread(evsel, evsel_list->threads); 31486470930SIngo Molnar } 31586470930SIngo Molnar 31686470930SIngo Molnar /* 31786470930SIngo Molnar * Does the counter have nsecs as a unit? 31886470930SIngo Molnar */ 319daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel) 32086470930SIngo Molnar { 321daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || 322daec78a0SArnaldo Carvalho de Melo perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 32386470930SIngo Molnar return 1; 32486470930SIngo Molnar 32586470930SIngo Molnar return 0; 32686470930SIngo Molnar } 32786470930SIngo Molnar 3284cabc3d1SAndi Kleen static struct perf_evsel *nth_evsel(int n) 3294cabc3d1SAndi Kleen { 3304cabc3d1SAndi Kleen static struct perf_evsel **array; 3314cabc3d1SAndi Kleen static int array_len; 3324cabc3d1SAndi Kleen struct perf_evsel *ev; 3334cabc3d1SAndi Kleen int j; 3344cabc3d1SAndi Kleen 3354cabc3d1SAndi Kleen /* Assumes this only called when evsel_list does not change anymore. */ 3364cabc3d1SAndi Kleen if (!array) { 3370050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, ev) 3384cabc3d1SAndi Kleen array_len++; 3394cabc3d1SAndi Kleen array = malloc(array_len * sizeof(void *)); 3404cabc3d1SAndi Kleen if (!array) 3414cabc3d1SAndi Kleen exit(ENOMEM); 3424cabc3d1SAndi Kleen j = 0; 3430050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, ev) 3444cabc3d1SAndi Kleen array[j++] = ev; 3454cabc3d1SAndi Kleen } 3464cabc3d1SAndi Kleen if (n < array_len) 3474cabc3d1SAndi Kleen return array[n]; 3484cabc3d1SAndi Kleen return NULL; 3494cabc3d1SAndi Kleen } 3504cabc3d1SAndi Kleen 35186470930SIngo Molnar /* 352dcd9936aSIngo Molnar * Update various tracking values we maintain to print 353dcd9936aSIngo Molnar * more semantic information such as miss/hit ratios, 354dcd9936aSIngo Molnar * instruction rates, etc: 355dcd9936aSIngo Molnar */ 356dcd9936aSIngo Molnar static void update_shadow_stats(struct perf_evsel *counter, u64 *count) 357dcd9936aSIngo Molnar { 358dcd9936aSIngo Molnar if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 359dcd9936aSIngo Molnar update_stats(&runtime_nsecs_stats[0], count[0]); 360dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 361dcd9936aSIngo Molnar update_stats(&runtime_cycles_stats[0], count[0]); 3624cabc3d1SAndi Kleen else if (transaction_run && 3634cabc3d1SAndi Kleen perf_evsel__cmp(counter, nth_evsel(T_CYCLES_IN_TX))) 3644cabc3d1SAndi Kleen update_stats(&runtime_cycles_in_tx_stats[0], count[0]); 3654cabc3d1SAndi Kleen else if (transaction_run && 3664cabc3d1SAndi Kleen perf_evsel__cmp(counter, nth_evsel(T_TRANSACTION_START))) 3674cabc3d1SAndi Kleen update_stats(&runtime_transaction_stats[0], count[0]); 3684cabc3d1SAndi Kleen else if (transaction_run && 3694cabc3d1SAndi Kleen perf_evsel__cmp(counter, nth_evsel(T_ELISION_START))) 3704cabc3d1SAndi Kleen update_stats(&runtime_elision_stats[0], count[0]); 371d3d1e86dSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) 372d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_front_stats[0], count[0]); 373129c04cbSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) 374d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_back_stats[0], count[0]); 375dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS)) 376dcd9936aSIngo Molnar update_stats(&runtime_branches_stats[0], count[0]); 377dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES)) 378dcd9936aSIngo Molnar update_stats(&runtime_cacherefs_stats[0], count[0]); 3798bb6c79fSIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D)) 3808bb6c79fSIngo Molnar update_stats(&runtime_l1_dcache_stats[0], count[0]); 381c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I)) 382c3305257SIngo Molnar update_stats(&runtime_l1_icache_stats[0], count[0]); 383c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL)) 384c3305257SIngo Molnar update_stats(&runtime_ll_cache_stats[0], count[0]); 385c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB)) 386c3305257SIngo Molnar update_stats(&runtime_dtlb_cache_stats[0], count[0]); 387c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) 388c3305257SIngo Molnar update_stats(&runtime_itlb_cache_stats[0], count[0]); 389dcd9936aSIngo Molnar } 390dcd9936aSIngo Molnar 391779d0b99SJiri Olsa static void zero_per_pkg(struct perf_evsel *counter) 392779d0b99SJiri Olsa { 393779d0b99SJiri Olsa if (counter->per_pkg_mask) 394779d0b99SJiri Olsa memset(counter->per_pkg_mask, 0, MAX_NR_CPUS); 395779d0b99SJiri Olsa } 396779d0b99SJiri Olsa 397779d0b99SJiri Olsa static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip) 398779d0b99SJiri Olsa { 399779d0b99SJiri Olsa unsigned long *mask = counter->per_pkg_mask; 400779d0b99SJiri Olsa struct cpu_map *cpus = perf_evsel__cpus(counter); 401779d0b99SJiri Olsa int s; 402779d0b99SJiri Olsa 403779d0b99SJiri Olsa *skip = false; 404779d0b99SJiri Olsa 405779d0b99SJiri Olsa if (!counter->per_pkg) 406779d0b99SJiri Olsa return 0; 407779d0b99SJiri Olsa 408779d0b99SJiri Olsa if (cpu_map__empty(cpus)) 409779d0b99SJiri Olsa return 0; 410779d0b99SJiri Olsa 411779d0b99SJiri Olsa if (!mask) { 412779d0b99SJiri Olsa mask = zalloc(MAX_NR_CPUS); 413779d0b99SJiri Olsa if (!mask) 414779d0b99SJiri Olsa return -ENOMEM; 415779d0b99SJiri Olsa 416779d0b99SJiri Olsa counter->per_pkg_mask = mask; 417779d0b99SJiri Olsa } 418779d0b99SJiri Olsa 419779d0b99SJiri Olsa s = cpu_map__get_socket(cpus, cpu); 420779d0b99SJiri Olsa if (s < 0) 421779d0b99SJiri Olsa return -1; 422779d0b99SJiri Olsa 423779d0b99SJiri Olsa *skip = test_and_set_bit(s, mask) == 1; 424779d0b99SJiri Olsa return 0; 425779d0b99SJiri Olsa } 426779d0b99SJiri Olsa 427060c4f9cSJiri Olsa static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused, 428060c4f9cSJiri Olsa struct perf_counts_values *count) 429060c4f9cSJiri Olsa { 4301971f59fSJiri Olsa struct perf_counts_values *aggr = &evsel->counts->aggr; 431779d0b99SJiri Olsa static struct perf_counts_values zero; 432779d0b99SJiri Olsa bool skip = false; 433779d0b99SJiri Olsa 434779d0b99SJiri Olsa if (check_per_pkg(evsel, cpu, &skip)) { 435779d0b99SJiri Olsa pr_err("failed to read per-pkg counter\n"); 436779d0b99SJiri Olsa return -1; 437779d0b99SJiri Olsa } 438779d0b99SJiri Olsa 439779d0b99SJiri Olsa if (skip) 440779d0b99SJiri Olsa count = &zero; 4411971f59fSJiri Olsa 442060c4f9cSJiri Olsa switch (aggr_mode) { 443060c4f9cSJiri Olsa case AGGR_CORE: 444060c4f9cSJiri Olsa case AGGR_SOCKET: 445060c4f9cSJiri Olsa case AGGR_NONE: 4466c0345b7SJiri Olsa if (!evsel->snapshot) 447060c4f9cSJiri Olsa perf_evsel__compute_deltas(evsel, cpu, count); 448060c4f9cSJiri Olsa perf_counts_values__scale(count, scale, NULL); 449060c4f9cSJiri Olsa evsel->counts->cpu[cpu] = *count; 450060c4f9cSJiri Olsa update_shadow_stats(evsel, count->values); 451060c4f9cSJiri Olsa break; 452060c4f9cSJiri Olsa case AGGR_GLOBAL: 4531971f59fSJiri Olsa aggr->val += count->val; 4541971f59fSJiri Olsa if (scale) { 4551971f59fSJiri Olsa aggr->ena += count->ena; 4561971f59fSJiri Olsa aggr->run += count->run; 4571971f59fSJiri Olsa } 458060c4f9cSJiri Olsa default: 459060c4f9cSJiri Olsa break; 460060c4f9cSJiri Olsa } 461060c4f9cSJiri Olsa 462060c4f9cSJiri Olsa return 0; 463060c4f9cSJiri Olsa } 464060c4f9cSJiri Olsa 4651971f59fSJiri Olsa static int read_counter(struct perf_evsel *counter); 4661971f59fSJiri Olsa 467dcd9936aSIngo Molnar /* 46886470930SIngo Molnar * Read out the results of a single counter: 469f5b4a9c3SStephane Eranian * aggregate counts across CPUs in system-wide mode 47086470930SIngo Molnar */ 471c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter) 47286470930SIngo Molnar { 4731971f59fSJiri Olsa struct perf_counts_values *aggr = &counter->counts->aggr; 47469aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 475c52b12edSArnaldo Carvalho de Melo u64 *count = counter->counts->aggr.values; 476c52b12edSArnaldo Carvalho de Melo int i; 47786470930SIngo Molnar 4781971f59fSJiri Olsa aggr->val = aggr->ena = aggr->run = 0; 4791971f59fSJiri Olsa 4801971f59fSJiri Olsa if (read_counter(counter)) 481c52b12edSArnaldo Carvalho de Melo return -1; 4829e9772c4SPeter Zijlstra 4836c0345b7SJiri Olsa if (!counter->snapshot) 4841971f59fSJiri Olsa perf_evsel__compute_deltas(counter, -1, aggr); 4851971f59fSJiri Olsa perf_counts_values__scale(aggr, scale, &counter->counts->scaled); 4861971f59fSJiri Olsa 4879e9772c4SPeter Zijlstra for (i = 0; i < 3; i++) 48869aad6f1SArnaldo Carvalho de Melo update_stats(&ps->res_stats[i], count[i]); 4899e9772c4SPeter Zijlstra 4909e9772c4SPeter Zijlstra if (verbose) { 4914aa9015fSStephane Eranian fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 4927289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter), count[0], count[1], count[2]); 4939e9772c4SPeter Zijlstra } 4949e9772c4SPeter Zijlstra 49586470930SIngo Molnar /* 49686470930SIngo Molnar * Save the full runtime - to allow normalization during printout: 49786470930SIngo Molnar */ 498dcd9936aSIngo Molnar update_shadow_stats(counter, count); 499c52b12edSArnaldo Carvalho de Melo 500c52b12edSArnaldo Carvalho de Melo return 0; 501f5b4a9c3SStephane Eranian } 502f5b4a9c3SStephane Eranian 503f5b4a9c3SStephane Eranian /* 504f5b4a9c3SStephane Eranian * Read out the results of a single counter: 505f5b4a9c3SStephane Eranian * do not aggregate counts across CPUs in system-wide mode 506f5b4a9c3SStephane Eranian */ 507c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter) 508f5b4a9c3SStephane Eranian { 5099bf1a529SJiri Olsa int nthreads = thread_map__nr(evsel_list->threads); 5109bf1a529SJiri Olsa int ncpus = perf_evsel__nr_cpus(counter); 5119bf1a529SJiri Olsa int cpu, thread; 512f5b4a9c3SStephane Eranian 5133b4331d9SSuzuki K. Poulose if (!counter->supported) 5143b4331d9SSuzuki K. Poulose return -ENOENT; 5153b4331d9SSuzuki K. Poulose 5169bf1a529SJiri Olsa if (counter->system_wide) 5179bf1a529SJiri Olsa nthreads = 1; 5189bf1a529SJiri Olsa 519779d0b99SJiri Olsa if (counter->per_pkg) 520779d0b99SJiri Olsa zero_per_pkg(counter); 521779d0b99SJiri Olsa 5229bf1a529SJiri Olsa for (thread = 0; thread < nthreads; thread++) { 5239bf1a529SJiri Olsa for (cpu = 0; cpu < ncpus; cpu++) { 5249bf1a529SJiri Olsa if (perf_evsel__read_cb(counter, cpu, thread, read_cb)) 525c52b12edSArnaldo Carvalho de Melo return -1; 526f5b4a9c3SStephane Eranian } 5279bf1a529SJiri Olsa } 528c52b12edSArnaldo Carvalho de Melo 529c52b12edSArnaldo Carvalho de Melo return 0; 53086470930SIngo Molnar } 53186470930SIngo Molnar 53213370a9bSStephane Eranian static void print_interval(void) 53313370a9bSStephane Eranian { 53413370a9bSStephane Eranian static int num_print_interval; 53513370a9bSStephane Eranian struct perf_evsel *counter; 53613370a9bSStephane Eranian struct perf_stat *ps; 53713370a9bSStephane Eranian struct timespec ts, rs; 53813370a9bSStephane Eranian char prefix[64]; 53913370a9bSStephane Eranian 54086ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) { 5410050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) { 54213370a9bSStephane Eranian ps = counter->priv; 54313370a9bSStephane Eranian memset(ps->res_stats, 0, sizeof(ps->res_stats)); 54413370a9bSStephane Eranian read_counter_aggr(counter); 54513370a9bSStephane Eranian } 54686ee6e18SStephane Eranian } else { 5470050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) { 54886ee6e18SStephane Eranian ps = counter->priv; 54986ee6e18SStephane Eranian memset(ps->res_stats, 0, sizeof(ps->res_stats)); 55086ee6e18SStephane Eranian read_counter(counter); 55113370a9bSStephane Eranian } 55286ee6e18SStephane Eranian } 55386ee6e18SStephane Eranian 55413370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ts); 55513370a9bSStephane Eranian diff_timespec(&rs, &ts, &ref_time); 55613370a9bSStephane Eranian sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep); 55713370a9bSStephane Eranian 55813370a9bSStephane Eranian if (num_print_interval == 0 && !csv_output) { 55986ee6e18SStephane Eranian switch (aggr_mode) { 56086ee6e18SStephane Eranian case AGGR_SOCKET: 561410136f5SStephane Eranian fprintf(output, "# time socket cpus counts %*s events\n", unit_width, "unit"); 56286ee6e18SStephane Eranian break; 56312c08a9fSStephane Eranian case AGGR_CORE: 564410136f5SStephane Eranian fprintf(output, "# time core cpus counts %*s events\n", unit_width, "unit"); 56512c08a9fSStephane Eranian break; 56686ee6e18SStephane Eranian case AGGR_NONE: 567410136f5SStephane Eranian fprintf(output, "# time CPU counts %*s events\n", unit_width, "unit"); 56886ee6e18SStephane Eranian break; 56986ee6e18SStephane Eranian case AGGR_GLOBAL: 57086ee6e18SStephane Eranian default: 571410136f5SStephane Eranian fprintf(output, "# time counts %*s events\n", unit_width, "unit"); 57213370a9bSStephane Eranian } 57386ee6e18SStephane Eranian } 57413370a9bSStephane Eranian 57513370a9bSStephane Eranian if (++num_print_interval == 25) 57613370a9bSStephane Eranian num_print_interval = 0; 57713370a9bSStephane Eranian 57886ee6e18SStephane Eranian switch (aggr_mode) { 57912c08a9fSStephane Eranian case AGGR_CORE: 58086ee6e18SStephane Eranian case AGGR_SOCKET: 58186ee6e18SStephane Eranian print_aggr(prefix); 58286ee6e18SStephane Eranian break; 58386ee6e18SStephane Eranian case AGGR_NONE: 5840050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) 58513370a9bSStephane Eranian print_counter(counter, prefix); 58686ee6e18SStephane Eranian break; 58786ee6e18SStephane Eranian case AGGR_GLOBAL: 58886ee6e18SStephane Eranian default: 5890050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) 59013370a9bSStephane Eranian print_counter_aggr(counter, prefix); 59113370a9bSStephane Eranian } 5922bbf03f1SAndi Kleen 5932bbf03f1SAndi Kleen fflush(output); 59413370a9bSStephane Eranian } 59513370a9bSStephane Eranian 59641191688SAndi Kleen static void handle_initial_delay(void) 59741191688SAndi Kleen { 59841191688SAndi Kleen struct perf_evsel *counter; 59941191688SAndi Kleen 60041191688SAndi Kleen if (initial_delay) { 60141191688SAndi Kleen const int ncpus = cpu_map__nr(evsel_list->cpus), 60241191688SAndi Kleen nthreads = thread_map__nr(evsel_list->threads); 60341191688SAndi Kleen 60441191688SAndi Kleen usleep(initial_delay * 1000); 6050050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) 60641191688SAndi Kleen perf_evsel__enable(counter, ncpus, nthreads); 60741191688SAndi Kleen } 60841191688SAndi Kleen } 60941191688SAndi Kleen 610f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno; 6116af206fdSArnaldo Carvalho de Melo 6126af206fdSArnaldo Carvalho de Melo /* 6136af206fdSArnaldo Carvalho de Melo * perf_evlist__prepare_workload will send a SIGUSR1 6146af206fdSArnaldo Carvalho de Melo * if the fork fails, since we asked by setting its 6156af206fdSArnaldo Carvalho de Melo * want_signal to true. 6166af206fdSArnaldo Carvalho de Melo */ 617f33cbe72SArnaldo Carvalho de Melo static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info, 618f33cbe72SArnaldo Carvalho de Melo void *ucontext __maybe_unused) 6196af206fdSArnaldo Carvalho de Melo { 620f33cbe72SArnaldo Carvalho de Melo workload_exec_errno = info->si_value.sival_int; 6216af206fdSArnaldo Carvalho de Melo } 6226af206fdSArnaldo Carvalho de Melo 623acf28922SNamhyung Kim static int __run_perf_stat(int argc, const char **argv) 62486470930SIngo Molnar { 62556e52e85SArnaldo Carvalho de Melo char msg[512]; 62686470930SIngo Molnar unsigned long long t0, t1; 627cac21425SJiri Olsa struct perf_evsel *counter; 62813370a9bSStephane Eranian struct timespec ts; 629410136f5SStephane Eranian size_t l; 63042202dd5SIngo Molnar int status = 0; 6316be2850eSZhang, Yanmin const bool forks = (argc > 0); 63286470930SIngo Molnar 63313370a9bSStephane Eranian if (interval) { 63413370a9bSStephane Eranian ts.tv_sec = interval / 1000; 63513370a9bSStephane Eranian ts.tv_nsec = (interval % 1000) * 1000000; 63613370a9bSStephane Eranian } else { 63713370a9bSStephane Eranian ts.tv_sec = 1; 63813370a9bSStephane Eranian ts.tv_nsec = 0; 63913370a9bSStephane Eranian } 64013370a9bSStephane Eranian 641acf28922SNamhyung Kim if (forks) { 642735f7e0bSArnaldo Carvalho de Melo if (perf_evlist__prepare_workload(evsel_list, &target, argv, false, 643735f7e0bSArnaldo Carvalho de Melo workload_exec_failed_signal) < 0) { 644acf28922SNamhyung Kim perror("failed to prepare workload"); 645fceda7feSDavid Ahern return -1; 646051ae7f7SPaul Mackerras } 647d20a47e7SNamhyung Kim child_pid = evsel_list->workload.pid; 64860666c63SLiming Wang } 649051ae7f7SPaul Mackerras 6506a4bb04cSJiri Olsa if (group) 65163dab225SArnaldo Carvalho de Melo perf_evlist__set_leader(evsel_list); 6526a4bb04cSJiri Olsa 6530050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) { 654cac21425SJiri Olsa if (create_perf_stat_counter(counter) < 0) { 655979987a5SDavid Ahern /* 656979987a5SDavid Ahern * PPC returns ENXIO for HW counters until 2.6.37 657979987a5SDavid Ahern * (behavior changed with commit b0a873e). 658979987a5SDavid Ahern */ 65938f6ae1eSAnton Blanchard if (errno == EINVAL || errno == ENOSYS || 660979987a5SDavid Ahern errno == ENOENT || errno == EOPNOTSUPP || 661979987a5SDavid Ahern errno == ENXIO) { 662c63ca0c0SDavid Ahern if (verbose) 663c63ca0c0SDavid Ahern ui__warning("%s event is not supported by the kernel.\n", 6647289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 6652cee77c4SDavid Ahern counter->supported = false; 666ede70290SIngo Molnar continue; 667c63ca0c0SDavid Ahern } 668ede70290SIngo Molnar 66956e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(counter, &target, 67056e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 67156e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 67256e52e85SArnaldo Carvalho de Melo 673084ab9f8SArnaldo Carvalho de Melo if (child_pid != -1) 674084ab9f8SArnaldo Carvalho de Melo kill(child_pid, SIGTERM); 675fceda7feSDavid Ahern 676084ab9f8SArnaldo Carvalho de Melo return -1; 677084ab9f8SArnaldo Carvalho de Melo } 6782cee77c4SDavid Ahern counter->supported = true; 679410136f5SStephane Eranian 680410136f5SStephane Eranian l = strlen(counter->unit); 681410136f5SStephane Eranian if (l > unit_width) 682410136f5SStephane Eranian unit_width = l; 68348290609SArnaldo Carvalho de Melo } 68486470930SIngo Molnar 6851491a632SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evsel_list)) { 686cfd748aeSFrederic Weisbecker error("failed to set filter with %d (%s)\n", errno, 687759e612bSMasami Hiramatsu strerror_r(errno, msg, sizeof(msg))); 688cfd748aeSFrederic Weisbecker return -1; 689cfd748aeSFrederic Weisbecker } 690cfd748aeSFrederic Weisbecker 69186470930SIngo Molnar /* 69286470930SIngo Molnar * Enable counters and exec the command: 69386470930SIngo Molnar */ 69486470930SIngo Molnar t0 = rdclock(); 69513370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ref_time); 69686470930SIngo Molnar 69760666c63SLiming Wang if (forks) { 698acf28922SNamhyung Kim perf_evlist__start_workload(evsel_list); 69941191688SAndi Kleen handle_initial_delay(); 700acf28922SNamhyung Kim 70113370a9bSStephane Eranian if (interval) { 70213370a9bSStephane Eranian while (!waitpid(child_pid, &status, WNOHANG)) { 70313370a9bSStephane Eranian nanosleep(&ts, NULL); 70413370a9bSStephane Eranian print_interval(); 70513370a9bSStephane Eranian } 70613370a9bSStephane Eranian } 70742202dd5SIngo Molnar wait(&status); 7086af206fdSArnaldo Carvalho de Melo 709f33cbe72SArnaldo Carvalho de Melo if (workload_exec_errno) { 710f33cbe72SArnaldo Carvalho de Melo const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); 711f33cbe72SArnaldo Carvalho de Melo pr_err("Workload failed: %s\n", emsg); 7126af206fdSArnaldo Carvalho de Melo return -1; 713f33cbe72SArnaldo Carvalho de Melo } 7146af206fdSArnaldo Carvalho de Melo 71533e49ea7SAndi Kleen if (WIFSIGNALED(status)) 71633e49ea7SAndi Kleen psignal(WTERMSIG(status), argv[0]); 71760666c63SLiming Wang } else { 71841191688SAndi Kleen handle_initial_delay(); 71913370a9bSStephane Eranian while (!done) { 72013370a9bSStephane Eranian nanosleep(&ts, NULL); 72113370a9bSStephane Eranian if (interval) 72213370a9bSStephane Eranian print_interval(); 72313370a9bSStephane Eranian } 72460666c63SLiming Wang } 72586470930SIngo Molnar 72686470930SIngo Molnar t1 = rdclock(); 72786470930SIngo Molnar 7289e9772c4SPeter Zijlstra update_stats(&walltime_nsecs_stats, t1 - t0); 72942202dd5SIngo Molnar 73086ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) { 7310050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) { 732c52b12edSArnaldo Carvalho de Melo read_counter_aggr(counter); 7337ae92e74SYan, Zheng perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 734b3a319d5SNamhyung Kim thread_map__nr(evsel_list->threads)); 735c52b12edSArnaldo Carvalho de Melo } 73686ee6e18SStephane Eranian } else { 7370050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) { 73886ee6e18SStephane Eranian read_counter(counter); 73986ee6e18SStephane Eranian perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1); 74086ee6e18SStephane Eranian } 741c52b12edSArnaldo Carvalho de Melo } 742c52b12edSArnaldo Carvalho de Melo 74342202dd5SIngo Molnar return WEXITSTATUS(status); 74442202dd5SIngo Molnar } 74542202dd5SIngo Molnar 74641cde476SArnaldo Carvalho de Melo static int run_perf_stat(int argc, const char **argv) 7471f16c575SPeter Zijlstra { 7481f16c575SPeter Zijlstra int ret; 7491f16c575SPeter Zijlstra 7501f16c575SPeter Zijlstra if (pre_cmd) { 7511f16c575SPeter Zijlstra ret = system(pre_cmd); 7521f16c575SPeter Zijlstra if (ret) 7531f16c575SPeter Zijlstra return ret; 7541f16c575SPeter Zijlstra } 7551f16c575SPeter Zijlstra 7561f16c575SPeter Zijlstra if (sync_run) 7571f16c575SPeter Zijlstra sync(); 7581f16c575SPeter Zijlstra 7591f16c575SPeter Zijlstra ret = __run_perf_stat(argc, argv); 7601f16c575SPeter Zijlstra if (ret) 7611f16c575SPeter Zijlstra return ret; 7621f16c575SPeter Zijlstra 7631f16c575SPeter Zijlstra if (post_cmd) { 7641f16c575SPeter Zijlstra ret = system(post_cmd); 7651f16c575SPeter Zijlstra if (ret) 7661f16c575SPeter Zijlstra return ret; 7671f16c575SPeter Zijlstra } 7681f16c575SPeter Zijlstra 7691f16c575SPeter Zijlstra return ret; 7701f16c575SPeter Zijlstra } 7711f16c575SPeter Zijlstra 772f99844cbSIngo Molnar static void print_noise_pct(double total, double avg) 773f99844cbSIngo Molnar { 7740007eceaSXiao Guangrong double pct = rel_stddev_stats(total, avg); 775f99844cbSIngo Molnar 7763ae9a34dSZhengyu He if (csv_output) 7774aa9015fSStephane Eranian fprintf(output, "%s%.2f%%", csv_sep, pct); 778a1bca6ccSJim Cromie else if (pct) 7794aa9015fSStephane Eranian fprintf(output, " ( +-%6.2f%% )", pct); 780f99844cbSIngo Molnar } 781f99844cbSIngo Molnar 78269aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg) 78342202dd5SIngo Molnar { 78469aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps; 78569aad6f1SArnaldo Carvalho de Melo 786849abde9SPeter Zijlstra if (run_count == 1) 787849abde9SPeter Zijlstra return; 788849abde9SPeter Zijlstra 78969aad6f1SArnaldo Carvalho de Melo ps = evsel->priv; 790f99844cbSIngo Molnar print_noise_pct(stddev_stats(&ps->res_stats[0]), avg); 79142202dd5SIngo Molnar } 79242202dd5SIngo Molnar 79312c08a9fSStephane Eranian static void aggr_printout(struct perf_evsel *evsel, int id, int nr) 79442202dd5SIngo Molnar { 79586ee6e18SStephane Eranian switch (aggr_mode) { 79612c08a9fSStephane Eranian case AGGR_CORE: 79712c08a9fSStephane Eranian fprintf(output, "S%d-C%*d%s%*d%s", 79812c08a9fSStephane Eranian cpu_map__id_to_socket(id), 79912c08a9fSStephane Eranian csv_output ? 0 : -8, 80012c08a9fSStephane Eranian cpu_map__id_to_cpu(id), 80112c08a9fSStephane Eranian csv_sep, 80212c08a9fSStephane Eranian csv_output ? 0 : 4, 80312c08a9fSStephane Eranian nr, 80412c08a9fSStephane Eranian csv_sep); 80512c08a9fSStephane Eranian break; 80686ee6e18SStephane Eranian case AGGR_SOCKET: 80786ee6e18SStephane Eranian fprintf(output, "S%*d%s%*d%s", 808d7e7a451SStephane Eranian csv_output ? 0 : -5, 80912c08a9fSStephane Eranian id, 810d7e7a451SStephane Eranian csv_sep, 811d7e7a451SStephane Eranian csv_output ? 0 : 4, 812d7e7a451SStephane Eranian nr, 813d7e7a451SStephane Eranian csv_sep); 81486ee6e18SStephane Eranian break; 81586ee6e18SStephane Eranian case AGGR_NONE: 81686ee6e18SStephane Eranian fprintf(output, "CPU%*d%s", 817d7470b6aSStephane Eranian csv_output ? 0 : -4, 81812c08a9fSStephane Eranian perf_evsel__cpus(evsel)->map[id], csv_sep); 81986ee6e18SStephane Eranian break; 82086ee6e18SStephane Eranian case AGGR_GLOBAL: 82186ee6e18SStephane Eranian default: 82286ee6e18SStephane Eranian break; 82386ee6e18SStephane Eranian } 82486ee6e18SStephane Eranian } 825d7470b6aSStephane Eranian 826da88c7f7SAndi Kleen static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg) 82786ee6e18SStephane Eranian { 82886ee6e18SStephane Eranian double msecs = avg / 1e6; 829410136f5SStephane Eranian const char *fmt_v, *fmt_n; 8304bbe5a61SDavid Ahern char name[25]; 83186ee6e18SStephane Eranian 832410136f5SStephane Eranian fmt_v = csv_output ? "%.6f%s" : "%18.6f%s"; 833410136f5SStephane Eranian fmt_n = csv_output ? "%s" : "%-25s"; 834410136f5SStephane Eranian 835da88c7f7SAndi Kleen aggr_printout(evsel, id, nr); 83686ee6e18SStephane Eranian 8374bbe5a61SDavid Ahern scnprintf(name, sizeof(name), "%s%s", 8384bbe5a61SDavid Ahern perf_evsel__name(evsel), csv_output ? "" : " (msec)"); 839410136f5SStephane Eranian 840410136f5SStephane Eranian fprintf(output, fmt_v, msecs, csv_sep); 841410136f5SStephane Eranian 842410136f5SStephane Eranian if (csv_output) 843410136f5SStephane Eranian fprintf(output, "%s%s", evsel->unit, csv_sep); 844410136f5SStephane Eranian else 845410136f5SStephane Eranian fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep); 846410136f5SStephane Eranian 847410136f5SStephane Eranian fprintf(output, fmt_n, name); 848d7470b6aSStephane Eranian 849023695d9SStephane Eranian if (evsel->cgrp) 8504aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 851023695d9SStephane Eranian 85213370a9bSStephane Eranian if (csv_output || interval) 853d7470b6aSStephane Eranian return; 85442202dd5SIngo Molnar 855daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 8564aa9015fSStephane Eranian fprintf(output, " # %8.3f CPUs utilized ", 8574aa9015fSStephane Eranian avg / avg_stats(&walltime_nsecs_stats)); 8589dac6a29SNamhyung Kim else 8599dac6a29SNamhyung Kim fprintf(output, " "); 86042202dd5SIngo Molnar } 86142202dd5SIngo Molnar 86215e6392fSNamhyung Kim /* used for get_ratio_color() */ 86315e6392fSNamhyung Kim enum grc_type { 86415e6392fSNamhyung Kim GRC_STALLED_CYCLES_FE, 86515e6392fSNamhyung Kim GRC_STALLED_CYCLES_BE, 86615e6392fSNamhyung Kim GRC_CACHE_MISSES, 86715e6392fSNamhyung Kim GRC_MAX_NR 86815e6392fSNamhyung Kim }; 86915e6392fSNamhyung Kim 87015e6392fSNamhyung Kim static const char *get_ratio_color(enum grc_type type, double ratio) 87115e6392fSNamhyung Kim { 87215e6392fSNamhyung Kim static const double grc_table[GRC_MAX_NR][3] = { 87315e6392fSNamhyung Kim [GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 }, 87415e6392fSNamhyung Kim [GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 }, 87515e6392fSNamhyung Kim [GRC_CACHE_MISSES] = { 20.0, 10.0, 5.0 }, 87615e6392fSNamhyung Kim }; 87715e6392fSNamhyung Kim const char *color = PERF_COLOR_NORMAL; 87815e6392fSNamhyung Kim 87915e6392fSNamhyung Kim if (ratio > grc_table[type][0]) 88015e6392fSNamhyung Kim color = PERF_COLOR_RED; 88115e6392fSNamhyung Kim else if (ratio > grc_table[type][1]) 88215e6392fSNamhyung Kim color = PERF_COLOR_MAGENTA; 88315e6392fSNamhyung Kim else if (ratio > grc_table[type][2]) 88415e6392fSNamhyung Kim color = PERF_COLOR_YELLOW; 88515e6392fSNamhyung Kim 88615e6392fSNamhyung Kim return color; 88715e6392fSNamhyung Kim } 88815e6392fSNamhyung Kim 8891d037ca1SIrina Tirdea static void print_stalled_cycles_frontend(int cpu, 8901d037ca1SIrina Tirdea struct perf_evsel *evsel 8911d037ca1SIrina Tirdea __maybe_unused, double avg) 892d3d1e86dSIngo Molnar { 893d3d1e86dSIngo Molnar double total, ratio = 0.0; 894d3d1e86dSIngo Molnar const char *color; 895d3d1e86dSIngo Molnar 896d3d1e86dSIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 897d3d1e86dSIngo Molnar 898d3d1e86dSIngo Molnar if (total) 899d3d1e86dSIngo Molnar ratio = avg / total * 100.0; 900d3d1e86dSIngo Molnar 90115e6392fSNamhyung Kim color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio); 902d3d1e86dSIngo Molnar 9034aa9015fSStephane Eranian fprintf(output, " # "); 9044aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 9054aa9015fSStephane Eranian fprintf(output, " frontend cycles idle "); 906d3d1e86dSIngo Molnar } 907d3d1e86dSIngo Molnar 9081d037ca1SIrina Tirdea static void print_stalled_cycles_backend(int cpu, 9091d037ca1SIrina Tirdea struct perf_evsel *evsel 9101d037ca1SIrina Tirdea __maybe_unused, double avg) 911a5d243d0SIngo Molnar { 912a5d243d0SIngo Molnar double total, ratio = 0.0; 913a5d243d0SIngo Molnar const char *color; 914a5d243d0SIngo Molnar 915a5d243d0SIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 916a5d243d0SIngo Molnar 917a5d243d0SIngo Molnar if (total) 918a5d243d0SIngo Molnar ratio = avg / total * 100.0; 919a5d243d0SIngo Molnar 92015e6392fSNamhyung Kim color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio); 921a5d243d0SIngo Molnar 9224aa9015fSStephane Eranian fprintf(output, " # "); 9234aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 9244aa9015fSStephane Eranian fprintf(output, " backend cycles idle "); 925a5d243d0SIngo Molnar } 926a5d243d0SIngo Molnar 9271d037ca1SIrina Tirdea static void print_branch_misses(int cpu, 9281d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 9291d037ca1SIrina Tirdea double avg) 930c78df6c1SIngo Molnar { 931c78df6c1SIngo Molnar double total, ratio = 0.0; 932c78df6c1SIngo Molnar const char *color; 933c78df6c1SIngo Molnar 934c78df6c1SIngo Molnar total = avg_stats(&runtime_branches_stats[cpu]); 935c78df6c1SIngo Molnar 936c78df6c1SIngo Molnar if (total) 937c78df6c1SIngo Molnar ratio = avg / total * 100.0; 938c78df6c1SIngo Molnar 93915e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 940c78df6c1SIngo Molnar 9414aa9015fSStephane Eranian fprintf(output, " # "); 9424aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 9434aa9015fSStephane Eranian fprintf(output, " of all branches "); 944c78df6c1SIngo Molnar } 945c78df6c1SIngo Molnar 9461d037ca1SIrina Tirdea static void print_l1_dcache_misses(int cpu, 9471d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 9481d037ca1SIrina Tirdea double avg) 9498bb6c79fSIngo Molnar { 9508bb6c79fSIngo Molnar double total, ratio = 0.0; 9518bb6c79fSIngo Molnar const char *color; 9528bb6c79fSIngo Molnar 9538bb6c79fSIngo Molnar total = avg_stats(&runtime_l1_dcache_stats[cpu]); 9548bb6c79fSIngo Molnar 9558bb6c79fSIngo Molnar if (total) 9568bb6c79fSIngo Molnar ratio = avg / total * 100.0; 9578bb6c79fSIngo Molnar 95815e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 9598bb6c79fSIngo Molnar 9604aa9015fSStephane Eranian fprintf(output, " # "); 9614aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 9624aa9015fSStephane Eranian fprintf(output, " of all L1-dcache hits "); 9638bb6c79fSIngo Molnar } 9648bb6c79fSIngo Molnar 9651d037ca1SIrina Tirdea static void print_l1_icache_misses(int cpu, 9661d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 9671d037ca1SIrina Tirdea double avg) 968c3305257SIngo Molnar { 969c3305257SIngo Molnar double total, ratio = 0.0; 970c3305257SIngo Molnar const char *color; 971c3305257SIngo Molnar 972c3305257SIngo Molnar total = avg_stats(&runtime_l1_icache_stats[cpu]); 973c3305257SIngo Molnar 974c3305257SIngo Molnar if (total) 975c3305257SIngo Molnar ratio = avg / total * 100.0; 976c3305257SIngo Molnar 97715e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 978c3305257SIngo Molnar 9794aa9015fSStephane Eranian fprintf(output, " # "); 9804aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 9814aa9015fSStephane Eranian fprintf(output, " of all L1-icache hits "); 982c3305257SIngo Molnar } 983c3305257SIngo Molnar 9841d037ca1SIrina Tirdea static void print_dtlb_cache_misses(int cpu, 9851d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 9861d037ca1SIrina Tirdea double avg) 987c3305257SIngo Molnar { 988c3305257SIngo Molnar double total, ratio = 0.0; 989c3305257SIngo Molnar const char *color; 990c3305257SIngo Molnar 991c3305257SIngo Molnar total = avg_stats(&runtime_dtlb_cache_stats[cpu]); 992c3305257SIngo Molnar 993c3305257SIngo Molnar if (total) 994c3305257SIngo Molnar ratio = avg / total * 100.0; 995c3305257SIngo Molnar 99615e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 997c3305257SIngo Molnar 9984aa9015fSStephane Eranian fprintf(output, " # "); 9994aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 10004aa9015fSStephane Eranian fprintf(output, " of all dTLB cache hits "); 1001c3305257SIngo Molnar } 1002c3305257SIngo Molnar 10031d037ca1SIrina Tirdea static void print_itlb_cache_misses(int cpu, 10041d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 10051d037ca1SIrina Tirdea double avg) 1006c3305257SIngo Molnar { 1007c3305257SIngo Molnar double total, ratio = 0.0; 1008c3305257SIngo Molnar const char *color; 1009c3305257SIngo Molnar 1010c3305257SIngo Molnar total = avg_stats(&runtime_itlb_cache_stats[cpu]); 1011c3305257SIngo Molnar 1012c3305257SIngo Molnar if (total) 1013c3305257SIngo Molnar ratio = avg / total * 100.0; 1014c3305257SIngo Molnar 101515e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 1016c3305257SIngo Molnar 10174aa9015fSStephane Eranian fprintf(output, " # "); 10184aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 10194aa9015fSStephane Eranian fprintf(output, " of all iTLB cache hits "); 1020c3305257SIngo Molnar } 1021c3305257SIngo Molnar 10221d037ca1SIrina Tirdea static void print_ll_cache_misses(int cpu, 10231d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 10241d037ca1SIrina Tirdea double avg) 1025c3305257SIngo Molnar { 1026c3305257SIngo Molnar double total, ratio = 0.0; 1027c3305257SIngo Molnar const char *color; 1028c3305257SIngo Molnar 1029c3305257SIngo Molnar total = avg_stats(&runtime_ll_cache_stats[cpu]); 1030c3305257SIngo Molnar 1031c3305257SIngo Molnar if (total) 1032c3305257SIngo Molnar ratio = avg / total * 100.0; 1033c3305257SIngo Molnar 103415e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 1035c3305257SIngo Molnar 10364aa9015fSStephane Eranian fprintf(output, " # "); 10374aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 10384aa9015fSStephane Eranian fprintf(output, " of all LL-cache hits "); 1039c3305257SIngo Molnar } 1040c3305257SIngo Molnar 1041da88c7f7SAndi Kleen static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg) 104242202dd5SIngo Molnar { 10434cabc3d1SAndi Kleen double total, ratio = 0.0, total2; 1044410136f5SStephane Eranian double sc = evsel->scale; 1045d7470b6aSStephane Eranian const char *fmt; 1046da88c7f7SAndi Kleen int cpu = cpu_map__id_to_cpu(id); 1047d7470b6aSStephane Eranian 1048410136f5SStephane Eranian if (csv_output) { 1049410136f5SStephane Eranian fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s"; 1050410136f5SStephane Eranian } else { 1051410136f5SStephane Eranian if (big_num) 1052410136f5SStephane Eranian fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s"; 1053d7470b6aSStephane Eranian else 1054410136f5SStephane Eranian fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s"; 1055410136f5SStephane Eranian } 1056f5b4a9c3SStephane Eranian 1057da88c7f7SAndi Kleen aggr_printout(evsel, id, nr); 105886ee6e18SStephane Eranian 105986ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) 1060f5b4a9c3SStephane Eranian cpu = 0; 1061c7f7fea3SIngo Molnar 1062410136f5SStephane Eranian fprintf(output, fmt, avg, csv_sep); 1063410136f5SStephane Eranian 1064410136f5SStephane Eranian if (evsel->unit) 1065410136f5SStephane Eranian fprintf(output, "%-*s%s", 1066410136f5SStephane Eranian csv_output ? 0 : unit_width, 1067410136f5SStephane Eranian evsel->unit, csv_sep); 1068410136f5SStephane Eranian 1069410136f5SStephane Eranian fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel)); 1070d7470b6aSStephane Eranian 1071023695d9SStephane Eranian if (evsel->cgrp) 10724aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 1073023695d9SStephane Eranian 107413370a9bSStephane Eranian if (csv_output || interval) 1075d7470b6aSStephane Eranian return; 107642202dd5SIngo Molnar 1077daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 1078f5b4a9c3SStephane Eranian total = avg_stats(&runtime_cycles_stats[cpu]); 10793e7a0817SRamkumar Ramachandra if (total) { 1080c7f7fea3SIngo Molnar ratio = avg / total; 10814aa9015fSStephane Eranian fprintf(output, " # %5.2f insns per cycle ", ratio); 10823e7a0817SRamkumar Ramachandra } 1083d3d1e86dSIngo Molnar total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]); 1084d3d1e86dSIngo Molnar total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu])); 1085481f988aSIngo Molnar 1086481f988aSIngo Molnar if (total && avg) { 1087481f988aSIngo Molnar ratio = total / avg; 1088410136f5SStephane Eranian fprintf(output, "\n"); 1089410136f5SStephane Eranian if (aggr_mode == AGGR_NONE) 1090410136f5SStephane Eranian fprintf(output, " "); 1091410136f5SStephane Eranian fprintf(output, " # %5.2f stalled cycles per insn", ratio); 1092481f988aSIngo Molnar } 1093481f988aSIngo Molnar 1094daec78a0SArnaldo Carvalho de Melo } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 1095f5b4a9c3SStephane Eranian runtime_branches_stats[cpu].n != 0) { 1096c78df6c1SIngo Molnar print_branch_misses(cpu, evsel, avg); 10978bb6c79fSIngo Molnar } else if ( 10988bb6c79fSIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 10998bb6c79fSIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D | 11008bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 11018bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 1102c6264defSIngo Molnar runtime_l1_dcache_stats[cpu].n != 0) { 11038bb6c79fSIngo Molnar print_l1_dcache_misses(cpu, evsel, avg); 1104c3305257SIngo Molnar } else if ( 1105c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 1106c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I | 1107c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 1108c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 1109c3305257SIngo Molnar runtime_l1_icache_stats[cpu].n != 0) { 1110c3305257SIngo Molnar print_l1_icache_misses(cpu, evsel, avg); 1111c3305257SIngo Molnar } else if ( 1112c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 1113c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB | 1114c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 1115c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 1116c3305257SIngo Molnar runtime_dtlb_cache_stats[cpu].n != 0) { 1117c3305257SIngo Molnar print_dtlb_cache_misses(cpu, evsel, avg); 1118c3305257SIngo Molnar } else if ( 1119c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 1120c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB | 1121c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 1122c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 1123c3305257SIngo Molnar runtime_itlb_cache_stats[cpu].n != 0) { 1124c3305257SIngo Molnar print_itlb_cache_misses(cpu, evsel, avg); 1125c3305257SIngo Molnar } else if ( 1126c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 1127c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL | 1128c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 1129c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 1130c3305257SIngo Molnar runtime_ll_cache_stats[cpu].n != 0) { 1131c3305257SIngo Molnar print_ll_cache_misses(cpu, evsel, avg); 1132d58f4c82SIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) && 1133d58f4c82SIngo Molnar runtime_cacherefs_stats[cpu].n != 0) { 1134d58f4c82SIngo Molnar total = avg_stats(&runtime_cacherefs_stats[cpu]); 1135d58f4c82SIngo Molnar 1136d58f4c82SIngo Molnar if (total) 1137d58f4c82SIngo Molnar ratio = avg * 100 / total; 1138d58f4c82SIngo Molnar 11394aa9015fSStephane Eranian fprintf(output, " # %8.3f %% of all cache refs ", ratio); 1140d58f4c82SIngo Molnar 1141d3d1e86dSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 1142d3d1e86dSIngo Molnar print_stalled_cycles_frontend(cpu, evsel, avg); 1143129c04cbSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) { 1144d3d1e86dSIngo Molnar print_stalled_cycles_backend(cpu, evsel, avg); 1145481f988aSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) { 1146481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 1147481f988aSIngo Molnar 1148c458fe62SRamkumar Ramachandra if (total) { 1149c458fe62SRamkumar Ramachandra ratio = avg / total; 11504aa9015fSStephane Eranian fprintf(output, " # %8.3f GHz ", ratio); 1151c458fe62SRamkumar Ramachandra } 11524cabc3d1SAndi Kleen } else if (transaction_run && 11534cabc3d1SAndi Kleen perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) { 11544cabc3d1SAndi Kleen total = avg_stats(&runtime_cycles_stats[cpu]); 11554cabc3d1SAndi Kleen if (total) 11564cabc3d1SAndi Kleen fprintf(output, 11574cabc3d1SAndi Kleen " # %5.2f%% transactional cycles ", 11584cabc3d1SAndi Kleen 100.0 * (avg / total)); 11594cabc3d1SAndi Kleen } else if (transaction_run && 11604cabc3d1SAndi Kleen perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX_CP))) { 11614cabc3d1SAndi Kleen total = avg_stats(&runtime_cycles_stats[cpu]); 11624cabc3d1SAndi Kleen total2 = avg_stats(&runtime_cycles_in_tx_stats[cpu]); 11634cabc3d1SAndi Kleen if (total2 < avg) 11644cabc3d1SAndi Kleen total2 = avg; 11654cabc3d1SAndi Kleen if (total) 11664cabc3d1SAndi Kleen fprintf(output, 11674cabc3d1SAndi Kleen " # %5.2f%% aborted cycles ", 11684cabc3d1SAndi Kleen 100.0 * ((total2-avg) / total)); 11694cabc3d1SAndi Kleen } else if (transaction_run && 11704cabc3d1SAndi Kleen perf_evsel__cmp(evsel, nth_evsel(T_TRANSACTION_START)) && 11714cabc3d1SAndi Kleen avg > 0 && 11724cabc3d1SAndi Kleen runtime_cycles_in_tx_stats[cpu].n != 0) { 11734cabc3d1SAndi Kleen total = avg_stats(&runtime_cycles_in_tx_stats[cpu]); 11744cabc3d1SAndi Kleen 11754cabc3d1SAndi Kleen if (total) 11764cabc3d1SAndi Kleen ratio = total / avg; 11774cabc3d1SAndi Kleen 11784cabc3d1SAndi Kleen fprintf(output, " # %8.0f cycles / transaction ", ratio); 11794cabc3d1SAndi Kleen } else if (transaction_run && 11804cabc3d1SAndi Kleen perf_evsel__cmp(evsel, nth_evsel(T_ELISION_START)) && 11814cabc3d1SAndi Kleen avg > 0 && 11824cabc3d1SAndi Kleen runtime_cycles_in_tx_stats[cpu].n != 0) { 11834cabc3d1SAndi Kleen total = avg_stats(&runtime_cycles_in_tx_stats[cpu]); 11844cabc3d1SAndi Kleen 11854cabc3d1SAndi Kleen if (total) 11864cabc3d1SAndi Kleen ratio = total / avg; 11874cabc3d1SAndi Kleen 11884cabc3d1SAndi Kleen fprintf(output, " # %8.0f cycles / elision ", ratio); 1189481f988aSIngo Molnar } else if (runtime_nsecs_stats[cpu].n != 0) { 11905fde2523SNamhyung Kim char unit = 'M'; 11915fde2523SNamhyung Kim 1192481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 1193481f988aSIngo Molnar 1194481f988aSIngo Molnar if (total) 1195481f988aSIngo Molnar ratio = 1000.0 * avg / total; 11965fde2523SNamhyung Kim if (ratio < 0.001) { 11975fde2523SNamhyung Kim ratio *= 1000; 11985fde2523SNamhyung Kim unit = 'K'; 11995fde2523SNamhyung Kim } 1200481f988aSIngo Molnar 12015fde2523SNamhyung Kim fprintf(output, " # %8.3f %c/sec ", ratio, unit); 1202a5d243d0SIngo Molnar } else { 12034aa9015fSStephane Eranian fprintf(output, " "); 120442202dd5SIngo Molnar } 120542202dd5SIngo Molnar } 120642202dd5SIngo Molnar 120786ee6e18SStephane Eranian static void print_aggr(char *prefix) 1208d7e7a451SStephane Eranian { 1209d7e7a451SStephane Eranian struct perf_evsel *counter; 1210582ec082SStephane Eranian int cpu, cpu2, s, s2, id, nr; 1211410136f5SStephane Eranian double uval; 1212d7e7a451SStephane Eranian u64 ena, run, val; 1213d7e7a451SStephane Eranian 121486ee6e18SStephane Eranian if (!(aggr_map || aggr_get_id)) 1215d7e7a451SStephane Eranian return; 1216d7e7a451SStephane Eranian 121786ee6e18SStephane Eranian for (s = 0; s < aggr_map->nr; s++) { 121886ee6e18SStephane Eranian id = aggr_map->map[s]; 12190050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) { 1220d7e7a451SStephane Eranian val = ena = run = 0; 1221d7e7a451SStephane Eranian nr = 0; 1222d7e7a451SStephane Eranian for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 1223582ec082SStephane Eranian cpu2 = perf_evsel__cpus(counter)->map[cpu]; 1224582ec082SStephane Eranian s2 = aggr_get_id(evsel_list->cpus, cpu2); 122586ee6e18SStephane Eranian if (s2 != id) 1226d7e7a451SStephane Eranian continue; 1227d7e7a451SStephane Eranian val += counter->counts->cpu[cpu].val; 1228d7e7a451SStephane Eranian ena += counter->counts->cpu[cpu].ena; 1229d7e7a451SStephane Eranian run += counter->counts->cpu[cpu].run; 1230d7e7a451SStephane Eranian nr++; 1231d7e7a451SStephane Eranian } 1232d7e7a451SStephane Eranian if (prefix) 1233d7e7a451SStephane Eranian fprintf(output, "%s", prefix); 1234d7e7a451SStephane Eranian 1235d7e7a451SStephane Eranian if (run == 0 || ena == 0) { 1236582ec082SStephane Eranian aggr_printout(counter, id, nr); 123786ee6e18SStephane Eranian 1238410136f5SStephane Eranian fprintf(output, "%*s%s", 1239d7e7a451SStephane Eranian csv_output ? 0 : 18, 1240d7e7a451SStephane Eranian counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 1241410136f5SStephane Eranian csv_sep); 1242410136f5SStephane Eranian 1243410136f5SStephane Eranian fprintf(output, "%-*s%s", 1244410136f5SStephane Eranian csv_output ? 0 : unit_width, 1245410136f5SStephane Eranian counter->unit, csv_sep); 1246410136f5SStephane Eranian 1247410136f5SStephane Eranian fprintf(output, "%*s", 1248410136f5SStephane Eranian csv_output ? 0 : -25, 1249d7e7a451SStephane Eranian perf_evsel__name(counter)); 125086ee6e18SStephane Eranian 1251d7e7a451SStephane Eranian if (counter->cgrp) 1252d7e7a451SStephane Eranian fprintf(output, "%s%s", 1253d7e7a451SStephane Eranian csv_sep, counter->cgrp->name); 1254d7e7a451SStephane Eranian 1255d7e7a451SStephane Eranian fputc('\n', output); 1256d7e7a451SStephane Eranian continue; 1257d7e7a451SStephane Eranian } 1258410136f5SStephane Eranian uval = val * counter->scale; 1259d7e7a451SStephane Eranian 1260d7e7a451SStephane Eranian if (nsec_counter(counter)) 1261410136f5SStephane Eranian nsec_printout(id, nr, counter, uval); 1262d7e7a451SStephane Eranian else 1263410136f5SStephane Eranian abs_printout(id, nr, counter, uval); 1264d7e7a451SStephane Eranian 1265d7e7a451SStephane Eranian if (!csv_output) { 1266d7e7a451SStephane Eranian print_noise(counter, 1.0); 1267d7e7a451SStephane Eranian 1268d7e7a451SStephane Eranian if (run != ena) 1269d7e7a451SStephane Eranian fprintf(output, " (%.2f%%)", 1270d7e7a451SStephane Eranian 100.0 * run / ena); 1271d7e7a451SStephane Eranian } 1272d7e7a451SStephane Eranian fputc('\n', output); 1273d7e7a451SStephane Eranian } 1274d7e7a451SStephane Eranian } 1275d7e7a451SStephane Eranian } 1276d7e7a451SStephane Eranian 127742202dd5SIngo Molnar /* 127842202dd5SIngo Molnar * Print out the results of a single counter: 1279f5b4a9c3SStephane Eranian * aggregated counts in system-wide mode 128042202dd5SIngo Molnar */ 128113370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix) 128242202dd5SIngo Molnar { 128369aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 128469aad6f1SArnaldo Carvalho de Melo double avg = avg_stats(&ps->res_stats[0]); 1285c52b12edSArnaldo Carvalho de Melo int scaled = counter->counts->scaled; 1286410136f5SStephane Eranian double uval; 128742202dd5SIngo Molnar 128813370a9bSStephane Eranian if (prefix) 128913370a9bSStephane Eranian fprintf(output, "%s", prefix); 129013370a9bSStephane Eranian 12913b4331d9SSuzuki K. Poulose if (scaled == -1 || !counter->supported) { 1292410136f5SStephane Eranian fprintf(output, "%*s%s", 1293d7470b6aSStephane Eranian csv_output ? 0 : 18, 12942cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 1295410136f5SStephane Eranian csv_sep); 1296410136f5SStephane Eranian fprintf(output, "%-*s%s", 1297410136f5SStephane Eranian csv_output ? 0 : unit_width, 1298410136f5SStephane Eranian counter->unit, csv_sep); 1299410136f5SStephane Eranian fprintf(output, "%*s", 1300410136f5SStephane Eranian csv_output ? 0 : -25, 13017289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 1302023695d9SStephane Eranian 1303023695d9SStephane Eranian if (counter->cgrp) 13044aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, counter->cgrp->name); 1305023695d9SStephane Eranian 13064aa9015fSStephane Eranian fputc('\n', output); 130742202dd5SIngo Molnar return; 130842202dd5SIngo Molnar } 130942202dd5SIngo Molnar 1310410136f5SStephane Eranian uval = avg * counter->scale; 1311410136f5SStephane Eranian 131242202dd5SIngo Molnar if (nsec_counter(counter)) 1313410136f5SStephane Eranian nsec_printout(-1, 0, counter, uval); 131442202dd5SIngo Molnar else 1315410136f5SStephane Eranian abs_printout(-1, 0, counter, uval); 1316849abde9SPeter Zijlstra 13173ae9a34dSZhengyu He print_noise(counter, avg); 13183ae9a34dSZhengyu He 1319d7470b6aSStephane Eranian if (csv_output) { 13204aa9015fSStephane Eranian fputc('\n', output); 1321d7470b6aSStephane Eranian return; 1322d7470b6aSStephane Eranian } 1323d7470b6aSStephane Eranian 1324506d4bc8SPeter Zijlstra if (scaled) { 1325506d4bc8SPeter Zijlstra double avg_enabled, avg_running; 1326506d4bc8SPeter Zijlstra 132769aad6f1SArnaldo Carvalho de Melo avg_enabled = avg_stats(&ps->res_stats[1]); 132869aad6f1SArnaldo Carvalho de Melo avg_running = avg_stats(&ps->res_stats[2]); 1329506d4bc8SPeter Zijlstra 13304aa9015fSStephane Eranian fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled); 1331506d4bc8SPeter Zijlstra } 13324aa9015fSStephane Eranian fprintf(output, "\n"); 133342202dd5SIngo Molnar } 133442202dd5SIngo Molnar 1335f5b4a9c3SStephane Eranian /* 1336f5b4a9c3SStephane Eranian * Print out the results of a single counter: 1337f5b4a9c3SStephane Eranian * does not use aggregated count in system-wide 1338f5b4a9c3SStephane Eranian */ 133913370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix) 1340f5b4a9c3SStephane Eranian { 1341f5b4a9c3SStephane Eranian u64 ena, run, val; 1342410136f5SStephane Eranian double uval; 1343f5b4a9c3SStephane Eranian int cpu; 1344f5b4a9c3SStephane Eranian 13457ae92e74SYan, Zheng for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 1346c52b12edSArnaldo Carvalho de Melo val = counter->counts->cpu[cpu].val; 1347c52b12edSArnaldo Carvalho de Melo ena = counter->counts->cpu[cpu].ena; 1348c52b12edSArnaldo Carvalho de Melo run = counter->counts->cpu[cpu].run; 134913370a9bSStephane Eranian 135013370a9bSStephane Eranian if (prefix) 135113370a9bSStephane Eranian fprintf(output, "%s", prefix); 135213370a9bSStephane Eranian 1353f5b4a9c3SStephane Eranian if (run == 0 || ena == 0) { 1354410136f5SStephane Eranian fprintf(output, "CPU%*d%s%*s%s", 1355d7470b6aSStephane Eranian csv_output ? 0 : -4, 13567ae92e74SYan, Zheng perf_evsel__cpus(counter)->map[cpu], csv_sep, 1357d7470b6aSStephane Eranian csv_output ? 0 : 18, 13582cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 1359410136f5SStephane Eranian csv_sep); 1360410136f5SStephane Eranian 1361410136f5SStephane Eranian fprintf(output, "%-*s%s", 1362410136f5SStephane Eranian csv_output ? 0 : unit_width, 1363410136f5SStephane Eranian counter->unit, csv_sep); 1364410136f5SStephane Eranian 1365410136f5SStephane Eranian fprintf(output, "%*s", 1366410136f5SStephane Eranian csv_output ? 0 : -25, 13677289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 1368f5b4a9c3SStephane Eranian 1369023695d9SStephane Eranian if (counter->cgrp) 13704aa9015fSStephane Eranian fprintf(output, "%s%s", 13714aa9015fSStephane Eranian csv_sep, counter->cgrp->name); 1372023695d9SStephane Eranian 13734aa9015fSStephane Eranian fputc('\n', output); 1374f5b4a9c3SStephane Eranian continue; 1375f5b4a9c3SStephane Eranian } 1376f5b4a9c3SStephane Eranian 1377410136f5SStephane Eranian uval = val * counter->scale; 1378410136f5SStephane Eranian 1379f5b4a9c3SStephane Eranian if (nsec_counter(counter)) 1380410136f5SStephane Eranian nsec_printout(cpu, 0, counter, uval); 1381f5b4a9c3SStephane Eranian else 1382410136f5SStephane Eranian abs_printout(cpu, 0, counter, uval); 1383f5b4a9c3SStephane Eranian 1384d7470b6aSStephane Eranian if (!csv_output) { 1385f5b4a9c3SStephane Eranian print_noise(counter, 1.0); 1386f5b4a9c3SStephane Eranian 1387c6264defSIngo Molnar if (run != ena) 13884aa9015fSStephane Eranian fprintf(output, " (%.2f%%)", 13894aa9015fSStephane Eranian 100.0 * run / ena); 1390d7470b6aSStephane Eranian } 13914aa9015fSStephane Eranian fputc('\n', output); 1392f5b4a9c3SStephane Eranian } 1393f5b4a9c3SStephane Eranian } 1394f5b4a9c3SStephane Eranian 139542202dd5SIngo Molnar static void print_stat(int argc, const char **argv) 139642202dd5SIngo Molnar { 139769aad6f1SArnaldo Carvalho de Melo struct perf_evsel *counter; 139869aad6f1SArnaldo Carvalho de Melo int i; 139942202dd5SIngo Molnar 140086470930SIngo Molnar fflush(stdout); 140186470930SIngo Molnar 1402d7470b6aSStephane Eranian if (!csv_output) { 14034aa9015fSStephane Eranian fprintf(output, "\n"); 14044aa9015fSStephane Eranian fprintf(output, " Performance counter stats for "); 140562d3b617SDavid Ahern if (target.system_wide) 140662d3b617SDavid Ahern fprintf(output, "\'system wide"); 140762d3b617SDavid Ahern else if (target.cpu_list) 140862d3b617SDavid Ahern fprintf(output, "\'CPU(s) %s", target.cpu_list); 1409602ad878SArnaldo Carvalho de Melo else if (!target__has_task(&target)) { 14104aa9015fSStephane Eranian fprintf(output, "\'%s", argv[0]); 141186470930SIngo Molnar for (i = 1; i < argc; i++) 14124aa9015fSStephane Eranian fprintf(output, " %s", argv[i]); 141320f946b4SNamhyung Kim } else if (target.pid) 141420f946b4SNamhyung Kim fprintf(output, "process id \'%s", target.pid); 1415d6d901c2SZhang, Yanmin else 141620f946b4SNamhyung Kim fprintf(output, "thread id \'%s", target.tid); 141786470930SIngo Molnar 14184aa9015fSStephane Eranian fprintf(output, "\'"); 141942202dd5SIngo Molnar if (run_count > 1) 14204aa9015fSStephane Eranian fprintf(output, " (%d runs)", run_count); 14214aa9015fSStephane Eranian fprintf(output, ":\n\n"); 1422d7470b6aSStephane Eranian } 142386470930SIngo Molnar 142486ee6e18SStephane Eranian switch (aggr_mode) { 142512c08a9fSStephane Eranian case AGGR_CORE: 142686ee6e18SStephane Eranian case AGGR_SOCKET: 142786ee6e18SStephane Eranian print_aggr(NULL); 142886ee6e18SStephane Eranian break; 142986ee6e18SStephane Eranian case AGGR_GLOBAL: 14300050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) 143113370a9bSStephane Eranian print_counter_aggr(counter, NULL); 143286ee6e18SStephane Eranian break; 143386ee6e18SStephane Eranian case AGGR_NONE: 14340050f7aaSArnaldo Carvalho de Melo evlist__for_each(evsel_list, counter) 143586ee6e18SStephane Eranian print_counter(counter, NULL); 143686ee6e18SStephane Eranian break; 143786ee6e18SStephane Eranian default: 143886ee6e18SStephane Eranian break; 1439f5b4a9c3SStephane Eranian } 144086470930SIngo Molnar 1441d7470b6aSStephane Eranian if (!csv_output) { 1442c3305257SIngo Molnar if (!null_run) 14434aa9015fSStephane Eranian fprintf(output, "\n"); 14444aa9015fSStephane Eranian fprintf(output, " %17.9f seconds time elapsed", 1445506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)/1e9); 1446566747e6SIngo Molnar if (run_count > 1) { 14474aa9015fSStephane Eranian fprintf(output, " "); 1448f99844cbSIngo Molnar print_noise_pct(stddev_stats(&walltime_nsecs_stats), 1449506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)); 1450566747e6SIngo Molnar } 14514aa9015fSStephane Eranian fprintf(output, "\n\n"); 145286470930SIngo Molnar } 1453d7470b6aSStephane Eranian } 145486470930SIngo Molnar 1455f7b7c26eSPeter Zijlstra static volatile int signr = -1; 1456f7b7c26eSPeter Zijlstra 145786470930SIngo Molnar static void skip_signal(int signo) 145886470930SIngo Molnar { 145913370a9bSStephane Eranian if ((child_pid == -1) || interval) 146060666c63SLiming Wang done = 1; 146160666c63SLiming Wang 1462f7b7c26eSPeter Zijlstra signr = signo; 1463d07f0b12SStephane Eranian /* 1464d07f0b12SStephane Eranian * render child_pid harmless 1465d07f0b12SStephane Eranian * won't send SIGTERM to a random 1466d07f0b12SStephane Eranian * process in case of race condition 1467d07f0b12SStephane Eranian * and fast PID recycling 1468d07f0b12SStephane Eranian */ 1469d07f0b12SStephane Eranian child_pid = -1; 1470f7b7c26eSPeter Zijlstra } 1471f7b7c26eSPeter Zijlstra 1472f7b7c26eSPeter Zijlstra static void sig_atexit(void) 1473f7b7c26eSPeter Zijlstra { 1474d07f0b12SStephane Eranian sigset_t set, oset; 1475d07f0b12SStephane Eranian 1476d07f0b12SStephane Eranian /* 1477d07f0b12SStephane Eranian * avoid race condition with SIGCHLD handler 1478d07f0b12SStephane Eranian * in skip_signal() which is modifying child_pid 1479d07f0b12SStephane Eranian * goal is to avoid send SIGTERM to a random 1480d07f0b12SStephane Eranian * process 1481d07f0b12SStephane Eranian */ 1482d07f0b12SStephane Eranian sigemptyset(&set); 1483d07f0b12SStephane Eranian sigaddset(&set, SIGCHLD); 1484d07f0b12SStephane Eranian sigprocmask(SIG_BLOCK, &set, &oset); 1485d07f0b12SStephane Eranian 1486933da83aSChris Wilson if (child_pid != -1) 1487933da83aSChris Wilson kill(child_pid, SIGTERM); 1488933da83aSChris Wilson 1489d07f0b12SStephane Eranian sigprocmask(SIG_SETMASK, &oset, NULL); 1490d07f0b12SStephane Eranian 1491f7b7c26eSPeter Zijlstra if (signr == -1) 1492f7b7c26eSPeter Zijlstra return; 1493f7b7c26eSPeter Zijlstra 1494f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 1495f7b7c26eSPeter Zijlstra kill(getpid(), signr); 149686470930SIngo Molnar } 149786470930SIngo Molnar 14981d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused, 14991d037ca1SIrina Tirdea const char *s __maybe_unused, int unset) 1500d7470b6aSStephane Eranian { 1501d7470b6aSStephane Eranian big_num_opt = unset ? 0 : 1; 1502d7470b6aSStephane Eranian return 0; 1503d7470b6aSStephane Eranian } 1504d7470b6aSStephane Eranian 150586ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void) 150686ee6e18SStephane Eranian { 150786ee6e18SStephane Eranian switch (aggr_mode) { 150886ee6e18SStephane Eranian case AGGR_SOCKET: 150986ee6e18SStephane Eranian if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) { 151086ee6e18SStephane Eranian perror("cannot build socket map"); 151186ee6e18SStephane Eranian return -1; 151286ee6e18SStephane Eranian } 151386ee6e18SStephane Eranian aggr_get_id = cpu_map__get_socket; 151486ee6e18SStephane Eranian break; 151512c08a9fSStephane Eranian case AGGR_CORE: 151612c08a9fSStephane Eranian if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) { 151712c08a9fSStephane Eranian perror("cannot build core map"); 151812c08a9fSStephane Eranian return -1; 151912c08a9fSStephane Eranian } 152012c08a9fSStephane Eranian aggr_get_id = cpu_map__get_core; 152112c08a9fSStephane Eranian break; 152286ee6e18SStephane Eranian case AGGR_NONE: 152386ee6e18SStephane Eranian case AGGR_GLOBAL: 152486ee6e18SStephane Eranian default: 152586ee6e18SStephane Eranian break; 152686ee6e18SStephane Eranian } 152786ee6e18SStephane Eranian return 0; 152886ee6e18SStephane Eranian } 152986ee6e18SStephane Eranian 15304cabc3d1SAndi Kleen static int setup_events(const char * const *attrs, unsigned len) 15314cabc3d1SAndi Kleen { 15324cabc3d1SAndi Kleen unsigned i; 15334cabc3d1SAndi Kleen 15344cabc3d1SAndi Kleen for (i = 0; i < len; i++) { 15354cabc3d1SAndi Kleen if (parse_events(evsel_list, attrs[i])) 15364cabc3d1SAndi Kleen return -1; 15374cabc3d1SAndi Kleen } 15384cabc3d1SAndi Kleen return 0; 15394cabc3d1SAndi Kleen } 154086ee6e18SStephane Eranian 15412cba3ffbSIngo Molnar /* 15422cba3ffbSIngo Molnar * Add default attributes, if there were no attributes specified or 15432cba3ffbSIngo Molnar * if -d/--detailed, -d -d or -d -d -d is used: 15442cba3ffbSIngo Molnar */ 15452cba3ffbSIngo Molnar static int add_default_attributes(void) 15462cba3ffbSIngo Molnar { 1547b070a547SArnaldo Carvalho de Melo struct perf_event_attr default_attrs[] = { 1548b070a547SArnaldo Carvalho de Melo 1549b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 1550b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 1551b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 1552b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 1553b070a547SArnaldo Carvalho de Melo 1554b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 1555b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 1556b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 1557b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 1558b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 1559b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 1560b070a547SArnaldo Carvalho de Melo 1561b070a547SArnaldo Carvalho de Melo }; 1562b070a547SArnaldo Carvalho de Melo 1563b070a547SArnaldo Carvalho de Melo /* 1564b070a547SArnaldo Carvalho de Melo * Detailed stats (-d), covering the L1 and last level data caches: 1565b070a547SArnaldo Carvalho de Melo */ 1566b070a547SArnaldo Carvalho de Melo struct perf_event_attr detailed_attrs[] = { 1567b070a547SArnaldo Carvalho de Melo 1568b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1569b070a547SArnaldo Carvalho de Melo .config = 1570b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1571b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1572b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1573b070a547SArnaldo Carvalho de Melo 1574b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1575b070a547SArnaldo Carvalho de Melo .config = 1576b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1577b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1578b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1579b070a547SArnaldo Carvalho de Melo 1580b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1581b070a547SArnaldo Carvalho de Melo .config = 1582b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1583b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1584b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1585b070a547SArnaldo Carvalho de Melo 1586b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1587b070a547SArnaldo Carvalho de Melo .config = 1588b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1589b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1590b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1591b070a547SArnaldo Carvalho de Melo }; 1592b070a547SArnaldo Carvalho de Melo 1593b070a547SArnaldo Carvalho de Melo /* 1594b070a547SArnaldo Carvalho de Melo * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: 1595b070a547SArnaldo Carvalho de Melo */ 1596b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_detailed_attrs[] = { 1597b070a547SArnaldo Carvalho de Melo 1598b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1599b070a547SArnaldo Carvalho de Melo .config = 1600b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1601b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1602b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1603b070a547SArnaldo Carvalho de Melo 1604b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1605b070a547SArnaldo Carvalho de Melo .config = 1606b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1607b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1608b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1609b070a547SArnaldo Carvalho de Melo 1610b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1611b070a547SArnaldo Carvalho de Melo .config = 1612b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1613b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1614b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1615b070a547SArnaldo Carvalho de Melo 1616b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1617b070a547SArnaldo Carvalho de Melo .config = 1618b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1619b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1620b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1621b070a547SArnaldo Carvalho de Melo 1622b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1623b070a547SArnaldo Carvalho de Melo .config = 1624b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1625b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1626b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1627b070a547SArnaldo Carvalho de Melo 1628b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1629b070a547SArnaldo Carvalho de Melo .config = 1630b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1631b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1632b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1633b070a547SArnaldo Carvalho de Melo 1634b070a547SArnaldo Carvalho de Melo }; 1635b070a547SArnaldo Carvalho de Melo 1636b070a547SArnaldo Carvalho de Melo /* 1637b070a547SArnaldo Carvalho de Melo * Very, very detailed stats (-d -d -d), adding prefetch events: 1638b070a547SArnaldo Carvalho de Melo */ 1639b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_very_detailed_attrs[] = { 1640b070a547SArnaldo Carvalho de Melo 1641b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1642b070a547SArnaldo Carvalho de Melo .config = 1643b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1644b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1645b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1646b070a547SArnaldo Carvalho de Melo 1647b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1648b070a547SArnaldo Carvalho de Melo .config = 1649b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1650b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1651b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1652b070a547SArnaldo Carvalho de Melo }; 1653b070a547SArnaldo Carvalho de Melo 16542cba3ffbSIngo Molnar /* Set attrs if no event is selected and !null_run: */ 16552cba3ffbSIngo Molnar if (null_run) 16562cba3ffbSIngo Molnar return 0; 16572cba3ffbSIngo Molnar 16584cabc3d1SAndi Kleen if (transaction_run) { 16594cabc3d1SAndi Kleen int err; 16604cabc3d1SAndi Kleen if (pmu_have_event("cpu", "cycles-ct") && 16614cabc3d1SAndi Kleen pmu_have_event("cpu", "el-start")) 16624cabc3d1SAndi Kleen err = setup_events(transaction_attrs, 16634cabc3d1SAndi Kleen ARRAY_SIZE(transaction_attrs)); 16644cabc3d1SAndi Kleen else 16654cabc3d1SAndi Kleen err = setup_events(transaction_limited_attrs, 16664cabc3d1SAndi Kleen ARRAY_SIZE(transaction_limited_attrs)); 16674cabc3d1SAndi Kleen if (err < 0) { 16684cabc3d1SAndi Kleen fprintf(stderr, "Cannot set up transaction events\n"); 16694cabc3d1SAndi Kleen return -1; 16704cabc3d1SAndi Kleen } 16714cabc3d1SAndi Kleen return 0; 16724cabc3d1SAndi Kleen } 16734cabc3d1SAndi Kleen 16742cba3ffbSIngo Molnar if (!evsel_list->nr_entries) { 167579695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0) 16762cba3ffbSIngo Molnar return -1; 16772cba3ffbSIngo Molnar } 16782cba3ffbSIngo Molnar 16792cba3ffbSIngo Molnar /* Detailed events get appended to the event list: */ 16802cba3ffbSIngo Molnar 16812cba3ffbSIngo Molnar if (detailed_run < 1) 16822cba3ffbSIngo Molnar return 0; 16832cba3ffbSIngo Molnar 16842cba3ffbSIngo Molnar /* Append detailed run extra attributes: */ 168579695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) 16862cba3ffbSIngo Molnar return -1; 16872cba3ffbSIngo Molnar 16882cba3ffbSIngo Molnar if (detailed_run < 2) 16892cba3ffbSIngo Molnar return 0; 16902cba3ffbSIngo Molnar 16912cba3ffbSIngo Molnar /* Append very detailed run extra attributes: */ 169279695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) 16932cba3ffbSIngo Molnar return -1; 16942cba3ffbSIngo Molnar 16952cba3ffbSIngo Molnar if (detailed_run < 3) 16962cba3ffbSIngo Molnar return 0; 16972cba3ffbSIngo Molnar 16982cba3ffbSIngo Molnar /* Append very, very detailed run extra attributes: */ 169979695e1bSArnaldo Carvalho de Melo return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); 17002cba3ffbSIngo Molnar } 17012cba3ffbSIngo Molnar 17021d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) 170386470930SIngo Molnar { 17041f16c575SPeter Zijlstra bool append_file = false; 1705b070a547SArnaldo Carvalho de Melo int output_fd = 0; 1706b070a547SArnaldo Carvalho de Melo const char *output_name = NULL; 1707b070a547SArnaldo Carvalho de Melo const struct option options[] = { 17084cabc3d1SAndi Kleen OPT_BOOLEAN('T', "transaction", &transaction_run, 17094cabc3d1SAndi Kleen "hardware transaction statistics"), 1710b070a547SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &evsel_list, "event", 1711b070a547SArnaldo Carvalho de Melo "event selector. use 'perf list' to list available events", 1712b070a547SArnaldo Carvalho de Melo parse_events_option), 1713b070a547SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &evsel_list, "filter", 1714b070a547SArnaldo Carvalho de Melo "event filter", parse_filter), 1715b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('i', "no-inherit", &no_inherit, 1716b070a547SArnaldo Carvalho de Melo "child tasks do not inherit counters"), 1717b070a547SArnaldo Carvalho de Melo OPT_STRING('p', "pid", &target.pid, "pid", 1718b070a547SArnaldo Carvalho de Melo "stat events on existing process id"), 1719b070a547SArnaldo Carvalho de Melo OPT_STRING('t', "tid", &target.tid, "tid", 1720b070a547SArnaldo Carvalho de Melo "stat events on existing thread id"), 1721b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('a', "all-cpus", &target.system_wide, 1722b070a547SArnaldo Carvalho de Melo "system-wide collection from all CPUs"), 1723b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('g', "group", &group, 1724b070a547SArnaldo Carvalho de Melo "put the counters into a counter group"), 1725b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"), 1726b070a547SArnaldo Carvalho de Melo OPT_INCR('v', "verbose", &verbose, 1727b070a547SArnaldo Carvalho de Melo "be more verbose (show counter open errors, etc)"), 1728b070a547SArnaldo Carvalho de Melo OPT_INTEGER('r', "repeat", &run_count, 1729a7e191c3SFrederik Deweerdt "repeat command and print average + stddev (max: 100, forever: 0)"), 1730b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "null", &null_run, 1731b070a547SArnaldo Carvalho de Melo "null run - dont start any counters"), 1732b070a547SArnaldo Carvalho de Melo OPT_INCR('d', "detailed", &detailed_run, 1733b070a547SArnaldo Carvalho de Melo "detailed run - start a lot of events"), 1734b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('S', "sync", &sync_run, 1735b070a547SArnaldo Carvalho de Melo "call sync() before starting a run"), 1736b070a547SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 1737b070a547SArnaldo Carvalho de Melo "print large numbers with thousands\' separators", 1738b070a547SArnaldo Carvalho de Melo stat__set_big_num), 1739b070a547SArnaldo Carvalho de Melo OPT_STRING('C', "cpu", &target.cpu_list, "cpu", 1740b070a547SArnaldo Carvalho de Melo "list of cpus to monitor in system-wide"), 174186ee6e18SStephane Eranian OPT_SET_UINT('A', "no-aggr", &aggr_mode, 174286ee6e18SStephane Eranian "disable CPU count aggregation", AGGR_NONE), 1743b070a547SArnaldo Carvalho de Melo OPT_STRING('x', "field-separator", &csv_sep, "separator", 1744b070a547SArnaldo Carvalho de Melo "print counts with custom separator"), 1745b070a547SArnaldo Carvalho de Melo OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1746b070a547SArnaldo Carvalho de Melo "monitor event in cgroup name only", parse_cgroups), 1747b070a547SArnaldo Carvalho de Melo OPT_STRING('o', "output", &output_name, "file", "output file name"), 1748b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), 1749b070a547SArnaldo Carvalho de Melo OPT_INTEGER(0, "log-fd", &output_fd, 1750b070a547SArnaldo Carvalho de Melo "log output to fd, instead of stderr"), 17511f16c575SPeter Zijlstra OPT_STRING(0, "pre", &pre_cmd, "command", 17521f16c575SPeter Zijlstra "command to run prior to the measured command"), 17531f16c575SPeter Zijlstra OPT_STRING(0, "post", &post_cmd, "command", 17541f16c575SPeter Zijlstra "command to run after to the measured command"), 175513370a9bSStephane Eranian OPT_UINTEGER('I', "interval-print", &interval, 175613370a9bSStephane Eranian "print counts at regular interval in ms (>= 100)"), 1757d4304958SStephane Eranian OPT_SET_UINT(0, "per-socket", &aggr_mode, 175886ee6e18SStephane Eranian "aggregate counts per processor socket", AGGR_SOCKET), 175912c08a9fSStephane Eranian OPT_SET_UINT(0, "per-core", &aggr_mode, 176012c08a9fSStephane Eranian "aggregate counts per physical processor core", AGGR_CORE), 176141191688SAndi Kleen OPT_UINTEGER('D', "delay", &initial_delay, 176241191688SAndi Kleen "ms to wait before starting measurement after program start"), 1763b070a547SArnaldo Carvalho de Melo OPT_END() 1764b070a547SArnaldo Carvalho de Melo }; 1765b070a547SArnaldo Carvalho de Melo const char * const stat_usage[] = { 1766b070a547SArnaldo Carvalho de Melo "perf stat [<options>] [<command>]", 1767b070a547SArnaldo Carvalho de Melo NULL 1768b070a547SArnaldo Carvalho de Melo }; 1769cc03c542SNamhyung Kim int status = -EINVAL, run_idx; 17704aa9015fSStephane Eranian const char *mode; 177142202dd5SIngo Molnar 17725af52b51SStephane Eranian setlocale(LC_ALL, ""); 17735af52b51SStephane Eranian 1774334fe7a3SNamhyung Kim evsel_list = perf_evlist__new(); 1775361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 1776361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1777361c99a6SArnaldo Carvalho de Melo 1778a0541234SAnton Blanchard argc = parse_options(argc, argv, options, stat_usage, 1779a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 1780d7470b6aSStephane Eranian 17814aa9015fSStephane Eranian output = stderr; 17824aa9015fSStephane Eranian if (output_name && strcmp(output_name, "-")) 17834aa9015fSStephane Eranian output = NULL; 17844aa9015fSStephane Eranian 178556f3bae7SJim Cromie if (output_name && output_fd) { 178656f3bae7SJim Cromie fprintf(stderr, "cannot use both --output and --log-fd\n"); 1787cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "o", 1); 1788cc03c542SNamhyung Kim parse_options_usage(NULL, options, "log-fd", 0); 1789cc03c542SNamhyung Kim goto out; 179056f3bae7SJim Cromie } 1791fc3e4d07SStephane Eranian 1792fc3e4d07SStephane Eranian if (output_fd < 0) { 1793fc3e4d07SStephane Eranian fprintf(stderr, "argument to --log-fd must be a > 0\n"); 1794cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "log-fd", 0); 1795cc03c542SNamhyung Kim goto out; 1796fc3e4d07SStephane Eranian } 1797fc3e4d07SStephane Eranian 17984aa9015fSStephane Eranian if (!output) { 17994aa9015fSStephane Eranian struct timespec tm; 18004aa9015fSStephane Eranian mode = append_file ? "a" : "w"; 18014aa9015fSStephane Eranian 18024aa9015fSStephane Eranian output = fopen(output_name, mode); 18034aa9015fSStephane Eranian if (!output) { 18044aa9015fSStephane Eranian perror("failed to create output file"); 1805fceda7feSDavid Ahern return -1; 18064aa9015fSStephane Eranian } 18074aa9015fSStephane Eranian clock_gettime(CLOCK_REALTIME, &tm); 18084aa9015fSStephane Eranian fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 1809fc3e4d07SStephane Eranian } else if (output_fd > 0) { 181056f3bae7SJim Cromie mode = append_file ? "a" : "w"; 181156f3bae7SJim Cromie output = fdopen(output_fd, mode); 181256f3bae7SJim Cromie if (!output) { 181356f3bae7SJim Cromie perror("Failed opening logfd"); 181456f3bae7SJim Cromie return -errno; 181556f3bae7SJim Cromie } 18164aa9015fSStephane Eranian } 18174aa9015fSStephane Eranian 1818d4ffd04dSJim Cromie if (csv_sep) { 1819d7470b6aSStephane Eranian csv_output = true; 1820d4ffd04dSJim Cromie if (!strcmp(csv_sep, "\\t")) 1821d4ffd04dSJim Cromie csv_sep = "\t"; 1822d4ffd04dSJim Cromie } else 1823d7470b6aSStephane Eranian csv_sep = DEFAULT_SEPARATOR; 1824d7470b6aSStephane Eranian 1825d7470b6aSStephane Eranian /* 1826d7470b6aSStephane Eranian * let the spreadsheet do the pretty-printing 1827d7470b6aSStephane Eranian */ 1828d7470b6aSStephane Eranian if (csv_output) { 182961a9f324SJim Cromie /* User explicitly passed -B? */ 1830d7470b6aSStephane Eranian if (big_num_opt == 1) { 1831d7470b6aSStephane Eranian fprintf(stderr, "-B option not supported with -x\n"); 1832cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "B", 1); 1833cc03c542SNamhyung Kim parse_options_usage(NULL, options, "x", 1); 1834cc03c542SNamhyung Kim goto out; 1835d7470b6aSStephane Eranian } else /* Nope, so disable big number formatting */ 1836d7470b6aSStephane Eranian big_num = false; 1837d7470b6aSStephane Eranian } else if (big_num_opt == 0) /* User passed --no-big-num */ 1838d7470b6aSStephane Eranian big_num = false; 1839d7470b6aSStephane Eranian 1840602ad878SArnaldo Carvalho de Melo if (!argc && target__none(&target)) 184186470930SIngo Molnar usage_with_options(stat_usage, options); 1842ac3063bdSDavid Ahern 1843a7e191c3SFrederik Deweerdt if (run_count < 0) { 1844cc03c542SNamhyung Kim pr_err("Run count must be a positive number\n"); 1845cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "r", 1); 1846cc03c542SNamhyung Kim goto out; 1847a7e191c3SFrederik Deweerdt } else if (run_count == 0) { 1848a7e191c3SFrederik Deweerdt forever = true; 1849a7e191c3SFrederik Deweerdt run_count = 1; 1850a7e191c3SFrederik Deweerdt } 185186470930SIngo Molnar 1852023695d9SStephane Eranian /* no_aggr, cgroup are for system-wide only */ 1853602ad878SArnaldo Carvalho de Melo if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) && 1854602ad878SArnaldo Carvalho de Melo !target__has_cpu(&target)) { 1855023695d9SStephane Eranian fprintf(stderr, "both cgroup and no-aggregation " 1856023695d9SStephane Eranian "modes only available in system-wide mode\n"); 1857023695d9SStephane Eranian 1858cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "G", 1); 1859cc03c542SNamhyung Kim parse_options_usage(NULL, options, "A", 1); 1860cc03c542SNamhyung Kim parse_options_usage(NULL, options, "a", 1); 1861cc03c542SNamhyung Kim goto out; 1862d7e7a451SStephane Eranian } 1863d7e7a451SStephane Eranian 18642cba3ffbSIngo Molnar if (add_default_attributes()) 1865c6264defSIngo Molnar goto out; 186686470930SIngo Molnar 1867602ad878SArnaldo Carvalho de Melo target__validate(&target); 18685c98d466SArnaldo Carvalho de Melo 186977a6f014SNamhyung Kim if (perf_evlist__create_maps(evsel_list, &target) < 0) { 1870602ad878SArnaldo Carvalho de Melo if (target__has_task(&target)) { 18715c98d466SArnaldo Carvalho de Melo pr_err("Problems finding threads of monitor\n"); 1872cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "p", 1); 1873cc03c542SNamhyung Kim parse_options_usage(NULL, options, "t", 1); 1874602ad878SArnaldo Carvalho de Melo } else if (target__has_cpu(&target)) { 187560d567e2SArnaldo Carvalho de Melo perror("failed to parse CPUs map"); 1876cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "C", 1); 1877cc03c542SNamhyung Kim parse_options_usage(NULL, options, "a", 1); 1878cc03c542SNamhyung Kim } 1879cc03c542SNamhyung Kim goto out; 188060d567e2SArnaldo Carvalho de Melo } 188113370a9bSStephane Eranian if (interval && interval < 100) { 188213370a9bSStephane Eranian pr_err("print interval must be >= 100ms\n"); 1883cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "I", 1); 188403ad9747SArnaldo Carvalho de Melo goto out; 188513370a9bSStephane Eranian } 1886c45c6ea2SStephane Eranian 1887d134ffb9SArnaldo Carvalho de Melo if (perf_evlist__alloc_stats(evsel_list, interval)) 188803ad9747SArnaldo Carvalho de Melo goto out; 1889d6d901c2SZhang, Yanmin 189086ee6e18SStephane Eranian if (perf_stat_init_aggr_mode()) 189103ad9747SArnaldo Carvalho de Melo goto out; 189286ee6e18SStephane Eranian 189386470930SIngo Molnar /* 189486470930SIngo Molnar * We dont want to block the signals - that would cause 189586470930SIngo Molnar * child tasks to inherit that and Ctrl-C would not work. 189686470930SIngo Molnar * What we want is for Ctrl-C to work in the exec()-ed 189786470930SIngo Molnar * task, but being ignored by perf stat itself: 189886470930SIngo Molnar */ 1899f7b7c26eSPeter Zijlstra atexit(sig_atexit); 1900a7e191c3SFrederik Deweerdt if (!forever) 190186470930SIngo Molnar signal(SIGINT, skip_signal); 190213370a9bSStephane Eranian signal(SIGCHLD, skip_signal); 190386470930SIngo Molnar signal(SIGALRM, skip_signal); 190486470930SIngo Molnar signal(SIGABRT, skip_signal); 190586470930SIngo Molnar 190642202dd5SIngo Molnar status = 0; 1907a7e191c3SFrederik Deweerdt for (run_idx = 0; forever || run_idx < run_count; run_idx++) { 190842202dd5SIngo Molnar if (run_count != 1 && verbose) 19094aa9015fSStephane Eranian fprintf(output, "[ perf stat: executing run #%d ... ]\n", 19104aa9015fSStephane Eranian run_idx + 1); 1911f9cef0a9SIngo Molnar 191242202dd5SIngo Molnar status = run_perf_stat(argc, argv); 1913a7e191c3SFrederik Deweerdt if (forever && status != -1) { 1914a7e191c3SFrederik Deweerdt print_stat(argc, argv); 1915d134ffb9SArnaldo Carvalho de Melo perf_stat__reset_stats(evsel_list); 1916a7e191c3SFrederik Deweerdt } 191742202dd5SIngo Molnar } 191842202dd5SIngo Molnar 1919a7e191c3SFrederik Deweerdt if (!forever && status != -1 && !interval) 192042202dd5SIngo Molnar print_stat(argc, argv); 1921d134ffb9SArnaldo Carvalho de Melo 1922d134ffb9SArnaldo Carvalho de Melo perf_evlist__free_stats(evsel_list); 19230015e2e1SArnaldo Carvalho de Melo out: 19240015e2e1SArnaldo Carvalho de Melo perf_evlist__delete(evsel_list); 192542202dd5SIngo Molnar return status; 192686470930SIngo Molnar } 1927