186470930SIngo Molnar /* 286470930SIngo Molnar * builtin-stat.c 386470930SIngo Molnar * 486470930SIngo Molnar * Builtin stat command: Give a precise performance counters summary 586470930SIngo Molnar * overview about any workload, CPU or specific PID. 686470930SIngo Molnar * 786470930SIngo Molnar * Sample output: 886470930SIngo Molnar 92cba3ffbSIngo Molnar $ perf stat ./hackbench 10 1086470930SIngo Molnar 112cba3ffbSIngo Molnar Time: 0.118 1286470930SIngo Molnar 132cba3ffbSIngo Molnar Performance counter stats for './hackbench 10': 1486470930SIngo Molnar 152cba3ffbSIngo Molnar 1708.761321 task-clock # 11.037 CPUs utilized 162cba3ffbSIngo Molnar 41,190 context-switches # 0.024 M/sec 172cba3ffbSIngo Molnar 6,735 CPU-migrations # 0.004 M/sec 182cba3ffbSIngo Molnar 17,318 page-faults # 0.010 M/sec 192cba3ffbSIngo Molnar 5,205,202,243 cycles # 3.046 GHz 202cba3ffbSIngo Molnar 3,856,436,920 stalled-cycles-frontend # 74.09% frontend cycles idle 212cba3ffbSIngo Molnar 1,600,790,871 stalled-cycles-backend # 30.75% backend cycles idle 222cba3ffbSIngo Molnar 2,603,501,247 instructions # 0.50 insns per cycle 232cba3ffbSIngo Molnar # 1.48 stalled cycles per insn 242cba3ffbSIngo Molnar 484,357,498 branches # 283.455 M/sec 252cba3ffbSIngo Molnar 6,388,934 branch-misses # 1.32% of all branches 262cba3ffbSIngo Molnar 272cba3ffbSIngo Molnar 0.154822978 seconds time elapsed 2886470930SIngo Molnar 2986470930SIngo Molnar * 302cba3ffbSIngo Molnar * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 3186470930SIngo Molnar * 3286470930SIngo Molnar * Improvements and fixes by: 3386470930SIngo Molnar * 3486470930SIngo Molnar * Arjan van de Ven <arjan@linux.intel.com> 3586470930SIngo Molnar * Yanmin Zhang <yanmin.zhang@intel.com> 3686470930SIngo Molnar * Wu Fengguang <fengguang.wu@intel.com> 3786470930SIngo Molnar * Mike Galbraith <efault@gmx.de> 3886470930SIngo Molnar * Paul Mackerras <paulus@samba.org> 396e750a8fSJaswinder Singh Rajput * Jaswinder Singh Rajput <jaswinder@kernel.org> 4086470930SIngo Molnar * 4186470930SIngo Molnar * Released under the GPL v2. (and only v2, not any later version) 4286470930SIngo Molnar */ 4386470930SIngo Molnar 4486470930SIngo Molnar #include "perf.h" 4586470930SIngo Molnar #include "builtin.h" 4686470930SIngo Molnar #include "util/util.h" 4786470930SIngo Molnar #include "util/parse-options.h" 4886470930SIngo Molnar #include "util/parse-events.h" 494cabc3d1SAndi Kleen #include "util/pmu.h" 508f28827aSFrederic Weisbecker #include "util/event.h" 51361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 5269aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 538f28827aSFrederic Weisbecker #include "util/debug.h" 54a5d243d0SIngo Molnar #include "util/color.h" 550007eceaSXiao Guangrong #include "util/stat.h" 5660666c63SLiming Wang #include "util/header.h" 57a12b51c4SPaul Mackerras #include "util/cpumap.h" 58d6d901c2SZhang, Yanmin #include "util/thread.h" 59fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 6086470930SIngo Molnar 611f16c575SPeter Zijlstra #include <stdlib.h> 6286470930SIngo Molnar #include <sys/prctl.h> 635af52b51SStephane Eranian #include <locale.h> 6486470930SIngo Molnar 65d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR " " 662cee77c4SDavid Ahern #define CNTR_NOT_SUPPORTED "<not supported>" 672cee77c4SDavid Ahern #define CNTR_NOT_COUNTED "<not counted>" 68d7470b6aSStephane Eranian 6913370a9bSStephane Eranian static void print_stat(int argc, const char **argv); 7013370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix); 7113370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix); 7286ee6e18SStephane Eranian static void print_aggr(char *prefix); 7313370a9bSStephane Eranian 744cabc3d1SAndi Kleen /* Default events used for perf stat -T */ 754cabc3d1SAndi Kleen static const char * const transaction_attrs[] = { 764cabc3d1SAndi Kleen "task-clock", 774cabc3d1SAndi Kleen "{" 784cabc3d1SAndi Kleen "instructions," 794cabc3d1SAndi Kleen "cycles," 804cabc3d1SAndi Kleen "cpu/cycles-t/," 814cabc3d1SAndi Kleen "cpu/tx-start/," 824cabc3d1SAndi Kleen "cpu/el-start/," 834cabc3d1SAndi Kleen "cpu/cycles-ct/" 844cabc3d1SAndi Kleen "}" 854cabc3d1SAndi Kleen }; 864cabc3d1SAndi Kleen 874cabc3d1SAndi Kleen /* More limited version when the CPU does not have all events. */ 884cabc3d1SAndi Kleen static const char * const transaction_limited_attrs[] = { 894cabc3d1SAndi Kleen "task-clock", 904cabc3d1SAndi Kleen "{" 914cabc3d1SAndi Kleen "instructions," 924cabc3d1SAndi Kleen "cycles," 934cabc3d1SAndi Kleen "cpu/cycles-t/," 944cabc3d1SAndi Kleen "cpu/tx-start/" 954cabc3d1SAndi Kleen "}" 964cabc3d1SAndi Kleen }; 974cabc3d1SAndi Kleen 984cabc3d1SAndi Kleen /* must match transaction_attrs and the beginning limited_attrs */ 994cabc3d1SAndi Kleen enum { 1004cabc3d1SAndi Kleen T_TASK_CLOCK, 1014cabc3d1SAndi Kleen T_INSTRUCTIONS, 1024cabc3d1SAndi Kleen T_CYCLES, 1034cabc3d1SAndi Kleen T_CYCLES_IN_TX, 1044cabc3d1SAndi Kleen T_TRANSACTION_START, 1054cabc3d1SAndi Kleen T_ELISION_START, 1064cabc3d1SAndi Kleen T_CYCLES_IN_TX_CP, 1074cabc3d1SAndi Kleen }; 1084cabc3d1SAndi Kleen 109666e6d48SRobert Richter static struct perf_evlist *evsel_list; 110361c99a6SArnaldo Carvalho de Melo 111602ad878SArnaldo Carvalho de Melo static struct target target = { 11277a6f014SNamhyung Kim .uid = UINT_MAX, 11377a6f014SNamhyung Kim }; 11442202dd5SIngo Molnar 11586ee6e18SStephane Eranian enum aggr_mode { 11686ee6e18SStephane Eranian AGGR_NONE, 11786ee6e18SStephane Eranian AGGR_GLOBAL, 11886ee6e18SStephane Eranian AGGR_SOCKET, 11912c08a9fSStephane Eranian AGGR_CORE, 12086ee6e18SStephane Eranian }; 12186ee6e18SStephane Eranian 1223d632595SJaswinder Singh Rajput static int run_count = 1; 1232e6cdf99SStephane Eranian static bool no_inherit = false; 124c0555642SIan Munsie static bool scale = true; 12586ee6e18SStephane Eranian static enum aggr_mode aggr_mode = AGGR_GLOBAL; 126d07f0b12SStephane Eranian static volatile pid_t child_pid = -1; 127c0555642SIan Munsie static bool null_run = false; 1282cba3ffbSIngo Molnar static int detailed_run = 0; 1294cabc3d1SAndi Kleen static bool transaction_run; 130201e0b06SArnaldo Carvalho de Melo static bool big_num = true; 131d7470b6aSStephane Eranian static int big_num_opt = -1; 132d7470b6aSStephane Eranian static const char *csv_sep = NULL; 133d7470b6aSStephane Eranian static bool csv_output = false; 13443bece79SLin Ming static bool group = false; 1354aa9015fSStephane Eranian static FILE *output = NULL; 1361f16c575SPeter Zijlstra static const char *pre_cmd = NULL; 1371f16c575SPeter Zijlstra static const char *post_cmd = NULL; 1381f16c575SPeter Zijlstra static bool sync_run = false; 13913370a9bSStephane Eranian static unsigned int interval = 0; 14041191688SAndi Kleen static unsigned int initial_delay = 0; 141a7e191c3SFrederik Deweerdt static bool forever = false; 14213370a9bSStephane Eranian static struct timespec ref_time; 14386ee6e18SStephane Eranian static struct cpu_map *aggr_map; 14486ee6e18SStephane Eranian static int (*aggr_get_id)(struct cpu_map *m, int cpu); 1455af52b51SStephane Eranian 14660666c63SLiming Wang static volatile int done = 0; 14760666c63SLiming Wang 14869aad6f1SArnaldo Carvalho de Melo struct perf_stat { 14969aad6f1SArnaldo Carvalho de Melo struct stats res_stats[3]; 15069aad6f1SArnaldo Carvalho de Melo }; 15169aad6f1SArnaldo Carvalho de Melo 15213370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a, 15313370a9bSStephane Eranian struct timespec *b) 15413370a9bSStephane Eranian { 15513370a9bSStephane Eranian r->tv_sec = a->tv_sec - b->tv_sec; 15613370a9bSStephane Eranian if (a->tv_nsec < b->tv_nsec) { 15713370a9bSStephane Eranian r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec; 15813370a9bSStephane Eranian r->tv_sec--; 15913370a9bSStephane Eranian } else { 16013370a9bSStephane Eranian r->tv_nsec = a->tv_nsec - b->tv_nsec ; 16113370a9bSStephane Eranian } 16213370a9bSStephane Eranian } 16313370a9bSStephane Eranian 16413370a9bSStephane Eranian static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) 16513370a9bSStephane Eranian { 16613370a9bSStephane Eranian return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus; 16713370a9bSStephane Eranian } 16813370a9bSStephane Eranian 16913370a9bSStephane Eranian static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) 17013370a9bSStephane Eranian { 17113370a9bSStephane Eranian return perf_evsel__cpus(evsel)->nr; 17213370a9bSStephane Eranian } 17313370a9bSStephane Eranian 174a7e191c3SFrederik Deweerdt static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) 175a7e191c3SFrederik Deweerdt { 176a7e191c3SFrederik Deweerdt memset(evsel->priv, 0, sizeof(struct perf_stat)); 177a7e191c3SFrederik Deweerdt } 178a7e191c3SFrederik Deweerdt 179c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) 18069aad6f1SArnaldo Carvalho de Melo { 181c52b12edSArnaldo Carvalho de Melo evsel->priv = zalloc(sizeof(struct perf_stat)); 18269aad6f1SArnaldo Carvalho de Melo return evsel->priv == NULL ? -ENOMEM : 0; 18369aad6f1SArnaldo Carvalho de Melo } 18469aad6f1SArnaldo Carvalho de Melo 18569aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) 18669aad6f1SArnaldo Carvalho de Melo { 18769aad6f1SArnaldo Carvalho de Melo free(evsel->priv); 18869aad6f1SArnaldo Carvalho de Melo evsel->priv = NULL; 18969aad6f1SArnaldo Carvalho de Melo } 19069aad6f1SArnaldo Carvalho de Melo 19113370a9bSStephane Eranian static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel) 1927ae92e74SYan, Zheng { 19313370a9bSStephane Eranian void *addr; 19413370a9bSStephane Eranian size_t sz; 19513370a9bSStephane Eranian 19613370a9bSStephane Eranian sz = sizeof(*evsel->counts) + 19713370a9bSStephane Eranian (perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values)); 19813370a9bSStephane Eranian 19913370a9bSStephane Eranian addr = zalloc(sz); 20013370a9bSStephane Eranian if (!addr) 20113370a9bSStephane Eranian return -ENOMEM; 20213370a9bSStephane Eranian 20313370a9bSStephane Eranian evsel->prev_raw_counts = addr; 20413370a9bSStephane Eranian 20513370a9bSStephane Eranian return 0; 2067ae92e74SYan, Zheng } 2077ae92e74SYan, Zheng 20813370a9bSStephane Eranian static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) 2097ae92e74SYan, Zheng { 21013370a9bSStephane Eranian free(evsel->prev_raw_counts); 21113370a9bSStephane Eranian evsel->prev_raw_counts = NULL; 2127ae92e74SYan, Zheng } 2137ae92e74SYan, Zheng 214d134ffb9SArnaldo Carvalho de Melo static void perf_evlist__free_stats(struct perf_evlist *evlist) 215d134ffb9SArnaldo Carvalho de Melo { 216d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 217d134ffb9SArnaldo Carvalho de Melo 218d134ffb9SArnaldo Carvalho de Melo list_for_each_entry(evsel, &evlist->entries, node) { 219d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_stat_priv(evsel); 220d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_counts(evsel); 221d134ffb9SArnaldo Carvalho de Melo perf_evsel__free_prev_raw_counts(evsel); 222d134ffb9SArnaldo Carvalho de Melo } 223d134ffb9SArnaldo Carvalho de Melo } 224d134ffb9SArnaldo Carvalho de Melo 225d134ffb9SArnaldo Carvalho de Melo static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw) 226d134ffb9SArnaldo Carvalho de Melo { 227d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 228d134ffb9SArnaldo Carvalho de Melo 229d134ffb9SArnaldo Carvalho de Melo list_for_each_entry(evsel, &evlist->entries, node) { 230d134ffb9SArnaldo Carvalho de Melo if (perf_evsel__alloc_stat_priv(evsel) < 0 || 231d134ffb9SArnaldo Carvalho de Melo perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 || 232d134ffb9SArnaldo Carvalho de Melo (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0)) 233d134ffb9SArnaldo Carvalho de Melo goto out_free; 234d134ffb9SArnaldo Carvalho de Melo } 235d134ffb9SArnaldo Carvalho de Melo 236d134ffb9SArnaldo Carvalho de Melo return 0; 237d134ffb9SArnaldo Carvalho de Melo 238d134ffb9SArnaldo Carvalho de Melo out_free: 239d134ffb9SArnaldo Carvalho de Melo perf_evlist__free_stats(evlist); 240d134ffb9SArnaldo Carvalho de Melo return -1; 241d134ffb9SArnaldo Carvalho de Melo } 242d134ffb9SArnaldo Carvalho de Melo 243666e6d48SRobert Richter static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 244666e6d48SRobert Richter static struct stats runtime_cycles_stats[MAX_NR_CPUS]; 245666e6d48SRobert Richter static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS]; 246666e6d48SRobert Richter static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS]; 247666e6d48SRobert Richter static struct stats runtime_branches_stats[MAX_NR_CPUS]; 248666e6d48SRobert Richter static struct stats runtime_cacherefs_stats[MAX_NR_CPUS]; 249666e6d48SRobert Richter static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS]; 250666e6d48SRobert Richter static struct stats runtime_l1_icache_stats[MAX_NR_CPUS]; 251666e6d48SRobert Richter static struct stats runtime_ll_cache_stats[MAX_NR_CPUS]; 252666e6d48SRobert Richter static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; 253666e6d48SRobert Richter static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; 2544cabc3d1SAndi Kleen static struct stats runtime_cycles_in_tx_stats[MAX_NR_CPUS]; 255666e6d48SRobert Richter static struct stats walltime_nsecs_stats; 2564cabc3d1SAndi Kleen static struct stats runtime_transaction_stats[MAX_NR_CPUS]; 2574cabc3d1SAndi Kleen static struct stats runtime_elision_stats[MAX_NR_CPUS]; 25886470930SIngo Molnar 259d134ffb9SArnaldo Carvalho de Melo static void perf_stat__reset_stats(struct perf_evlist *evlist) 260a7e191c3SFrederik Deweerdt { 261d134ffb9SArnaldo Carvalho de Melo struct perf_evsel *evsel; 262d134ffb9SArnaldo Carvalho de Melo 263d134ffb9SArnaldo Carvalho de Melo list_for_each_entry(evsel, &evlist->entries, node) { 264d134ffb9SArnaldo Carvalho de Melo perf_evsel__reset_stat_priv(evsel); 265d134ffb9SArnaldo Carvalho de Melo perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel)); 266d134ffb9SArnaldo Carvalho de Melo } 267d134ffb9SArnaldo Carvalho de Melo 268a7e191c3SFrederik Deweerdt memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats)); 269a7e191c3SFrederik Deweerdt memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats)); 270a7e191c3SFrederik Deweerdt memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats)); 271a7e191c3SFrederik Deweerdt memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats)); 272a7e191c3SFrederik Deweerdt memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats)); 273a7e191c3SFrederik Deweerdt memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats)); 274a7e191c3SFrederik Deweerdt memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats)); 275a7e191c3SFrederik Deweerdt memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats)); 276a7e191c3SFrederik Deweerdt memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats)); 277a7e191c3SFrederik Deweerdt memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats)); 278a7e191c3SFrederik Deweerdt memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats)); 2794cabc3d1SAndi Kleen memset(runtime_cycles_in_tx_stats, 0, 2804cabc3d1SAndi Kleen sizeof(runtime_cycles_in_tx_stats)); 2814cabc3d1SAndi Kleen memset(runtime_transaction_stats, 0, 2824cabc3d1SAndi Kleen sizeof(runtime_transaction_stats)); 2834cabc3d1SAndi Kleen memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats)); 284a7e191c3SFrederik Deweerdt memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats)); 285a7e191c3SFrederik Deweerdt } 286a7e191c3SFrederik Deweerdt 287cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel) 28886470930SIngo Molnar { 28969aad6f1SArnaldo Carvalho de Melo struct perf_event_attr *attr = &evsel->attr; 290727ab04eSArnaldo Carvalho de Melo 29186470930SIngo Molnar if (scale) 29286470930SIngo Molnar attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 29386470930SIngo Molnar PERF_FORMAT_TOTAL_TIME_RUNNING; 29486470930SIngo Molnar 2952e6cdf99SStephane Eranian attr->inherit = !no_inherit; 2965d2cd909SArnaldo Carvalho de Melo 297602ad878SArnaldo Carvalho de Melo if (target__has_cpu(&target)) 298594ac61aSArnaldo Carvalho de Melo return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); 2995622c07bSStephane Eranian 300602ad878SArnaldo Carvalho de Melo if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) { 30186470930SIngo Molnar attr->disabled = 1; 30241191688SAndi Kleen if (!initial_delay) 30357e7986eSPaul Mackerras attr->enable_on_exec = 1; 3046be2850eSZhang, Yanmin } 305084ab9f8SArnaldo Carvalho de Melo 306594ac61aSArnaldo Carvalho de Melo return perf_evsel__open_per_thread(evsel, evsel_list->threads); 30786470930SIngo Molnar } 30886470930SIngo Molnar 30986470930SIngo Molnar /* 31086470930SIngo Molnar * Does the counter have nsecs as a unit? 31186470930SIngo Molnar */ 312daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel) 31386470930SIngo Molnar { 314daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || 315daec78a0SArnaldo Carvalho de Melo perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 31686470930SIngo Molnar return 1; 31786470930SIngo Molnar 31886470930SIngo Molnar return 0; 31986470930SIngo Molnar } 32086470930SIngo Molnar 3214cabc3d1SAndi Kleen static struct perf_evsel *nth_evsel(int n) 3224cabc3d1SAndi Kleen { 3234cabc3d1SAndi Kleen static struct perf_evsel **array; 3244cabc3d1SAndi Kleen static int array_len; 3254cabc3d1SAndi Kleen struct perf_evsel *ev; 3264cabc3d1SAndi Kleen int j; 3274cabc3d1SAndi Kleen 3284cabc3d1SAndi Kleen /* Assumes this only called when evsel_list does not change anymore. */ 3294cabc3d1SAndi Kleen if (!array) { 3304cabc3d1SAndi Kleen list_for_each_entry(ev, &evsel_list->entries, node) 3314cabc3d1SAndi Kleen array_len++; 3324cabc3d1SAndi Kleen array = malloc(array_len * sizeof(void *)); 3334cabc3d1SAndi Kleen if (!array) 3344cabc3d1SAndi Kleen exit(ENOMEM); 3354cabc3d1SAndi Kleen j = 0; 3364cabc3d1SAndi Kleen list_for_each_entry(ev, &evsel_list->entries, node) 3374cabc3d1SAndi Kleen array[j++] = ev; 3384cabc3d1SAndi Kleen } 3394cabc3d1SAndi Kleen if (n < array_len) 3404cabc3d1SAndi Kleen return array[n]; 3414cabc3d1SAndi Kleen return NULL; 3424cabc3d1SAndi Kleen } 3434cabc3d1SAndi Kleen 34486470930SIngo Molnar /* 345dcd9936aSIngo Molnar * Update various tracking values we maintain to print 346dcd9936aSIngo Molnar * more semantic information such as miss/hit ratios, 347dcd9936aSIngo Molnar * instruction rates, etc: 348dcd9936aSIngo Molnar */ 349dcd9936aSIngo Molnar static void update_shadow_stats(struct perf_evsel *counter, u64 *count) 350dcd9936aSIngo Molnar { 351dcd9936aSIngo Molnar if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 352dcd9936aSIngo Molnar update_stats(&runtime_nsecs_stats[0], count[0]); 353dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 354dcd9936aSIngo Molnar update_stats(&runtime_cycles_stats[0], count[0]); 3554cabc3d1SAndi Kleen else if (transaction_run && 3564cabc3d1SAndi Kleen perf_evsel__cmp(counter, nth_evsel(T_CYCLES_IN_TX))) 3574cabc3d1SAndi Kleen update_stats(&runtime_cycles_in_tx_stats[0], count[0]); 3584cabc3d1SAndi Kleen else if (transaction_run && 3594cabc3d1SAndi Kleen perf_evsel__cmp(counter, nth_evsel(T_TRANSACTION_START))) 3604cabc3d1SAndi Kleen update_stats(&runtime_transaction_stats[0], count[0]); 3614cabc3d1SAndi Kleen else if (transaction_run && 3624cabc3d1SAndi Kleen perf_evsel__cmp(counter, nth_evsel(T_ELISION_START))) 3634cabc3d1SAndi Kleen update_stats(&runtime_elision_stats[0], count[0]); 364d3d1e86dSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) 365d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_front_stats[0], count[0]); 366129c04cbSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) 367d3d1e86dSIngo Molnar update_stats(&runtime_stalled_cycles_back_stats[0], count[0]); 368dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS)) 369dcd9936aSIngo Molnar update_stats(&runtime_branches_stats[0], count[0]); 370dcd9936aSIngo Molnar else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES)) 371dcd9936aSIngo Molnar update_stats(&runtime_cacherefs_stats[0], count[0]); 3728bb6c79fSIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D)) 3738bb6c79fSIngo Molnar update_stats(&runtime_l1_dcache_stats[0], count[0]); 374c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I)) 375c3305257SIngo Molnar update_stats(&runtime_l1_icache_stats[0], count[0]); 376c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL)) 377c3305257SIngo Molnar update_stats(&runtime_ll_cache_stats[0], count[0]); 378c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB)) 379c3305257SIngo Molnar update_stats(&runtime_dtlb_cache_stats[0], count[0]); 380c3305257SIngo Molnar else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) 381c3305257SIngo Molnar update_stats(&runtime_itlb_cache_stats[0], count[0]); 382dcd9936aSIngo Molnar } 383dcd9936aSIngo Molnar 384dcd9936aSIngo Molnar /* 38586470930SIngo Molnar * Read out the results of a single counter: 386f5b4a9c3SStephane Eranian * aggregate counts across CPUs in system-wide mode 38786470930SIngo Molnar */ 388c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter) 38986470930SIngo Molnar { 39069aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 391c52b12edSArnaldo Carvalho de Melo u64 *count = counter->counts->aggr.values; 392c52b12edSArnaldo Carvalho de Melo int i; 39386470930SIngo Molnar 3947ae92e74SYan, Zheng if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter), 395b3a319d5SNamhyung Kim thread_map__nr(evsel_list->threads), scale) < 0) 396c52b12edSArnaldo Carvalho de Melo return -1; 3979e9772c4SPeter Zijlstra 3989e9772c4SPeter Zijlstra for (i = 0; i < 3; i++) 39969aad6f1SArnaldo Carvalho de Melo update_stats(&ps->res_stats[i], count[i]); 4009e9772c4SPeter Zijlstra 4019e9772c4SPeter Zijlstra if (verbose) { 4024aa9015fSStephane Eranian fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 4037289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter), count[0], count[1], count[2]); 4049e9772c4SPeter Zijlstra } 4059e9772c4SPeter Zijlstra 40686470930SIngo Molnar /* 40786470930SIngo Molnar * Save the full runtime - to allow normalization during printout: 40886470930SIngo Molnar */ 409dcd9936aSIngo Molnar update_shadow_stats(counter, count); 410c52b12edSArnaldo Carvalho de Melo 411c52b12edSArnaldo Carvalho de Melo return 0; 412f5b4a9c3SStephane Eranian } 413f5b4a9c3SStephane Eranian 414f5b4a9c3SStephane Eranian /* 415f5b4a9c3SStephane Eranian * Read out the results of a single counter: 416f5b4a9c3SStephane Eranian * do not aggregate counts across CPUs in system-wide mode 417f5b4a9c3SStephane Eranian */ 418c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter) 419f5b4a9c3SStephane Eranian { 420c52b12edSArnaldo Carvalho de Melo u64 *count; 421f5b4a9c3SStephane Eranian int cpu; 422f5b4a9c3SStephane Eranian 4237ae92e74SYan, Zheng for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 424c52b12edSArnaldo Carvalho de Melo if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) 425c52b12edSArnaldo Carvalho de Melo return -1; 426f5b4a9c3SStephane Eranian 427c52b12edSArnaldo Carvalho de Melo count = counter->counts->cpu[cpu].values; 428f5b4a9c3SStephane Eranian 429dcd9936aSIngo Molnar update_shadow_stats(counter, count); 430f5b4a9c3SStephane Eranian } 431c52b12edSArnaldo Carvalho de Melo 432c52b12edSArnaldo Carvalho de Melo return 0; 43386470930SIngo Molnar } 43486470930SIngo Molnar 43513370a9bSStephane Eranian static void print_interval(void) 43613370a9bSStephane Eranian { 43713370a9bSStephane Eranian static int num_print_interval; 43813370a9bSStephane Eranian struct perf_evsel *counter; 43913370a9bSStephane Eranian struct perf_stat *ps; 44013370a9bSStephane Eranian struct timespec ts, rs; 44113370a9bSStephane Eranian char prefix[64]; 44213370a9bSStephane Eranian 44386ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) { 44413370a9bSStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) { 44513370a9bSStephane Eranian ps = counter->priv; 44613370a9bSStephane Eranian memset(ps->res_stats, 0, sizeof(ps->res_stats)); 44713370a9bSStephane Eranian read_counter_aggr(counter); 44813370a9bSStephane Eranian } 44986ee6e18SStephane Eranian } else { 45086ee6e18SStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) { 45186ee6e18SStephane Eranian ps = counter->priv; 45286ee6e18SStephane Eranian memset(ps->res_stats, 0, sizeof(ps->res_stats)); 45386ee6e18SStephane Eranian read_counter(counter); 45413370a9bSStephane Eranian } 45586ee6e18SStephane Eranian } 45686ee6e18SStephane Eranian 45713370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ts); 45813370a9bSStephane Eranian diff_timespec(&rs, &ts, &ref_time); 45913370a9bSStephane Eranian sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep); 46013370a9bSStephane Eranian 46113370a9bSStephane Eranian if (num_print_interval == 0 && !csv_output) { 46286ee6e18SStephane Eranian switch (aggr_mode) { 46386ee6e18SStephane Eranian case AGGR_SOCKET: 464d7e7a451SStephane Eranian fprintf(output, "# time socket cpus counts events\n"); 46586ee6e18SStephane Eranian break; 46612c08a9fSStephane Eranian case AGGR_CORE: 46712c08a9fSStephane Eranian fprintf(output, "# time core cpus counts events\n"); 46812c08a9fSStephane Eranian break; 46986ee6e18SStephane Eranian case AGGR_NONE: 47013370a9bSStephane Eranian fprintf(output, "# time CPU counts events\n"); 47186ee6e18SStephane Eranian break; 47286ee6e18SStephane Eranian case AGGR_GLOBAL: 47386ee6e18SStephane Eranian default: 47413370a9bSStephane Eranian fprintf(output, "# time counts events\n"); 47513370a9bSStephane Eranian } 47686ee6e18SStephane Eranian } 47713370a9bSStephane Eranian 47813370a9bSStephane Eranian if (++num_print_interval == 25) 47913370a9bSStephane Eranian num_print_interval = 0; 48013370a9bSStephane Eranian 48186ee6e18SStephane Eranian switch (aggr_mode) { 48212c08a9fSStephane Eranian case AGGR_CORE: 48386ee6e18SStephane Eranian case AGGR_SOCKET: 48486ee6e18SStephane Eranian print_aggr(prefix); 48586ee6e18SStephane Eranian break; 48686ee6e18SStephane Eranian case AGGR_NONE: 48713370a9bSStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) 48813370a9bSStephane Eranian print_counter(counter, prefix); 48986ee6e18SStephane Eranian break; 49086ee6e18SStephane Eranian case AGGR_GLOBAL: 49186ee6e18SStephane Eranian default: 49213370a9bSStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) 49313370a9bSStephane Eranian print_counter_aggr(counter, prefix); 49413370a9bSStephane Eranian } 4952bbf03f1SAndi Kleen 4962bbf03f1SAndi Kleen fflush(output); 49713370a9bSStephane Eranian } 49813370a9bSStephane Eranian 49941191688SAndi Kleen static void handle_initial_delay(void) 50041191688SAndi Kleen { 50141191688SAndi Kleen struct perf_evsel *counter; 50241191688SAndi Kleen 50341191688SAndi Kleen if (initial_delay) { 50441191688SAndi Kleen const int ncpus = cpu_map__nr(evsel_list->cpus), 50541191688SAndi Kleen nthreads = thread_map__nr(evsel_list->threads); 50641191688SAndi Kleen 50741191688SAndi Kleen usleep(initial_delay * 1000); 50841191688SAndi Kleen list_for_each_entry(counter, &evsel_list->entries, node) 50941191688SAndi Kleen perf_evsel__enable(counter, ncpus, nthreads); 51041191688SAndi Kleen } 51141191688SAndi Kleen } 51241191688SAndi Kleen 513acf28922SNamhyung Kim static int __run_perf_stat(int argc, const char **argv) 51486470930SIngo Molnar { 51556e52e85SArnaldo Carvalho de Melo char msg[512]; 51686470930SIngo Molnar unsigned long long t0, t1; 517cac21425SJiri Olsa struct perf_evsel *counter; 51813370a9bSStephane Eranian struct timespec ts; 51942202dd5SIngo Molnar int status = 0; 5206be2850eSZhang, Yanmin const bool forks = (argc > 0); 52186470930SIngo Molnar 52213370a9bSStephane Eranian if (interval) { 52313370a9bSStephane Eranian ts.tv_sec = interval / 1000; 52413370a9bSStephane Eranian ts.tv_nsec = (interval % 1000) * 1000000; 52513370a9bSStephane Eranian } else { 52613370a9bSStephane Eranian ts.tv_sec = 1; 52713370a9bSStephane Eranian ts.tv_nsec = 0; 52813370a9bSStephane Eranian } 52913370a9bSStephane Eranian 530acf28922SNamhyung Kim if (forks) { 531acf28922SNamhyung Kim if (perf_evlist__prepare_workload(evsel_list, &target, argv, 532acf28922SNamhyung Kim false, false) < 0) { 533acf28922SNamhyung Kim perror("failed to prepare workload"); 534fceda7feSDavid Ahern return -1; 535051ae7f7SPaul Mackerras } 536d20a47e7SNamhyung Kim child_pid = evsel_list->workload.pid; 53760666c63SLiming Wang } 538051ae7f7SPaul Mackerras 5396a4bb04cSJiri Olsa if (group) 54063dab225SArnaldo Carvalho de Melo perf_evlist__set_leader(evsel_list); 5416a4bb04cSJiri Olsa 542361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 543cac21425SJiri Olsa if (create_perf_stat_counter(counter) < 0) { 544979987a5SDavid Ahern /* 545979987a5SDavid Ahern * PPC returns ENXIO for HW counters until 2.6.37 546979987a5SDavid Ahern * (behavior changed with commit b0a873e). 547979987a5SDavid Ahern */ 54838f6ae1eSAnton Blanchard if (errno == EINVAL || errno == ENOSYS || 549979987a5SDavid Ahern errno == ENOENT || errno == EOPNOTSUPP || 550979987a5SDavid Ahern errno == ENXIO) { 551c63ca0c0SDavid Ahern if (verbose) 552c63ca0c0SDavid Ahern ui__warning("%s event is not supported by the kernel.\n", 5537289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 5542cee77c4SDavid Ahern counter->supported = false; 555ede70290SIngo Molnar continue; 556c63ca0c0SDavid Ahern } 557ede70290SIngo Molnar 55856e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(counter, &target, 55956e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 56056e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 56156e52e85SArnaldo Carvalho de Melo 562084ab9f8SArnaldo Carvalho de Melo if (child_pid != -1) 563084ab9f8SArnaldo Carvalho de Melo kill(child_pid, SIGTERM); 564fceda7feSDavid Ahern 565084ab9f8SArnaldo Carvalho de Melo return -1; 566084ab9f8SArnaldo Carvalho de Melo } 5672cee77c4SDavid Ahern counter->supported = true; 56848290609SArnaldo Carvalho de Melo } 56986470930SIngo Molnar 5701491a632SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evsel_list)) { 571cfd748aeSFrederic Weisbecker error("failed to set filter with %d (%s)\n", errno, 572cfd748aeSFrederic Weisbecker strerror(errno)); 573cfd748aeSFrederic Weisbecker return -1; 574cfd748aeSFrederic Weisbecker } 575cfd748aeSFrederic Weisbecker 57686470930SIngo Molnar /* 57786470930SIngo Molnar * Enable counters and exec the command: 57886470930SIngo Molnar */ 57986470930SIngo Molnar t0 = rdclock(); 58013370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ref_time); 58186470930SIngo Molnar 58260666c63SLiming Wang if (forks) { 583acf28922SNamhyung Kim perf_evlist__start_workload(evsel_list); 58441191688SAndi Kleen handle_initial_delay(); 585acf28922SNamhyung Kim 58613370a9bSStephane Eranian if (interval) { 58713370a9bSStephane Eranian while (!waitpid(child_pid, &status, WNOHANG)) { 58813370a9bSStephane Eranian nanosleep(&ts, NULL); 58913370a9bSStephane Eranian print_interval(); 59013370a9bSStephane Eranian } 59113370a9bSStephane Eranian } 59242202dd5SIngo Molnar wait(&status); 59333e49ea7SAndi Kleen if (WIFSIGNALED(status)) 59433e49ea7SAndi Kleen psignal(WTERMSIG(status), argv[0]); 59560666c63SLiming Wang } else { 59641191688SAndi Kleen handle_initial_delay(); 59713370a9bSStephane Eranian while (!done) { 59813370a9bSStephane Eranian nanosleep(&ts, NULL); 59913370a9bSStephane Eranian if (interval) 60013370a9bSStephane Eranian print_interval(); 60113370a9bSStephane Eranian } 60260666c63SLiming Wang } 60386470930SIngo Molnar 60486470930SIngo Molnar t1 = rdclock(); 60586470930SIngo Molnar 6069e9772c4SPeter Zijlstra update_stats(&walltime_nsecs_stats, t1 - t0); 60742202dd5SIngo Molnar 60886ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) { 609361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) { 610c52b12edSArnaldo Carvalho de Melo read_counter_aggr(counter); 6117ae92e74SYan, Zheng perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 612b3a319d5SNamhyung Kim thread_map__nr(evsel_list->threads)); 613c52b12edSArnaldo Carvalho de Melo } 61486ee6e18SStephane Eranian } else { 61586ee6e18SStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) { 61686ee6e18SStephane Eranian read_counter(counter); 61786ee6e18SStephane Eranian perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1); 61886ee6e18SStephane Eranian } 619c52b12edSArnaldo Carvalho de Melo } 620c52b12edSArnaldo Carvalho de Melo 62142202dd5SIngo Molnar return WEXITSTATUS(status); 62242202dd5SIngo Molnar } 62342202dd5SIngo Molnar 6241f16c575SPeter Zijlstra static int run_perf_stat(int argc __maybe_unused, const char **argv) 6251f16c575SPeter Zijlstra { 6261f16c575SPeter Zijlstra int ret; 6271f16c575SPeter Zijlstra 6281f16c575SPeter Zijlstra if (pre_cmd) { 6291f16c575SPeter Zijlstra ret = system(pre_cmd); 6301f16c575SPeter Zijlstra if (ret) 6311f16c575SPeter Zijlstra return ret; 6321f16c575SPeter Zijlstra } 6331f16c575SPeter Zijlstra 6341f16c575SPeter Zijlstra if (sync_run) 6351f16c575SPeter Zijlstra sync(); 6361f16c575SPeter Zijlstra 6371f16c575SPeter Zijlstra ret = __run_perf_stat(argc, argv); 6381f16c575SPeter Zijlstra if (ret) 6391f16c575SPeter Zijlstra return ret; 6401f16c575SPeter Zijlstra 6411f16c575SPeter Zijlstra if (post_cmd) { 6421f16c575SPeter Zijlstra ret = system(post_cmd); 6431f16c575SPeter Zijlstra if (ret) 6441f16c575SPeter Zijlstra return ret; 6451f16c575SPeter Zijlstra } 6461f16c575SPeter Zijlstra 6471f16c575SPeter Zijlstra return ret; 6481f16c575SPeter Zijlstra } 6491f16c575SPeter Zijlstra 650f99844cbSIngo Molnar static void print_noise_pct(double total, double avg) 651f99844cbSIngo Molnar { 6520007eceaSXiao Guangrong double pct = rel_stddev_stats(total, avg); 653f99844cbSIngo Molnar 6543ae9a34dSZhengyu He if (csv_output) 6554aa9015fSStephane Eranian fprintf(output, "%s%.2f%%", csv_sep, pct); 656a1bca6ccSJim Cromie else if (pct) 6574aa9015fSStephane Eranian fprintf(output, " ( +-%6.2f%% )", pct); 658f99844cbSIngo Molnar } 659f99844cbSIngo Molnar 66069aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg) 66142202dd5SIngo Molnar { 66269aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps; 66369aad6f1SArnaldo Carvalho de Melo 664849abde9SPeter Zijlstra if (run_count == 1) 665849abde9SPeter Zijlstra return; 666849abde9SPeter Zijlstra 66769aad6f1SArnaldo Carvalho de Melo ps = evsel->priv; 668f99844cbSIngo Molnar print_noise_pct(stddev_stats(&ps->res_stats[0]), avg); 66942202dd5SIngo Molnar } 67042202dd5SIngo Molnar 67112c08a9fSStephane Eranian static void aggr_printout(struct perf_evsel *evsel, int id, int nr) 67242202dd5SIngo Molnar { 67386ee6e18SStephane Eranian switch (aggr_mode) { 67412c08a9fSStephane Eranian case AGGR_CORE: 67512c08a9fSStephane Eranian fprintf(output, "S%d-C%*d%s%*d%s", 67612c08a9fSStephane Eranian cpu_map__id_to_socket(id), 67712c08a9fSStephane Eranian csv_output ? 0 : -8, 67812c08a9fSStephane Eranian cpu_map__id_to_cpu(id), 67912c08a9fSStephane Eranian csv_sep, 68012c08a9fSStephane Eranian csv_output ? 0 : 4, 68112c08a9fSStephane Eranian nr, 68212c08a9fSStephane Eranian csv_sep); 68312c08a9fSStephane Eranian break; 68486ee6e18SStephane Eranian case AGGR_SOCKET: 68586ee6e18SStephane Eranian fprintf(output, "S%*d%s%*d%s", 686d7e7a451SStephane Eranian csv_output ? 0 : -5, 68712c08a9fSStephane Eranian id, 688d7e7a451SStephane Eranian csv_sep, 689d7e7a451SStephane Eranian csv_output ? 0 : 4, 690d7e7a451SStephane Eranian nr, 691d7e7a451SStephane Eranian csv_sep); 69286ee6e18SStephane Eranian break; 69386ee6e18SStephane Eranian case AGGR_NONE: 69486ee6e18SStephane Eranian fprintf(output, "CPU%*d%s", 695d7470b6aSStephane Eranian csv_output ? 0 : -4, 69612c08a9fSStephane Eranian perf_evsel__cpus(evsel)->map[id], csv_sep); 69786ee6e18SStephane Eranian break; 69886ee6e18SStephane Eranian case AGGR_GLOBAL: 69986ee6e18SStephane Eranian default: 70086ee6e18SStephane Eranian break; 70186ee6e18SStephane Eranian } 70286ee6e18SStephane Eranian } 703d7470b6aSStephane Eranian 70486ee6e18SStephane Eranian static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) 70586ee6e18SStephane Eranian { 70686ee6e18SStephane Eranian double msecs = avg / 1e6; 70786ee6e18SStephane Eranian const char *fmt = csv_output ? "%.6f%s%s" : "%18.6f%s%-25s"; 7084bbe5a61SDavid Ahern char name[25]; 70986ee6e18SStephane Eranian 71086ee6e18SStephane Eranian aggr_printout(evsel, cpu, nr); 71186ee6e18SStephane Eranian 7124bbe5a61SDavid Ahern scnprintf(name, sizeof(name), "%s%s", 7134bbe5a61SDavid Ahern perf_evsel__name(evsel), csv_output ? "" : " (msec)"); 7144bbe5a61SDavid Ahern fprintf(output, fmt, msecs, csv_sep, name); 715d7470b6aSStephane Eranian 716023695d9SStephane Eranian if (evsel->cgrp) 7174aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 718023695d9SStephane Eranian 71913370a9bSStephane Eranian if (csv_output || interval) 720d7470b6aSStephane Eranian return; 72142202dd5SIngo Molnar 722daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 7234aa9015fSStephane Eranian fprintf(output, " # %8.3f CPUs utilized ", 7244aa9015fSStephane Eranian avg / avg_stats(&walltime_nsecs_stats)); 7259dac6a29SNamhyung Kim else 7269dac6a29SNamhyung Kim fprintf(output, " "); 72742202dd5SIngo Molnar } 72842202dd5SIngo Molnar 72915e6392fSNamhyung Kim /* used for get_ratio_color() */ 73015e6392fSNamhyung Kim enum grc_type { 73115e6392fSNamhyung Kim GRC_STALLED_CYCLES_FE, 73215e6392fSNamhyung Kim GRC_STALLED_CYCLES_BE, 73315e6392fSNamhyung Kim GRC_CACHE_MISSES, 73415e6392fSNamhyung Kim GRC_MAX_NR 73515e6392fSNamhyung Kim }; 73615e6392fSNamhyung Kim 73715e6392fSNamhyung Kim static const char *get_ratio_color(enum grc_type type, double ratio) 73815e6392fSNamhyung Kim { 73915e6392fSNamhyung Kim static const double grc_table[GRC_MAX_NR][3] = { 74015e6392fSNamhyung Kim [GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 }, 74115e6392fSNamhyung Kim [GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 }, 74215e6392fSNamhyung Kim [GRC_CACHE_MISSES] = { 20.0, 10.0, 5.0 }, 74315e6392fSNamhyung Kim }; 74415e6392fSNamhyung Kim const char *color = PERF_COLOR_NORMAL; 74515e6392fSNamhyung Kim 74615e6392fSNamhyung Kim if (ratio > grc_table[type][0]) 74715e6392fSNamhyung Kim color = PERF_COLOR_RED; 74815e6392fSNamhyung Kim else if (ratio > grc_table[type][1]) 74915e6392fSNamhyung Kim color = PERF_COLOR_MAGENTA; 75015e6392fSNamhyung Kim else if (ratio > grc_table[type][2]) 75115e6392fSNamhyung Kim color = PERF_COLOR_YELLOW; 75215e6392fSNamhyung Kim 75315e6392fSNamhyung Kim return color; 75415e6392fSNamhyung Kim } 75515e6392fSNamhyung Kim 7561d037ca1SIrina Tirdea static void print_stalled_cycles_frontend(int cpu, 7571d037ca1SIrina Tirdea struct perf_evsel *evsel 7581d037ca1SIrina Tirdea __maybe_unused, double avg) 759d3d1e86dSIngo Molnar { 760d3d1e86dSIngo Molnar double total, ratio = 0.0; 761d3d1e86dSIngo Molnar const char *color; 762d3d1e86dSIngo Molnar 763d3d1e86dSIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 764d3d1e86dSIngo Molnar 765d3d1e86dSIngo Molnar if (total) 766d3d1e86dSIngo Molnar ratio = avg / total * 100.0; 767d3d1e86dSIngo Molnar 76815e6392fSNamhyung Kim color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio); 769d3d1e86dSIngo Molnar 7704aa9015fSStephane Eranian fprintf(output, " # "); 7714aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7724aa9015fSStephane Eranian fprintf(output, " frontend cycles idle "); 773d3d1e86dSIngo Molnar } 774d3d1e86dSIngo Molnar 7751d037ca1SIrina Tirdea static void print_stalled_cycles_backend(int cpu, 7761d037ca1SIrina Tirdea struct perf_evsel *evsel 7771d037ca1SIrina Tirdea __maybe_unused, double avg) 778a5d243d0SIngo Molnar { 779a5d243d0SIngo Molnar double total, ratio = 0.0; 780a5d243d0SIngo Molnar const char *color; 781a5d243d0SIngo Molnar 782a5d243d0SIngo Molnar total = avg_stats(&runtime_cycles_stats[cpu]); 783a5d243d0SIngo Molnar 784a5d243d0SIngo Molnar if (total) 785a5d243d0SIngo Molnar ratio = avg / total * 100.0; 786a5d243d0SIngo Molnar 78715e6392fSNamhyung Kim color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio); 788a5d243d0SIngo Molnar 7894aa9015fSStephane Eranian fprintf(output, " # "); 7904aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 7914aa9015fSStephane Eranian fprintf(output, " backend cycles idle "); 792a5d243d0SIngo Molnar } 793a5d243d0SIngo Molnar 7941d037ca1SIrina Tirdea static void print_branch_misses(int cpu, 7951d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 7961d037ca1SIrina Tirdea double avg) 797c78df6c1SIngo Molnar { 798c78df6c1SIngo Molnar double total, ratio = 0.0; 799c78df6c1SIngo Molnar const char *color; 800c78df6c1SIngo Molnar 801c78df6c1SIngo Molnar total = avg_stats(&runtime_branches_stats[cpu]); 802c78df6c1SIngo Molnar 803c78df6c1SIngo Molnar if (total) 804c78df6c1SIngo Molnar ratio = avg / total * 100.0; 805c78df6c1SIngo Molnar 80615e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 807c78df6c1SIngo Molnar 8084aa9015fSStephane Eranian fprintf(output, " # "); 8094aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 8104aa9015fSStephane Eranian fprintf(output, " of all branches "); 811c78df6c1SIngo Molnar } 812c78df6c1SIngo Molnar 8131d037ca1SIrina Tirdea static void print_l1_dcache_misses(int cpu, 8141d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 8151d037ca1SIrina Tirdea double avg) 8168bb6c79fSIngo Molnar { 8178bb6c79fSIngo Molnar double total, ratio = 0.0; 8188bb6c79fSIngo Molnar const char *color; 8198bb6c79fSIngo Molnar 8208bb6c79fSIngo Molnar total = avg_stats(&runtime_l1_dcache_stats[cpu]); 8218bb6c79fSIngo Molnar 8228bb6c79fSIngo Molnar if (total) 8238bb6c79fSIngo Molnar ratio = avg / total * 100.0; 8248bb6c79fSIngo Molnar 82515e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 8268bb6c79fSIngo Molnar 8274aa9015fSStephane Eranian fprintf(output, " # "); 8284aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 8294aa9015fSStephane Eranian fprintf(output, " of all L1-dcache hits "); 8308bb6c79fSIngo Molnar } 8318bb6c79fSIngo Molnar 8321d037ca1SIrina Tirdea static void print_l1_icache_misses(int cpu, 8331d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 8341d037ca1SIrina Tirdea double avg) 835c3305257SIngo Molnar { 836c3305257SIngo Molnar double total, ratio = 0.0; 837c3305257SIngo Molnar const char *color; 838c3305257SIngo Molnar 839c3305257SIngo Molnar total = avg_stats(&runtime_l1_icache_stats[cpu]); 840c3305257SIngo Molnar 841c3305257SIngo Molnar if (total) 842c3305257SIngo Molnar ratio = avg / total * 100.0; 843c3305257SIngo Molnar 84415e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 845c3305257SIngo Molnar 8464aa9015fSStephane Eranian fprintf(output, " # "); 8474aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 8484aa9015fSStephane Eranian fprintf(output, " of all L1-icache hits "); 849c3305257SIngo Molnar } 850c3305257SIngo Molnar 8511d037ca1SIrina Tirdea static void print_dtlb_cache_misses(int cpu, 8521d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 8531d037ca1SIrina Tirdea double avg) 854c3305257SIngo Molnar { 855c3305257SIngo Molnar double total, ratio = 0.0; 856c3305257SIngo Molnar const char *color; 857c3305257SIngo Molnar 858c3305257SIngo Molnar total = avg_stats(&runtime_dtlb_cache_stats[cpu]); 859c3305257SIngo Molnar 860c3305257SIngo Molnar if (total) 861c3305257SIngo Molnar ratio = avg / total * 100.0; 862c3305257SIngo Molnar 86315e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 864c3305257SIngo Molnar 8654aa9015fSStephane Eranian fprintf(output, " # "); 8664aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 8674aa9015fSStephane Eranian fprintf(output, " of all dTLB cache hits "); 868c3305257SIngo Molnar } 869c3305257SIngo Molnar 8701d037ca1SIrina Tirdea static void print_itlb_cache_misses(int cpu, 8711d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 8721d037ca1SIrina Tirdea double avg) 873c3305257SIngo Molnar { 874c3305257SIngo Molnar double total, ratio = 0.0; 875c3305257SIngo Molnar const char *color; 876c3305257SIngo Molnar 877c3305257SIngo Molnar total = avg_stats(&runtime_itlb_cache_stats[cpu]); 878c3305257SIngo Molnar 879c3305257SIngo Molnar if (total) 880c3305257SIngo Molnar ratio = avg / total * 100.0; 881c3305257SIngo Molnar 88215e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 883c3305257SIngo Molnar 8844aa9015fSStephane Eranian fprintf(output, " # "); 8854aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 8864aa9015fSStephane Eranian fprintf(output, " of all iTLB cache hits "); 887c3305257SIngo Molnar } 888c3305257SIngo Molnar 8891d037ca1SIrina Tirdea static void print_ll_cache_misses(int cpu, 8901d037ca1SIrina Tirdea struct perf_evsel *evsel __maybe_unused, 8911d037ca1SIrina Tirdea double avg) 892c3305257SIngo Molnar { 893c3305257SIngo Molnar double total, ratio = 0.0; 894c3305257SIngo Molnar const char *color; 895c3305257SIngo Molnar 896c3305257SIngo Molnar total = avg_stats(&runtime_ll_cache_stats[cpu]); 897c3305257SIngo Molnar 898c3305257SIngo Molnar if (total) 899c3305257SIngo Molnar ratio = avg / total * 100.0; 900c3305257SIngo Molnar 90115e6392fSNamhyung Kim color = get_ratio_color(GRC_CACHE_MISSES, ratio); 902c3305257SIngo Molnar 9034aa9015fSStephane Eranian fprintf(output, " # "); 9044aa9015fSStephane Eranian color_fprintf(output, color, "%6.2f%%", ratio); 9054aa9015fSStephane Eranian fprintf(output, " of all LL-cache hits "); 906c3305257SIngo Molnar } 907c3305257SIngo Molnar 908d7e7a451SStephane Eranian static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg) 90942202dd5SIngo Molnar { 9104cabc3d1SAndi Kleen double total, ratio = 0.0, total2; 911d7470b6aSStephane Eranian const char *fmt; 912d7470b6aSStephane Eranian 913d7470b6aSStephane Eranian if (csv_output) 91486ee6e18SStephane Eranian fmt = "%.0f%s%s"; 915d7470b6aSStephane Eranian else if (big_num) 91686ee6e18SStephane Eranian fmt = "%'18.0f%s%-25s"; 917d7470b6aSStephane Eranian else 91886ee6e18SStephane Eranian fmt = "%18.0f%s%-25s"; 919f5b4a9c3SStephane Eranian 92086ee6e18SStephane Eranian aggr_printout(evsel, cpu, nr); 92186ee6e18SStephane Eranian 92286ee6e18SStephane Eranian if (aggr_mode == AGGR_GLOBAL) 923f5b4a9c3SStephane Eranian cpu = 0; 924c7f7fea3SIngo Molnar 92586ee6e18SStephane Eranian fprintf(output, fmt, avg, csv_sep, perf_evsel__name(evsel)); 926d7470b6aSStephane Eranian 927023695d9SStephane Eranian if (evsel->cgrp) 9284aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 929023695d9SStephane Eranian 93013370a9bSStephane Eranian if (csv_output || interval) 931d7470b6aSStephane Eranian return; 93242202dd5SIngo Molnar 933daec78a0SArnaldo Carvalho de Melo if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 934f5b4a9c3SStephane Eranian total = avg_stats(&runtime_cycles_stats[cpu]); 9353e7a0817SRamkumar Ramachandra if (total) { 936c7f7fea3SIngo Molnar ratio = avg / total; 9374aa9015fSStephane Eranian fprintf(output, " # %5.2f insns per cycle ", ratio); 9383e7a0817SRamkumar Ramachandra } 939d3d1e86dSIngo Molnar total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]); 940d3d1e86dSIngo Molnar total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu])); 941481f988aSIngo Molnar 942481f988aSIngo Molnar if (total && avg) { 943481f988aSIngo Molnar ratio = total / avg; 9444aa9015fSStephane Eranian fprintf(output, "\n # %5.2f stalled cycles per insn", ratio); 945481f988aSIngo Molnar } 946481f988aSIngo Molnar 947daec78a0SArnaldo Carvalho de Melo } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 948f5b4a9c3SStephane Eranian runtime_branches_stats[cpu].n != 0) { 949c78df6c1SIngo Molnar print_branch_misses(cpu, evsel, avg); 9508bb6c79fSIngo Molnar } else if ( 9518bb6c79fSIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 9528bb6c79fSIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D | 9538bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 9548bb6c79fSIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 955c6264defSIngo Molnar runtime_l1_dcache_stats[cpu].n != 0) { 9568bb6c79fSIngo Molnar print_l1_dcache_misses(cpu, evsel, avg); 957c3305257SIngo Molnar } else if ( 958c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 959c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I | 960c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 961c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 962c3305257SIngo Molnar runtime_l1_icache_stats[cpu].n != 0) { 963c3305257SIngo Molnar print_l1_icache_misses(cpu, evsel, avg); 964c3305257SIngo Molnar } else if ( 965c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 966c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB | 967c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 968c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 969c3305257SIngo Molnar runtime_dtlb_cache_stats[cpu].n != 0) { 970c3305257SIngo Molnar print_dtlb_cache_misses(cpu, evsel, avg); 971c3305257SIngo Molnar } else if ( 972c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 973c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB | 974c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 975c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 976c3305257SIngo Molnar runtime_itlb_cache_stats[cpu].n != 0) { 977c3305257SIngo Molnar print_itlb_cache_misses(cpu, evsel, avg); 978c3305257SIngo Molnar } else if ( 979c3305257SIngo Molnar evsel->attr.type == PERF_TYPE_HW_CACHE && 980c3305257SIngo Molnar evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL | 981c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 982c3305257SIngo Molnar ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 983c3305257SIngo Molnar runtime_ll_cache_stats[cpu].n != 0) { 984c3305257SIngo Molnar print_ll_cache_misses(cpu, evsel, avg); 985d58f4c82SIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) && 986d58f4c82SIngo Molnar runtime_cacherefs_stats[cpu].n != 0) { 987d58f4c82SIngo Molnar total = avg_stats(&runtime_cacherefs_stats[cpu]); 988d58f4c82SIngo Molnar 989d58f4c82SIngo Molnar if (total) 990d58f4c82SIngo Molnar ratio = avg * 100 / total; 991d58f4c82SIngo Molnar 9924aa9015fSStephane Eranian fprintf(output, " # %8.3f %% of all cache refs ", ratio); 993d58f4c82SIngo Molnar 994d3d1e86dSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 995d3d1e86dSIngo Molnar print_stalled_cycles_frontend(cpu, evsel, avg); 996129c04cbSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) { 997d3d1e86dSIngo Molnar print_stalled_cycles_backend(cpu, evsel, avg); 998481f988aSIngo Molnar } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) { 999481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 1000481f988aSIngo Molnar 1001c458fe62SRamkumar Ramachandra if (total) { 1002c458fe62SRamkumar Ramachandra ratio = avg / total; 10034aa9015fSStephane Eranian fprintf(output, " # %8.3f GHz ", ratio); 1004c458fe62SRamkumar Ramachandra } 10054cabc3d1SAndi Kleen } else if (transaction_run && 10064cabc3d1SAndi Kleen perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) { 10074cabc3d1SAndi Kleen total = avg_stats(&runtime_cycles_stats[cpu]); 10084cabc3d1SAndi Kleen if (total) 10094cabc3d1SAndi Kleen fprintf(output, 10104cabc3d1SAndi Kleen " # %5.2f%% transactional cycles ", 10114cabc3d1SAndi Kleen 100.0 * (avg / total)); 10124cabc3d1SAndi Kleen } else if (transaction_run && 10134cabc3d1SAndi Kleen perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX_CP))) { 10144cabc3d1SAndi Kleen total = avg_stats(&runtime_cycles_stats[cpu]); 10154cabc3d1SAndi Kleen total2 = avg_stats(&runtime_cycles_in_tx_stats[cpu]); 10164cabc3d1SAndi Kleen if (total2 < avg) 10174cabc3d1SAndi Kleen total2 = avg; 10184cabc3d1SAndi Kleen if (total) 10194cabc3d1SAndi Kleen fprintf(output, 10204cabc3d1SAndi Kleen " # %5.2f%% aborted cycles ", 10214cabc3d1SAndi Kleen 100.0 * ((total2-avg) / total)); 10224cabc3d1SAndi Kleen } else if (transaction_run && 10234cabc3d1SAndi Kleen perf_evsel__cmp(evsel, nth_evsel(T_TRANSACTION_START)) && 10244cabc3d1SAndi Kleen avg > 0 && 10254cabc3d1SAndi Kleen runtime_cycles_in_tx_stats[cpu].n != 0) { 10264cabc3d1SAndi Kleen total = avg_stats(&runtime_cycles_in_tx_stats[cpu]); 10274cabc3d1SAndi Kleen 10284cabc3d1SAndi Kleen if (total) 10294cabc3d1SAndi Kleen ratio = total / avg; 10304cabc3d1SAndi Kleen 10314cabc3d1SAndi Kleen fprintf(output, " # %8.0f cycles / transaction ", ratio); 10324cabc3d1SAndi Kleen } else if (transaction_run && 10334cabc3d1SAndi Kleen perf_evsel__cmp(evsel, nth_evsel(T_ELISION_START)) && 10344cabc3d1SAndi Kleen avg > 0 && 10354cabc3d1SAndi Kleen runtime_cycles_in_tx_stats[cpu].n != 0) { 10364cabc3d1SAndi Kleen total = avg_stats(&runtime_cycles_in_tx_stats[cpu]); 10374cabc3d1SAndi Kleen 10384cabc3d1SAndi Kleen if (total) 10394cabc3d1SAndi Kleen ratio = total / avg; 10404cabc3d1SAndi Kleen 10414cabc3d1SAndi Kleen fprintf(output, " # %8.0f cycles / elision ", ratio); 1042481f988aSIngo Molnar } else if (runtime_nsecs_stats[cpu].n != 0) { 10435fde2523SNamhyung Kim char unit = 'M'; 10445fde2523SNamhyung Kim 1045481f988aSIngo Molnar total = avg_stats(&runtime_nsecs_stats[cpu]); 1046481f988aSIngo Molnar 1047481f988aSIngo Molnar if (total) 1048481f988aSIngo Molnar ratio = 1000.0 * avg / total; 10495fde2523SNamhyung Kim if (ratio < 0.001) { 10505fde2523SNamhyung Kim ratio *= 1000; 10515fde2523SNamhyung Kim unit = 'K'; 10525fde2523SNamhyung Kim } 1053481f988aSIngo Molnar 10545fde2523SNamhyung Kim fprintf(output, " # %8.3f %c/sec ", ratio, unit); 1055a5d243d0SIngo Molnar } else { 10564aa9015fSStephane Eranian fprintf(output, " "); 105742202dd5SIngo Molnar } 105842202dd5SIngo Molnar } 105942202dd5SIngo Molnar 106086ee6e18SStephane Eranian static void print_aggr(char *prefix) 1061d7e7a451SStephane Eranian { 1062d7e7a451SStephane Eranian struct perf_evsel *counter; 1063582ec082SStephane Eranian int cpu, cpu2, s, s2, id, nr; 1064d7e7a451SStephane Eranian u64 ena, run, val; 1065d7e7a451SStephane Eranian 106686ee6e18SStephane Eranian if (!(aggr_map || aggr_get_id)) 1067d7e7a451SStephane Eranian return; 1068d7e7a451SStephane Eranian 106986ee6e18SStephane Eranian for (s = 0; s < aggr_map->nr; s++) { 107086ee6e18SStephane Eranian id = aggr_map->map[s]; 1071d7e7a451SStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) { 1072d7e7a451SStephane Eranian val = ena = run = 0; 1073d7e7a451SStephane Eranian nr = 0; 1074d7e7a451SStephane Eranian for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 1075582ec082SStephane Eranian cpu2 = perf_evsel__cpus(counter)->map[cpu]; 1076582ec082SStephane Eranian s2 = aggr_get_id(evsel_list->cpus, cpu2); 107786ee6e18SStephane Eranian if (s2 != id) 1078d7e7a451SStephane Eranian continue; 1079d7e7a451SStephane Eranian val += counter->counts->cpu[cpu].val; 1080d7e7a451SStephane Eranian ena += counter->counts->cpu[cpu].ena; 1081d7e7a451SStephane Eranian run += counter->counts->cpu[cpu].run; 1082d7e7a451SStephane Eranian nr++; 1083d7e7a451SStephane Eranian } 1084d7e7a451SStephane Eranian if (prefix) 1085d7e7a451SStephane Eranian fprintf(output, "%s", prefix); 1086d7e7a451SStephane Eranian 1087d7e7a451SStephane Eranian if (run == 0 || ena == 0) { 1088582ec082SStephane Eranian aggr_printout(counter, id, nr); 108986ee6e18SStephane Eranian 109086ee6e18SStephane Eranian fprintf(output, "%*s%s%*s", 1091d7e7a451SStephane Eranian csv_output ? 0 : 18, 1092d7e7a451SStephane Eranian counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 1093d7e7a451SStephane Eranian csv_sep, 1094d7e7a451SStephane Eranian csv_output ? 0 : -24, 1095d7e7a451SStephane Eranian perf_evsel__name(counter)); 109686ee6e18SStephane Eranian 1097d7e7a451SStephane Eranian if (counter->cgrp) 1098d7e7a451SStephane Eranian fprintf(output, "%s%s", 1099d7e7a451SStephane Eranian csv_sep, counter->cgrp->name); 1100d7e7a451SStephane Eranian 1101d7e7a451SStephane Eranian fputc('\n', output); 1102d7e7a451SStephane Eranian continue; 1103d7e7a451SStephane Eranian } 1104d7e7a451SStephane Eranian 1105d7e7a451SStephane Eranian if (nsec_counter(counter)) 110686ee6e18SStephane Eranian nsec_printout(id, nr, counter, val); 1107d7e7a451SStephane Eranian else 110886ee6e18SStephane Eranian abs_printout(id, nr, counter, val); 1109d7e7a451SStephane Eranian 1110d7e7a451SStephane Eranian if (!csv_output) { 1111d7e7a451SStephane Eranian print_noise(counter, 1.0); 1112d7e7a451SStephane Eranian 1113d7e7a451SStephane Eranian if (run != ena) 1114d7e7a451SStephane Eranian fprintf(output, " (%.2f%%)", 1115d7e7a451SStephane Eranian 100.0 * run / ena); 1116d7e7a451SStephane Eranian } 1117d7e7a451SStephane Eranian fputc('\n', output); 1118d7e7a451SStephane Eranian } 1119d7e7a451SStephane Eranian } 1120d7e7a451SStephane Eranian } 1121d7e7a451SStephane Eranian 112242202dd5SIngo Molnar /* 112342202dd5SIngo Molnar * Print out the results of a single counter: 1124f5b4a9c3SStephane Eranian * aggregated counts in system-wide mode 112542202dd5SIngo Molnar */ 112613370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix) 112742202dd5SIngo Molnar { 112869aad6f1SArnaldo Carvalho de Melo struct perf_stat *ps = counter->priv; 112969aad6f1SArnaldo Carvalho de Melo double avg = avg_stats(&ps->res_stats[0]); 1130c52b12edSArnaldo Carvalho de Melo int scaled = counter->counts->scaled; 113142202dd5SIngo Molnar 113213370a9bSStephane Eranian if (prefix) 113313370a9bSStephane Eranian fprintf(output, "%s", prefix); 113413370a9bSStephane Eranian 113542202dd5SIngo Molnar if (scaled == -1) { 11364aa9015fSStephane Eranian fprintf(output, "%*s%s%*s", 1137d7470b6aSStephane Eranian csv_output ? 0 : 18, 11382cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 1139023695d9SStephane Eranian csv_sep, 1140023695d9SStephane Eranian csv_output ? 0 : -24, 11417289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 1142023695d9SStephane Eranian 1143023695d9SStephane Eranian if (counter->cgrp) 11444aa9015fSStephane Eranian fprintf(output, "%s%s", csv_sep, counter->cgrp->name); 1145023695d9SStephane Eranian 11464aa9015fSStephane Eranian fputc('\n', output); 114742202dd5SIngo Molnar return; 114842202dd5SIngo Molnar } 114942202dd5SIngo Molnar 115042202dd5SIngo Molnar if (nsec_counter(counter)) 1151d7e7a451SStephane Eranian nsec_printout(-1, 0, counter, avg); 115242202dd5SIngo Molnar else 1153d7e7a451SStephane Eranian abs_printout(-1, 0, counter, avg); 1154849abde9SPeter Zijlstra 11553ae9a34dSZhengyu He print_noise(counter, avg); 11563ae9a34dSZhengyu He 1157d7470b6aSStephane Eranian if (csv_output) { 11584aa9015fSStephane Eranian fputc('\n', output); 1159d7470b6aSStephane Eranian return; 1160d7470b6aSStephane Eranian } 1161d7470b6aSStephane Eranian 1162506d4bc8SPeter Zijlstra if (scaled) { 1163506d4bc8SPeter Zijlstra double avg_enabled, avg_running; 1164506d4bc8SPeter Zijlstra 116569aad6f1SArnaldo Carvalho de Melo avg_enabled = avg_stats(&ps->res_stats[1]); 116669aad6f1SArnaldo Carvalho de Melo avg_running = avg_stats(&ps->res_stats[2]); 1167506d4bc8SPeter Zijlstra 11684aa9015fSStephane Eranian fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled); 1169506d4bc8SPeter Zijlstra } 11704aa9015fSStephane Eranian fprintf(output, "\n"); 117142202dd5SIngo Molnar } 117242202dd5SIngo Molnar 1173f5b4a9c3SStephane Eranian /* 1174f5b4a9c3SStephane Eranian * Print out the results of a single counter: 1175f5b4a9c3SStephane Eranian * does not use aggregated count in system-wide 1176f5b4a9c3SStephane Eranian */ 117713370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix) 1178f5b4a9c3SStephane Eranian { 1179f5b4a9c3SStephane Eranian u64 ena, run, val; 1180f5b4a9c3SStephane Eranian int cpu; 1181f5b4a9c3SStephane Eranian 11827ae92e74SYan, Zheng for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 1183c52b12edSArnaldo Carvalho de Melo val = counter->counts->cpu[cpu].val; 1184c52b12edSArnaldo Carvalho de Melo ena = counter->counts->cpu[cpu].ena; 1185c52b12edSArnaldo Carvalho de Melo run = counter->counts->cpu[cpu].run; 118613370a9bSStephane Eranian 118713370a9bSStephane Eranian if (prefix) 118813370a9bSStephane Eranian fprintf(output, "%s", prefix); 118913370a9bSStephane Eranian 1190f5b4a9c3SStephane Eranian if (run == 0 || ena == 0) { 11914aa9015fSStephane Eranian fprintf(output, "CPU%*d%s%*s%s%*s", 1192d7470b6aSStephane Eranian csv_output ? 0 : -4, 11937ae92e74SYan, Zheng perf_evsel__cpus(counter)->map[cpu], csv_sep, 1194d7470b6aSStephane Eranian csv_output ? 0 : 18, 11952cee77c4SDavid Ahern counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 11962cee77c4SDavid Ahern csv_sep, 1197023695d9SStephane Eranian csv_output ? 0 : -24, 11987289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 1199f5b4a9c3SStephane Eranian 1200023695d9SStephane Eranian if (counter->cgrp) 12014aa9015fSStephane Eranian fprintf(output, "%s%s", 12024aa9015fSStephane Eranian csv_sep, counter->cgrp->name); 1203023695d9SStephane Eranian 12044aa9015fSStephane Eranian fputc('\n', output); 1205f5b4a9c3SStephane Eranian continue; 1206f5b4a9c3SStephane Eranian } 1207f5b4a9c3SStephane Eranian 1208f5b4a9c3SStephane Eranian if (nsec_counter(counter)) 1209d7e7a451SStephane Eranian nsec_printout(cpu, 0, counter, val); 1210f5b4a9c3SStephane Eranian else 1211d7e7a451SStephane Eranian abs_printout(cpu, 0, counter, val); 1212f5b4a9c3SStephane Eranian 1213d7470b6aSStephane Eranian if (!csv_output) { 1214f5b4a9c3SStephane Eranian print_noise(counter, 1.0); 1215f5b4a9c3SStephane Eranian 1216c6264defSIngo Molnar if (run != ena) 12174aa9015fSStephane Eranian fprintf(output, " (%.2f%%)", 12184aa9015fSStephane Eranian 100.0 * run / ena); 1219d7470b6aSStephane Eranian } 12204aa9015fSStephane Eranian fputc('\n', output); 1221f5b4a9c3SStephane Eranian } 1222f5b4a9c3SStephane Eranian } 1223f5b4a9c3SStephane Eranian 122442202dd5SIngo Molnar static void print_stat(int argc, const char **argv) 122542202dd5SIngo Molnar { 122669aad6f1SArnaldo Carvalho de Melo struct perf_evsel *counter; 122769aad6f1SArnaldo Carvalho de Melo int i; 122842202dd5SIngo Molnar 122986470930SIngo Molnar fflush(stdout); 123086470930SIngo Molnar 1231d7470b6aSStephane Eranian if (!csv_output) { 12324aa9015fSStephane Eranian fprintf(output, "\n"); 12334aa9015fSStephane Eranian fprintf(output, " Performance counter stats for "); 123462d3b617SDavid Ahern if (target.system_wide) 123562d3b617SDavid Ahern fprintf(output, "\'system wide"); 123662d3b617SDavid Ahern else if (target.cpu_list) 123762d3b617SDavid Ahern fprintf(output, "\'CPU(s) %s", target.cpu_list); 1238602ad878SArnaldo Carvalho de Melo else if (!target__has_task(&target)) { 12394aa9015fSStephane Eranian fprintf(output, "\'%s", argv[0]); 124086470930SIngo Molnar for (i = 1; i < argc; i++) 12414aa9015fSStephane Eranian fprintf(output, " %s", argv[i]); 124220f946b4SNamhyung Kim } else if (target.pid) 124320f946b4SNamhyung Kim fprintf(output, "process id \'%s", target.pid); 1244d6d901c2SZhang, Yanmin else 124520f946b4SNamhyung Kim fprintf(output, "thread id \'%s", target.tid); 124686470930SIngo Molnar 12474aa9015fSStephane Eranian fprintf(output, "\'"); 124842202dd5SIngo Molnar if (run_count > 1) 12494aa9015fSStephane Eranian fprintf(output, " (%d runs)", run_count); 12504aa9015fSStephane Eranian fprintf(output, ":\n\n"); 1251d7470b6aSStephane Eranian } 125286470930SIngo Molnar 125386ee6e18SStephane Eranian switch (aggr_mode) { 125412c08a9fSStephane Eranian case AGGR_CORE: 125586ee6e18SStephane Eranian case AGGR_SOCKET: 125686ee6e18SStephane Eranian print_aggr(NULL); 125786ee6e18SStephane Eranian break; 125886ee6e18SStephane Eranian case AGGR_GLOBAL: 1259361c99a6SArnaldo Carvalho de Melo list_for_each_entry(counter, &evsel_list->entries, node) 126013370a9bSStephane Eranian print_counter_aggr(counter, NULL); 126186ee6e18SStephane Eranian break; 126286ee6e18SStephane Eranian case AGGR_NONE: 126386ee6e18SStephane Eranian list_for_each_entry(counter, &evsel_list->entries, node) 126486ee6e18SStephane Eranian print_counter(counter, NULL); 126586ee6e18SStephane Eranian break; 126686ee6e18SStephane Eranian default: 126786ee6e18SStephane Eranian break; 1268f5b4a9c3SStephane Eranian } 126986470930SIngo Molnar 1270d7470b6aSStephane Eranian if (!csv_output) { 1271c3305257SIngo Molnar if (!null_run) 12724aa9015fSStephane Eranian fprintf(output, "\n"); 12734aa9015fSStephane Eranian fprintf(output, " %17.9f seconds time elapsed", 1274506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)/1e9); 1275566747e6SIngo Molnar if (run_count > 1) { 12764aa9015fSStephane Eranian fprintf(output, " "); 1277f99844cbSIngo Molnar print_noise_pct(stddev_stats(&walltime_nsecs_stats), 1278506d4bc8SPeter Zijlstra avg_stats(&walltime_nsecs_stats)); 1279566747e6SIngo Molnar } 12804aa9015fSStephane Eranian fprintf(output, "\n\n"); 128186470930SIngo Molnar } 1282d7470b6aSStephane Eranian } 128386470930SIngo Molnar 1284f7b7c26eSPeter Zijlstra static volatile int signr = -1; 1285f7b7c26eSPeter Zijlstra 128686470930SIngo Molnar static void skip_signal(int signo) 128786470930SIngo Molnar { 128813370a9bSStephane Eranian if ((child_pid == -1) || interval) 128960666c63SLiming Wang done = 1; 129060666c63SLiming Wang 1291f7b7c26eSPeter Zijlstra signr = signo; 1292d07f0b12SStephane Eranian /* 1293d07f0b12SStephane Eranian * render child_pid harmless 1294d07f0b12SStephane Eranian * won't send SIGTERM to a random 1295d07f0b12SStephane Eranian * process in case of race condition 1296d07f0b12SStephane Eranian * and fast PID recycling 1297d07f0b12SStephane Eranian */ 1298d07f0b12SStephane Eranian child_pid = -1; 1299f7b7c26eSPeter Zijlstra } 1300f7b7c26eSPeter Zijlstra 1301f7b7c26eSPeter Zijlstra static void sig_atexit(void) 1302f7b7c26eSPeter Zijlstra { 1303d07f0b12SStephane Eranian sigset_t set, oset; 1304d07f0b12SStephane Eranian 1305d07f0b12SStephane Eranian /* 1306d07f0b12SStephane Eranian * avoid race condition with SIGCHLD handler 1307d07f0b12SStephane Eranian * in skip_signal() which is modifying child_pid 1308d07f0b12SStephane Eranian * goal is to avoid send SIGTERM to a random 1309d07f0b12SStephane Eranian * process 1310d07f0b12SStephane Eranian */ 1311d07f0b12SStephane Eranian sigemptyset(&set); 1312d07f0b12SStephane Eranian sigaddset(&set, SIGCHLD); 1313d07f0b12SStephane Eranian sigprocmask(SIG_BLOCK, &set, &oset); 1314d07f0b12SStephane Eranian 1315933da83aSChris Wilson if (child_pid != -1) 1316933da83aSChris Wilson kill(child_pid, SIGTERM); 1317933da83aSChris Wilson 1318d07f0b12SStephane Eranian sigprocmask(SIG_SETMASK, &oset, NULL); 1319d07f0b12SStephane Eranian 1320f7b7c26eSPeter Zijlstra if (signr == -1) 1321f7b7c26eSPeter Zijlstra return; 1322f7b7c26eSPeter Zijlstra 1323f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 1324f7b7c26eSPeter Zijlstra kill(getpid(), signr); 132586470930SIngo Molnar } 132686470930SIngo Molnar 13271d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused, 13281d037ca1SIrina Tirdea const char *s __maybe_unused, int unset) 1329d7470b6aSStephane Eranian { 1330d7470b6aSStephane Eranian big_num_opt = unset ? 0 : 1; 1331d7470b6aSStephane Eranian return 0; 1332d7470b6aSStephane Eranian } 1333d7470b6aSStephane Eranian 133486ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void) 133586ee6e18SStephane Eranian { 133686ee6e18SStephane Eranian switch (aggr_mode) { 133786ee6e18SStephane Eranian case AGGR_SOCKET: 133886ee6e18SStephane Eranian if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) { 133986ee6e18SStephane Eranian perror("cannot build socket map"); 134086ee6e18SStephane Eranian return -1; 134186ee6e18SStephane Eranian } 134286ee6e18SStephane Eranian aggr_get_id = cpu_map__get_socket; 134386ee6e18SStephane Eranian break; 134412c08a9fSStephane Eranian case AGGR_CORE: 134512c08a9fSStephane Eranian if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) { 134612c08a9fSStephane Eranian perror("cannot build core map"); 134712c08a9fSStephane Eranian return -1; 134812c08a9fSStephane Eranian } 134912c08a9fSStephane Eranian aggr_get_id = cpu_map__get_core; 135012c08a9fSStephane Eranian break; 135186ee6e18SStephane Eranian case AGGR_NONE: 135286ee6e18SStephane Eranian case AGGR_GLOBAL: 135386ee6e18SStephane Eranian default: 135486ee6e18SStephane Eranian break; 135586ee6e18SStephane Eranian } 135686ee6e18SStephane Eranian return 0; 135786ee6e18SStephane Eranian } 135886ee6e18SStephane Eranian 13594cabc3d1SAndi Kleen static int setup_events(const char * const *attrs, unsigned len) 13604cabc3d1SAndi Kleen { 13614cabc3d1SAndi Kleen unsigned i; 13624cabc3d1SAndi Kleen 13634cabc3d1SAndi Kleen for (i = 0; i < len; i++) { 13644cabc3d1SAndi Kleen if (parse_events(evsel_list, attrs[i])) 13654cabc3d1SAndi Kleen return -1; 13664cabc3d1SAndi Kleen } 13674cabc3d1SAndi Kleen return 0; 13684cabc3d1SAndi Kleen } 136986ee6e18SStephane Eranian 13702cba3ffbSIngo Molnar /* 13712cba3ffbSIngo Molnar * Add default attributes, if there were no attributes specified or 13722cba3ffbSIngo Molnar * if -d/--detailed, -d -d or -d -d -d is used: 13732cba3ffbSIngo Molnar */ 13742cba3ffbSIngo Molnar static int add_default_attributes(void) 13752cba3ffbSIngo Molnar { 1376b070a547SArnaldo Carvalho de Melo struct perf_event_attr default_attrs[] = { 1377b070a547SArnaldo Carvalho de Melo 1378b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 1379b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 1380b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 1381b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 1382b070a547SArnaldo Carvalho de Melo 1383b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 1384b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 1385b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 1386b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 1387b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 1388b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 1389b070a547SArnaldo Carvalho de Melo 1390b070a547SArnaldo Carvalho de Melo }; 1391b070a547SArnaldo Carvalho de Melo 1392b070a547SArnaldo Carvalho de Melo /* 1393b070a547SArnaldo Carvalho de Melo * Detailed stats (-d), covering the L1 and last level data caches: 1394b070a547SArnaldo Carvalho de Melo */ 1395b070a547SArnaldo Carvalho de Melo struct perf_event_attr detailed_attrs[] = { 1396b070a547SArnaldo Carvalho de Melo 1397b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1398b070a547SArnaldo Carvalho de Melo .config = 1399b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1400b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1401b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1402b070a547SArnaldo Carvalho de Melo 1403b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1404b070a547SArnaldo Carvalho de Melo .config = 1405b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1406b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1407b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1408b070a547SArnaldo Carvalho de Melo 1409b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1410b070a547SArnaldo Carvalho de Melo .config = 1411b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1412b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1413b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1414b070a547SArnaldo Carvalho de Melo 1415b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1416b070a547SArnaldo Carvalho de Melo .config = 1417b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1418b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1419b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1420b070a547SArnaldo Carvalho de Melo }; 1421b070a547SArnaldo Carvalho de Melo 1422b070a547SArnaldo Carvalho de Melo /* 1423b070a547SArnaldo Carvalho de Melo * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: 1424b070a547SArnaldo Carvalho de Melo */ 1425b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_detailed_attrs[] = { 1426b070a547SArnaldo Carvalho de Melo 1427b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1428b070a547SArnaldo Carvalho de Melo .config = 1429b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1430b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1431b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1432b070a547SArnaldo Carvalho de Melo 1433b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1434b070a547SArnaldo Carvalho de Melo .config = 1435b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1436b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1437b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1438b070a547SArnaldo Carvalho de Melo 1439b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1440b070a547SArnaldo Carvalho de Melo .config = 1441b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1442b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1443b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1444b070a547SArnaldo Carvalho de Melo 1445b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1446b070a547SArnaldo Carvalho de Melo .config = 1447b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1448b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1449b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1450b070a547SArnaldo Carvalho de Melo 1451b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1452b070a547SArnaldo Carvalho de Melo .config = 1453b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1454b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1455b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1456b070a547SArnaldo Carvalho de Melo 1457b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1458b070a547SArnaldo Carvalho de Melo .config = 1459b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1460b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1461b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1462b070a547SArnaldo Carvalho de Melo 1463b070a547SArnaldo Carvalho de Melo }; 1464b070a547SArnaldo Carvalho de Melo 1465b070a547SArnaldo Carvalho de Melo /* 1466b070a547SArnaldo Carvalho de Melo * Very, very detailed stats (-d -d -d), adding prefetch events: 1467b070a547SArnaldo Carvalho de Melo */ 1468b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_very_detailed_attrs[] = { 1469b070a547SArnaldo Carvalho de Melo 1470b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1471b070a547SArnaldo Carvalho de Melo .config = 1472b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1473b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1474b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1475b070a547SArnaldo Carvalho de Melo 1476b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1477b070a547SArnaldo Carvalho de Melo .config = 1478b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1479b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1480b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1481b070a547SArnaldo Carvalho de Melo }; 1482b070a547SArnaldo Carvalho de Melo 14832cba3ffbSIngo Molnar /* Set attrs if no event is selected and !null_run: */ 14842cba3ffbSIngo Molnar if (null_run) 14852cba3ffbSIngo Molnar return 0; 14862cba3ffbSIngo Molnar 14874cabc3d1SAndi Kleen if (transaction_run) { 14884cabc3d1SAndi Kleen int err; 14894cabc3d1SAndi Kleen if (pmu_have_event("cpu", "cycles-ct") && 14904cabc3d1SAndi Kleen pmu_have_event("cpu", "el-start")) 14914cabc3d1SAndi Kleen err = setup_events(transaction_attrs, 14924cabc3d1SAndi Kleen ARRAY_SIZE(transaction_attrs)); 14934cabc3d1SAndi Kleen else 14944cabc3d1SAndi Kleen err = setup_events(transaction_limited_attrs, 14954cabc3d1SAndi Kleen ARRAY_SIZE(transaction_limited_attrs)); 14964cabc3d1SAndi Kleen if (err < 0) { 14974cabc3d1SAndi Kleen fprintf(stderr, "Cannot set up transaction events\n"); 14984cabc3d1SAndi Kleen return -1; 14994cabc3d1SAndi Kleen } 15004cabc3d1SAndi Kleen return 0; 15014cabc3d1SAndi Kleen } 15024cabc3d1SAndi Kleen 15032cba3ffbSIngo Molnar if (!evsel_list->nr_entries) { 150479695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0) 15052cba3ffbSIngo Molnar return -1; 15062cba3ffbSIngo Molnar } 15072cba3ffbSIngo Molnar 15082cba3ffbSIngo Molnar /* Detailed events get appended to the event list: */ 15092cba3ffbSIngo Molnar 15102cba3ffbSIngo Molnar if (detailed_run < 1) 15112cba3ffbSIngo Molnar return 0; 15122cba3ffbSIngo Molnar 15132cba3ffbSIngo Molnar /* Append detailed run extra attributes: */ 151479695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) 15152cba3ffbSIngo Molnar return -1; 15162cba3ffbSIngo Molnar 15172cba3ffbSIngo Molnar if (detailed_run < 2) 15182cba3ffbSIngo Molnar return 0; 15192cba3ffbSIngo Molnar 15202cba3ffbSIngo Molnar /* Append very detailed run extra attributes: */ 152179695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) 15222cba3ffbSIngo Molnar return -1; 15232cba3ffbSIngo Molnar 15242cba3ffbSIngo Molnar if (detailed_run < 3) 15252cba3ffbSIngo Molnar return 0; 15262cba3ffbSIngo Molnar 15272cba3ffbSIngo Molnar /* Append very, very detailed run extra attributes: */ 152879695e1bSArnaldo Carvalho de Melo return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); 15292cba3ffbSIngo Molnar } 15302cba3ffbSIngo Molnar 15311d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) 153286470930SIngo Molnar { 15331f16c575SPeter Zijlstra bool append_file = false; 1534b070a547SArnaldo Carvalho de Melo int output_fd = 0; 1535b070a547SArnaldo Carvalho de Melo const char *output_name = NULL; 1536b070a547SArnaldo Carvalho de Melo const struct option options[] = { 15374cabc3d1SAndi Kleen OPT_BOOLEAN('T', "transaction", &transaction_run, 15384cabc3d1SAndi Kleen "hardware transaction statistics"), 1539b070a547SArnaldo Carvalho de Melo OPT_CALLBACK('e', "event", &evsel_list, "event", 1540b070a547SArnaldo Carvalho de Melo "event selector. use 'perf list' to list available events", 1541b070a547SArnaldo Carvalho de Melo parse_events_option), 1542b070a547SArnaldo Carvalho de Melo OPT_CALLBACK(0, "filter", &evsel_list, "filter", 1543b070a547SArnaldo Carvalho de Melo "event filter", parse_filter), 1544b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('i', "no-inherit", &no_inherit, 1545b070a547SArnaldo Carvalho de Melo "child tasks do not inherit counters"), 1546b070a547SArnaldo Carvalho de Melo OPT_STRING('p', "pid", &target.pid, "pid", 1547b070a547SArnaldo Carvalho de Melo "stat events on existing process id"), 1548b070a547SArnaldo Carvalho de Melo OPT_STRING('t', "tid", &target.tid, "tid", 1549b070a547SArnaldo Carvalho de Melo "stat events on existing thread id"), 1550b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('a', "all-cpus", &target.system_wide, 1551b070a547SArnaldo Carvalho de Melo "system-wide collection from all CPUs"), 1552b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('g', "group", &group, 1553b070a547SArnaldo Carvalho de Melo "put the counters into a counter group"), 1554b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"), 1555b070a547SArnaldo Carvalho de Melo OPT_INCR('v', "verbose", &verbose, 1556b070a547SArnaldo Carvalho de Melo "be more verbose (show counter open errors, etc)"), 1557b070a547SArnaldo Carvalho de Melo OPT_INTEGER('r', "repeat", &run_count, 1558a7e191c3SFrederik Deweerdt "repeat command and print average + stddev (max: 100, forever: 0)"), 1559b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('n', "null", &null_run, 1560b070a547SArnaldo Carvalho de Melo "null run - dont start any counters"), 1561b070a547SArnaldo Carvalho de Melo OPT_INCR('d', "detailed", &detailed_run, 1562b070a547SArnaldo Carvalho de Melo "detailed run - start a lot of events"), 1563b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN('S', "sync", &sync_run, 1564b070a547SArnaldo Carvalho de Melo "call sync() before starting a run"), 1565b070a547SArnaldo Carvalho de Melo OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 1566b070a547SArnaldo Carvalho de Melo "print large numbers with thousands\' separators", 1567b070a547SArnaldo Carvalho de Melo stat__set_big_num), 1568b070a547SArnaldo Carvalho de Melo OPT_STRING('C', "cpu", &target.cpu_list, "cpu", 1569b070a547SArnaldo Carvalho de Melo "list of cpus to monitor in system-wide"), 157086ee6e18SStephane Eranian OPT_SET_UINT('A', "no-aggr", &aggr_mode, 157186ee6e18SStephane Eranian "disable CPU count aggregation", AGGR_NONE), 1572b070a547SArnaldo Carvalho de Melo OPT_STRING('x', "field-separator", &csv_sep, "separator", 1573b070a547SArnaldo Carvalho de Melo "print counts with custom separator"), 1574b070a547SArnaldo Carvalho de Melo OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1575b070a547SArnaldo Carvalho de Melo "monitor event in cgroup name only", parse_cgroups), 1576b070a547SArnaldo Carvalho de Melo OPT_STRING('o', "output", &output_name, "file", "output file name"), 1577b070a547SArnaldo Carvalho de Melo OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), 1578b070a547SArnaldo Carvalho de Melo OPT_INTEGER(0, "log-fd", &output_fd, 1579b070a547SArnaldo Carvalho de Melo "log output to fd, instead of stderr"), 15801f16c575SPeter Zijlstra OPT_STRING(0, "pre", &pre_cmd, "command", 15811f16c575SPeter Zijlstra "command to run prior to the measured command"), 15821f16c575SPeter Zijlstra OPT_STRING(0, "post", &post_cmd, "command", 15831f16c575SPeter Zijlstra "command to run after to the measured command"), 158413370a9bSStephane Eranian OPT_UINTEGER('I', "interval-print", &interval, 158513370a9bSStephane Eranian "print counts at regular interval in ms (>= 100)"), 1586d4304958SStephane Eranian OPT_SET_UINT(0, "per-socket", &aggr_mode, 158786ee6e18SStephane Eranian "aggregate counts per processor socket", AGGR_SOCKET), 158812c08a9fSStephane Eranian OPT_SET_UINT(0, "per-core", &aggr_mode, 158912c08a9fSStephane Eranian "aggregate counts per physical processor core", AGGR_CORE), 159041191688SAndi Kleen OPT_UINTEGER('D', "delay", &initial_delay, 159141191688SAndi Kleen "ms to wait before starting measurement after program start"), 1592b070a547SArnaldo Carvalho de Melo OPT_END() 1593b070a547SArnaldo Carvalho de Melo }; 1594b070a547SArnaldo Carvalho de Melo const char * const stat_usage[] = { 1595b070a547SArnaldo Carvalho de Melo "perf stat [<options>] [<command>]", 1596b070a547SArnaldo Carvalho de Melo NULL 1597b070a547SArnaldo Carvalho de Melo }; 1598cc03c542SNamhyung Kim int status = -EINVAL, run_idx; 15994aa9015fSStephane Eranian const char *mode; 160042202dd5SIngo Molnar 16015af52b51SStephane Eranian setlocale(LC_ALL, ""); 16025af52b51SStephane Eranian 1603334fe7a3SNamhyung Kim evsel_list = perf_evlist__new(); 1604361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 1605361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1606361c99a6SArnaldo Carvalho de Melo 1607a0541234SAnton Blanchard argc = parse_options(argc, argv, options, stat_usage, 1608a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 1609d7470b6aSStephane Eranian 16104aa9015fSStephane Eranian output = stderr; 16114aa9015fSStephane Eranian if (output_name && strcmp(output_name, "-")) 16124aa9015fSStephane Eranian output = NULL; 16134aa9015fSStephane Eranian 161456f3bae7SJim Cromie if (output_name && output_fd) { 161556f3bae7SJim Cromie fprintf(stderr, "cannot use both --output and --log-fd\n"); 1616cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "o", 1); 1617cc03c542SNamhyung Kim parse_options_usage(NULL, options, "log-fd", 0); 1618cc03c542SNamhyung Kim goto out; 161956f3bae7SJim Cromie } 1620fc3e4d07SStephane Eranian 1621fc3e4d07SStephane Eranian if (output_fd < 0) { 1622fc3e4d07SStephane Eranian fprintf(stderr, "argument to --log-fd must be a > 0\n"); 1623cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "log-fd", 0); 1624cc03c542SNamhyung Kim goto out; 1625fc3e4d07SStephane Eranian } 1626fc3e4d07SStephane Eranian 16274aa9015fSStephane Eranian if (!output) { 16284aa9015fSStephane Eranian struct timespec tm; 16294aa9015fSStephane Eranian mode = append_file ? "a" : "w"; 16304aa9015fSStephane Eranian 16314aa9015fSStephane Eranian output = fopen(output_name, mode); 16324aa9015fSStephane Eranian if (!output) { 16334aa9015fSStephane Eranian perror("failed to create output file"); 1634fceda7feSDavid Ahern return -1; 16354aa9015fSStephane Eranian } 16364aa9015fSStephane Eranian clock_gettime(CLOCK_REALTIME, &tm); 16374aa9015fSStephane Eranian fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 1638fc3e4d07SStephane Eranian } else if (output_fd > 0) { 163956f3bae7SJim Cromie mode = append_file ? "a" : "w"; 164056f3bae7SJim Cromie output = fdopen(output_fd, mode); 164156f3bae7SJim Cromie if (!output) { 164256f3bae7SJim Cromie perror("Failed opening logfd"); 164356f3bae7SJim Cromie return -errno; 164456f3bae7SJim Cromie } 16454aa9015fSStephane Eranian } 16464aa9015fSStephane Eranian 1647d4ffd04dSJim Cromie if (csv_sep) { 1648d7470b6aSStephane Eranian csv_output = true; 1649d4ffd04dSJim Cromie if (!strcmp(csv_sep, "\\t")) 1650d4ffd04dSJim Cromie csv_sep = "\t"; 1651d4ffd04dSJim Cromie } else 1652d7470b6aSStephane Eranian csv_sep = DEFAULT_SEPARATOR; 1653d7470b6aSStephane Eranian 1654d7470b6aSStephane Eranian /* 1655d7470b6aSStephane Eranian * let the spreadsheet do the pretty-printing 1656d7470b6aSStephane Eranian */ 1657d7470b6aSStephane Eranian if (csv_output) { 165861a9f324SJim Cromie /* User explicitly passed -B? */ 1659d7470b6aSStephane Eranian if (big_num_opt == 1) { 1660d7470b6aSStephane Eranian fprintf(stderr, "-B option not supported with -x\n"); 1661cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "B", 1); 1662cc03c542SNamhyung Kim parse_options_usage(NULL, options, "x", 1); 1663cc03c542SNamhyung Kim goto out; 1664d7470b6aSStephane Eranian } else /* Nope, so disable big number formatting */ 1665d7470b6aSStephane Eranian big_num = false; 1666d7470b6aSStephane Eranian } else if (big_num_opt == 0) /* User passed --no-big-num */ 1667d7470b6aSStephane Eranian big_num = false; 1668d7470b6aSStephane Eranian 1669602ad878SArnaldo Carvalho de Melo if (!argc && target__none(&target)) 167086470930SIngo Molnar usage_with_options(stat_usage, options); 1671ac3063bdSDavid Ahern 1672a7e191c3SFrederik Deweerdt if (run_count < 0) { 1673cc03c542SNamhyung Kim pr_err("Run count must be a positive number\n"); 1674cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "r", 1); 1675cc03c542SNamhyung Kim goto out; 1676a7e191c3SFrederik Deweerdt } else if (run_count == 0) { 1677a7e191c3SFrederik Deweerdt forever = true; 1678a7e191c3SFrederik Deweerdt run_count = 1; 1679a7e191c3SFrederik Deweerdt } 168086470930SIngo Molnar 1681023695d9SStephane Eranian /* no_aggr, cgroup are for system-wide only */ 1682602ad878SArnaldo Carvalho de Melo if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) && 1683602ad878SArnaldo Carvalho de Melo !target__has_cpu(&target)) { 1684023695d9SStephane Eranian fprintf(stderr, "both cgroup and no-aggregation " 1685023695d9SStephane Eranian "modes only available in system-wide mode\n"); 1686023695d9SStephane Eranian 1687cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "G", 1); 1688cc03c542SNamhyung Kim parse_options_usage(NULL, options, "A", 1); 1689cc03c542SNamhyung Kim parse_options_usage(NULL, options, "a", 1); 1690cc03c542SNamhyung Kim goto out; 1691d7e7a451SStephane Eranian } 1692d7e7a451SStephane Eranian 16932cba3ffbSIngo Molnar if (add_default_attributes()) 1694c6264defSIngo Molnar goto out; 169586470930SIngo Molnar 1696602ad878SArnaldo Carvalho de Melo target__validate(&target); 16975c98d466SArnaldo Carvalho de Melo 169877a6f014SNamhyung Kim if (perf_evlist__create_maps(evsel_list, &target) < 0) { 1699602ad878SArnaldo Carvalho de Melo if (target__has_task(&target)) { 17005c98d466SArnaldo Carvalho de Melo pr_err("Problems finding threads of monitor\n"); 1701cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "p", 1); 1702cc03c542SNamhyung Kim parse_options_usage(NULL, options, "t", 1); 1703602ad878SArnaldo Carvalho de Melo } else if (target__has_cpu(&target)) { 170460d567e2SArnaldo Carvalho de Melo perror("failed to parse CPUs map"); 1705cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "C", 1); 1706cc03c542SNamhyung Kim parse_options_usage(NULL, options, "a", 1); 1707cc03c542SNamhyung Kim } 1708cc03c542SNamhyung Kim goto out; 170960d567e2SArnaldo Carvalho de Melo } 171013370a9bSStephane Eranian if (interval && interval < 100) { 171113370a9bSStephane Eranian pr_err("print interval must be >= 100ms\n"); 1712cc03c542SNamhyung Kim parse_options_usage(stat_usage, options, "I", 1); 1713cc03c542SNamhyung Kim goto out_free_maps; 171413370a9bSStephane Eranian } 1715c45c6ea2SStephane Eranian 1716d134ffb9SArnaldo Carvalho de Melo if (perf_evlist__alloc_stats(evsel_list, interval)) 1717d134ffb9SArnaldo Carvalho de Melo goto out_free_maps; 1718d6d901c2SZhang, Yanmin 171986ee6e18SStephane Eranian if (perf_stat_init_aggr_mode()) 1720cc03c542SNamhyung Kim goto out_free_maps; 172186ee6e18SStephane Eranian 172286470930SIngo Molnar /* 172386470930SIngo Molnar * We dont want to block the signals - that would cause 172486470930SIngo Molnar * child tasks to inherit that and Ctrl-C would not work. 172586470930SIngo Molnar * What we want is for Ctrl-C to work in the exec()-ed 172686470930SIngo Molnar * task, but being ignored by perf stat itself: 172786470930SIngo Molnar */ 1728f7b7c26eSPeter Zijlstra atexit(sig_atexit); 1729a7e191c3SFrederik Deweerdt if (!forever) 173086470930SIngo Molnar signal(SIGINT, skip_signal); 173113370a9bSStephane Eranian signal(SIGCHLD, skip_signal); 173286470930SIngo Molnar signal(SIGALRM, skip_signal); 173386470930SIngo Molnar signal(SIGABRT, skip_signal); 173486470930SIngo Molnar 173542202dd5SIngo Molnar status = 0; 1736a7e191c3SFrederik Deweerdt for (run_idx = 0; forever || run_idx < run_count; run_idx++) { 173742202dd5SIngo Molnar if (run_count != 1 && verbose) 17384aa9015fSStephane Eranian fprintf(output, "[ perf stat: executing run #%d ... ]\n", 17394aa9015fSStephane Eranian run_idx + 1); 1740f9cef0a9SIngo Molnar 174142202dd5SIngo Molnar status = run_perf_stat(argc, argv); 1742a7e191c3SFrederik Deweerdt if (forever && status != -1) { 1743a7e191c3SFrederik Deweerdt print_stat(argc, argv); 1744d134ffb9SArnaldo Carvalho de Melo perf_stat__reset_stats(evsel_list); 1745a7e191c3SFrederik Deweerdt } 174642202dd5SIngo Molnar } 174742202dd5SIngo Molnar 1748a7e191c3SFrederik Deweerdt if (!forever && status != -1 && !interval) 174942202dd5SIngo Molnar print_stat(argc, argv); 1750d134ffb9SArnaldo Carvalho de Melo 1751d134ffb9SArnaldo Carvalho de Melo perf_evlist__free_stats(evsel_list); 1752d134ffb9SArnaldo Carvalho de Melo out_free_maps: 17537e2ed097SArnaldo Carvalho de Melo perf_evlist__delete_maps(evsel_list); 17540015e2e1SArnaldo Carvalho de Melo out: 17550015e2e1SArnaldo Carvalho de Melo perf_evlist__delete(evsel_list); 175642202dd5SIngo Molnar return status; 175786470930SIngo Molnar } 1758