186470930SIngo Molnar /* 286470930SIngo Molnar * builtin-stat.c 386470930SIngo Molnar * 486470930SIngo Molnar * Builtin stat command: Give a precise performance counters summary 586470930SIngo Molnar * overview about any workload, CPU or specific PID. 686470930SIngo Molnar * 786470930SIngo Molnar * Sample output: 886470930SIngo Molnar 92cba3ffbSIngo Molnar $ perf stat ./hackbench 10 1086470930SIngo Molnar 112cba3ffbSIngo Molnar Time: 0.118 1286470930SIngo Molnar 132cba3ffbSIngo Molnar Performance counter stats for './hackbench 10': 1486470930SIngo Molnar 152cba3ffbSIngo Molnar 1708.761321 task-clock # 11.037 CPUs utilized 162cba3ffbSIngo Molnar 41,190 context-switches # 0.024 M/sec 172cba3ffbSIngo Molnar 6,735 CPU-migrations # 0.004 M/sec 182cba3ffbSIngo Molnar 17,318 page-faults # 0.010 M/sec 192cba3ffbSIngo Molnar 5,205,202,243 cycles # 3.046 GHz 202cba3ffbSIngo Molnar 3,856,436,920 stalled-cycles-frontend # 74.09% frontend cycles idle 212cba3ffbSIngo Molnar 1,600,790,871 stalled-cycles-backend # 30.75% backend cycles idle 222cba3ffbSIngo Molnar 2,603,501,247 instructions # 0.50 insns per cycle 232cba3ffbSIngo Molnar # 1.48 stalled cycles per insn 242cba3ffbSIngo Molnar 484,357,498 branches # 283.455 M/sec 252cba3ffbSIngo Molnar 6,388,934 branch-misses # 1.32% of all branches 262cba3ffbSIngo Molnar 272cba3ffbSIngo Molnar 0.154822978 seconds time elapsed 2886470930SIngo Molnar 2986470930SIngo Molnar * 302cba3ffbSIngo Molnar * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 3186470930SIngo Molnar * 3286470930SIngo Molnar * Improvements and fixes by: 3386470930SIngo Molnar * 3486470930SIngo Molnar * Arjan van de Ven <arjan@linux.intel.com> 3586470930SIngo Molnar * Yanmin Zhang <yanmin.zhang@intel.com> 3686470930SIngo Molnar * Wu Fengguang <fengguang.wu@intel.com> 3786470930SIngo Molnar * Mike Galbraith <efault@gmx.de> 3886470930SIngo Molnar * Paul Mackerras <paulus@samba.org> 396e750a8fSJaswinder Singh Rajput * Jaswinder Singh Rajput <jaswinder@kernel.org> 4086470930SIngo Molnar * 4186470930SIngo Molnar * Released under the GPL v2. (and only v2, not any later version) 4286470930SIngo Molnar */ 4386470930SIngo Molnar 4486470930SIngo Molnar #include "perf.h" 4586470930SIngo Molnar #include "builtin.h" 46f14d5707SArnaldo Carvalho de Melo #include "util/cgroup.h" 4786470930SIngo Molnar #include "util/util.h" 484b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 4986470930SIngo Molnar #include "util/parse-events.h" 504cabc3d1SAndi Kleen #include "util/pmu.h" 518f28827aSFrederic Weisbecker #include "util/event.h" 52361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 5369aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 548f28827aSFrederic Weisbecker #include "util/debug.h" 555d8bb1ecSMathieu Poirier #include "util/drv_configs.h" 56a5d243d0SIngo Molnar #include "util/color.h" 570007eceaSXiao Guangrong #include "util/stat.h" 5860666c63SLiming Wang #include "util/header.h" 59a12b51c4SPaul Mackerras #include "util/cpumap.h" 60d6d901c2SZhang, Yanmin #include "util/thread.h" 61fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 62d809560bSJiri Olsa #include "util/counts.h" 6344b1e60aSAndi Kleen #include "util/group.h" 644979d0c7SJiri Olsa #include "util/session.h" 65ba6039b6SJiri Olsa #include "util/tool.h" 66a067558eSArnaldo Carvalho de Melo #include "util/string2.h" 67b18f3e36SAndi Kleen #include "util/metricgroup.h" 689660e08eSJiri Olsa #include "util/top.h" 69ba6039b6SJiri Olsa #include "asm/bug.h" 7086470930SIngo Molnar 71bd48c63eSArnaldo Carvalho de Melo #include <linux/time64.h> 7244b1e60aSAndi Kleen #include <api/fs/fs.h> 73a43783aeSArnaldo Carvalho de Melo #include <errno.h> 749607ad3aSArnaldo Carvalho de Melo #include <signal.h> 751f16c575SPeter Zijlstra #include <stdlib.h> 7686470930SIngo Molnar #include <sys/prctl.h> 77fd20e811SArnaldo Carvalho de Melo #include <inttypes.h> 785af52b51SStephane Eranian #include <locale.h> 79e3b03b6cSAndi Kleen #include <math.h> 807a8ef4c4SArnaldo Carvalho de Melo #include <sys/types.h> 817a8ef4c4SArnaldo Carvalho de Melo #include <sys/stat.h> 824208735dSArnaldo Carvalho de Melo #include <sys/wait.h> 837a8ef4c4SArnaldo Carvalho de Melo #include <unistd.h> 840ce2da14SJiri Olsa #include <sys/time.h> 850ce2da14SJiri Olsa #include <sys/resource.h> 860ce2da14SJiri Olsa #include <sys/wait.h> 8786470930SIngo Molnar 883d689ed6SArnaldo Carvalho de Melo #include "sane_ctype.h" 893d689ed6SArnaldo Carvalho de Melo 90d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR " " 91daefd0bcSKan Liang #define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi" 92d7470b6aSStephane Eranian 93d4f63a47SJiri Olsa static void print_counters(struct timespec *ts, int argc, const char **argv); 9413370a9bSStephane Eranian 954cabc3d1SAndi Kleen /* Default events used for perf stat -T */ 96a454742cSJiri Olsa static const char *transaction_attrs = { 97a454742cSJiri Olsa "task-clock," 984cabc3d1SAndi Kleen "{" 994cabc3d1SAndi Kleen "instructions," 1004cabc3d1SAndi Kleen "cycles," 1014cabc3d1SAndi Kleen "cpu/cycles-t/," 1024cabc3d1SAndi Kleen "cpu/tx-start/," 1034cabc3d1SAndi Kleen "cpu/el-start/," 1044cabc3d1SAndi Kleen "cpu/cycles-ct/" 1054cabc3d1SAndi Kleen "}" 1064cabc3d1SAndi Kleen }; 1074cabc3d1SAndi Kleen 1084cabc3d1SAndi Kleen /* More limited version when the CPU does not have all events. */ 109a454742cSJiri Olsa static const char * transaction_limited_attrs = { 110a454742cSJiri Olsa "task-clock," 1114cabc3d1SAndi Kleen "{" 1124cabc3d1SAndi Kleen "instructions," 1134cabc3d1SAndi Kleen "cycles," 1144cabc3d1SAndi Kleen "cpu/cycles-t/," 1154cabc3d1SAndi Kleen "cpu/tx-start/" 1164cabc3d1SAndi Kleen "}" 1174cabc3d1SAndi Kleen }; 1184cabc3d1SAndi Kleen 11944b1e60aSAndi Kleen static const char * topdown_attrs[] = { 12044b1e60aSAndi Kleen "topdown-total-slots", 12144b1e60aSAndi Kleen "topdown-slots-retired", 12244b1e60aSAndi Kleen "topdown-recovery-bubbles", 12344b1e60aSAndi Kleen "topdown-fetch-bubbles", 12444b1e60aSAndi Kleen "topdown-slots-issued", 12544b1e60aSAndi Kleen NULL, 12644b1e60aSAndi Kleen }; 12744b1e60aSAndi Kleen 128daefd0bcSKan Liang static const char *smi_cost_attrs = { 129daefd0bcSKan Liang "{" 130daefd0bcSKan Liang "msr/aperf/," 131daefd0bcSKan Liang "msr/smi/," 132daefd0bcSKan Liang "cycles" 133daefd0bcSKan Liang "}" 134daefd0bcSKan Liang }; 135daefd0bcSKan Liang 136666e6d48SRobert Richter static struct perf_evlist *evsel_list; 137361c99a6SArnaldo Carvalho de Melo 138602ad878SArnaldo Carvalho de Melo static struct target target = { 13977a6f014SNamhyung Kim .uid = UINT_MAX, 14077a6f014SNamhyung Kim }; 14142202dd5SIngo Molnar 142c1a1f5d9SJiri Olsa #define METRIC_ONLY_LEN 20 143c1a1f5d9SJiri Olsa 144d07f0b12SStephane Eranian static volatile pid_t child_pid = -1; 1452cba3ffbSIngo Molnar static int detailed_run = 0; 1464cabc3d1SAndi Kleen static bool transaction_run; 14744b1e60aSAndi Kleen static bool topdown_run = false; 148daefd0bcSKan Liang static bool smi_cost = false; 149daefd0bcSKan Liang static bool smi_reset = false; 150d7470b6aSStephane Eranian static int big_num_opt = -1; 15143bece79SLin Ming static bool group = false; 1521f16c575SPeter Zijlstra static const char *pre_cmd = NULL; 1531f16c575SPeter Zijlstra static const char *post_cmd = NULL; 1541f16c575SPeter Zijlstra static bool sync_run = false; 155a7e191c3SFrederik Deweerdt static bool forever = false; 15644b1e60aSAndi Kleen static bool force_metric_only = false; 15713370a9bSStephane Eranian static struct timespec ref_time; 158e0547311SJiri Olsa static bool append_file; 159db06a269Syuzhoujian static bool interval_count; 160e0547311SJiri Olsa static const char *output_name; 161e0547311SJiri Olsa static int output_fd; 1625af52b51SStephane Eranian 1634979d0c7SJiri Olsa struct perf_stat { 1644979d0c7SJiri Olsa bool record; 1658ceb41d7SJiri Olsa struct perf_data data; 1664979d0c7SJiri Olsa struct perf_session *session; 1674979d0c7SJiri Olsa u64 bytes_written; 168ba6039b6SJiri Olsa struct perf_tool tool; 1691975d36eSJiri Olsa bool maps_allocated; 1701975d36eSJiri Olsa struct cpu_map *cpus; 1711975d36eSJiri Olsa struct thread_map *threads; 17289af4e05SJiri Olsa enum aggr_mode aggr_mode; 1734979d0c7SJiri Olsa }; 1744979d0c7SJiri Olsa 1754979d0c7SJiri Olsa static struct perf_stat perf_stat; 1764979d0c7SJiri Olsa #define STAT_RECORD perf_stat.record 1774979d0c7SJiri Olsa 17860666c63SLiming Wang static volatile int done = 0; 17960666c63SLiming Wang 180421a50f3SJiri Olsa static struct perf_stat_config stat_config = { 181421a50f3SJiri Olsa .aggr_mode = AGGR_GLOBAL, 182711a572eSJiri Olsa .scale = true, 183df4f7b4dSJiri Olsa .unit_width = 4, /* strlen("unit") */ 184d97ae04bSJiri Olsa .run_count = 1, 185ee1760e2SJiri Olsa .metric_only_len = METRIC_ONLY_LEN, 18626893a60SJiri Olsa .walltime_nsecs_stats = &walltime_nsecs_stats, 18734ff0866SJiri Olsa .big_num = true, 188421a50f3SJiri Olsa }; 189421a50f3SJiri Olsa 19013370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a, 19113370a9bSStephane Eranian struct timespec *b) 19213370a9bSStephane Eranian { 19313370a9bSStephane Eranian r->tv_sec = a->tv_sec - b->tv_sec; 19413370a9bSStephane Eranian if (a->tv_nsec < b->tv_nsec) { 195310ebb93SArnaldo Carvalho de Melo r->tv_nsec = a->tv_nsec + NSEC_PER_SEC - b->tv_nsec; 19613370a9bSStephane Eranian r->tv_sec--; 19713370a9bSStephane Eranian } else { 19813370a9bSStephane Eranian r->tv_nsec = a->tv_nsec - b->tv_nsec ; 19913370a9bSStephane Eranian } 20013370a9bSStephane Eranian } 20113370a9bSStephane Eranian 202254ecbc7SJiri Olsa static void perf_stat__reset_stats(void) 203254ecbc7SJiri Olsa { 20456739444SJin Yao int i; 20556739444SJin Yao 206254ecbc7SJiri Olsa perf_evlist__reset_stats(evsel_list); 207f87027b9SJiri Olsa perf_stat__reset_shadow_stats(); 20856739444SJin Yao 20956739444SJin Yao for (i = 0; i < stat_config.stats_num; i++) 21056739444SJin Yao perf_stat__reset_shadow_per_stat(&stat_config.stats[i]); 2111eda3b21SJiri Olsa } 2121eda3b21SJiri Olsa 2138b99b1a4SJiri Olsa static int process_synthesized_event(struct perf_tool *tool __maybe_unused, 2144979d0c7SJiri Olsa union perf_event *event, 2154979d0c7SJiri Olsa struct perf_sample *sample __maybe_unused, 2164979d0c7SJiri Olsa struct machine *machine __maybe_unused) 2174979d0c7SJiri Olsa { 2188ceb41d7SJiri Olsa if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) { 2198b99b1a4SJiri Olsa pr_err("failed to write perf data, error: %m\n"); 2208b99b1a4SJiri Olsa return -1; 2218b99b1a4SJiri Olsa } 2228b99b1a4SJiri Olsa 2238b99b1a4SJiri Olsa perf_stat.bytes_written += event->header.size; 2248b99b1a4SJiri Olsa return 0; 2254979d0c7SJiri Olsa } 2264979d0c7SJiri Olsa 2271975d36eSJiri Olsa static int write_stat_round_event(u64 tm, u64 type) 2287aad0c32SJiri Olsa { 2291975d36eSJiri Olsa return perf_event__synthesize_stat_round(NULL, tm, type, 2307aad0c32SJiri Olsa process_synthesized_event, 2317aad0c32SJiri Olsa NULL); 2327aad0c32SJiri Olsa } 2337aad0c32SJiri Olsa 2347aad0c32SJiri Olsa #define WRITE_STAT_ROUND_EVENT(time, interval) \ 2357aad0c32SJiri Olsa write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval) 2367aad0c32SJiri Olsa 2375a6ea81bSJiri Olsa #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) 2385a6ea81bSJiri Olsa 2395a6ea81bSJiri Olsa static int 2405a6ea81bSJiri Olsa perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread, 2415a6ea81bSJiri Olsa struct perf_counts_values *count) 2425a6ea81bSJiri Olsa { 2435a6ea81bSJiri Olsa struct perf_sample_id *sid = SID(counter, cpu, thread); 2445a6ea81bSJiri Olsa 2455a6ea81bSJiri Olsa return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count, 2465a6ea81bSJiri Olsa process_synthesized_event, NULL); 2475a6ea81bSJiri Olsa } 2485a6ea81bSJiri Olsa 249f5b4a9c3SStephane Eranian /* 250f5b4a9c3SStephane Eranian * Read out the results of a single counter: 251f5b4a9c3SStephane Eranian * do not aggregate counts across CPUs in system-wide mode 252f5b4a9c3SStephane Eranian */ 253c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter) 254f5b4a9c3SStephane Eranian { 2559bf1a529SJiri Olsa int nthreads = thread_map__nr(evsel_list->threads); 25600e727bbSMark Rutland int ncpus, cpu, thread; 25700e727bbSMark Rutland 2581d9f8d1bSJin Yao if (target__has_cpu(&target) && !target__has_per_thread(&target)) 25900e727bbSMark Rutland ncpus = perf_evsel__nr_cpus(counter); 26000e727bbSMark Rutland else 26100e727bbSMark Rutland ncpus = 1; 262f5b4a9c3SStephane Eranian 2633b4331d9SSuzuki K. Poulose if (!counter->supported) 2643b4331d9SSuzuki K. Poulose return -ENOENT; 2653b4331d9SSuzuki K. Poulose 2669bf1a529SJiri Olsa if (counter->system_wide) 2679bf1a529SJiri Olsa nthreads = 1; 2689bf1a529SJiri Olsa 2699bf1a529SJiri Olsa for (thread = 0; thread < nthreads; thread++) { 2709bf1a529SJiri Olsa for (cpu = 0; cpu < ncpus; cpu++) { 2713b3eb044SJiri Olsa struct perf_counts_values *count; 2723b3eb044SJiri Olsa 2733b3eb044SJiri Olsa count = perf_counts(counter->counts, cpu, thread); 27482bf311eSJiri Olsa 27582bf311eSJiri Olsa /* 27682bf311eSJiri Olsa * The leader's group read loads data into its group members 27782bf311eSJiri Olsa * (via perf_evsel__read_counter) and sets threir count->loaded. 27882bf311eSJiri Olsa */ 27982bf311eSJiri Olsa if (!count->loaded && 28082bf311eSJiri Olsa perf_evsel__read_counter(counter, cpu, thread)) { 281db49a717SStephane Eranian counter->counts->scaled = -1; 282db49a717SStephane Eranian perf_counts(counter->counts, cpu, thread)->ena = 0; 283db49a717SStephane Eranian perf_counts(counter->counts, cpu, thread)->run = 0; 284c52b12edSArnaldo Carvalho de Melo return -1; 285db49a717SStephane Eranian } 2865a6ea81bSJiri Olsa 28782bf311eSJiri Olsa count->loaded = false; 28882bf311eSJiri Olsa 2895a6ea81bSJiri Olsa if (STAT_RECORD) { 2905a6ea81bSJiri Olsa if (perf_evsel__write_stat_event(counter, cpu, thread, count)) { 2915a6ea81bSJiri Olsa pr_err("failed to write stat event\n"); 2925a6ea81bSJiri Olsa return -1; 2935a6ea81bSJiri Olsa } 2945a6ea81bSJiri Olsa } 2950b1abbf4SAndi Kleen 2960b1abbf4SAndi Kleen if (verbose > 1) { 2970b1abbf4SAndi Kleen fprintf(stat_config.output, 2980b1abbf4SAndi Kleen "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 2990b1abbf4SAndi Kleen perf_evsel__name(counter), 3000b1abbf4SAndi Kleen cpu, 3010b1abbf4SAndi Kleen count->val, count->ena, count->run); 3020b1abbf4SAndi Kleen } 303f5b4a9c3SStephane Eranian } 3049bf1a529SJiri Olsa } 305c52b12edSArnaldo Carvalho de Melo 306c52b12edSArnaldo Carvalho de Melo return 0; 30786470930SIngo Molnar } 30886470930SIngo Molnar 3093df33effSMark Rutland static void read_counters(void) 310106a94a0SJiri Olsa { 311106a94a0SJiri Olsa struct perf_evsel *counter; 312db49a717SStephane Eranian int ret; 313106a94a0SJiri Olsa 314e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evsel_list, counter) { 315db49a717SStephane Eranian ret = read_counter(counter); 316db49a717SStephane Eranian if (ret) 317245bad8eSAndi Kleen pr_debug("failed to read counter %s\n", counter->name); 3183b3eb044SJiri Olsa 319db49a717SStephane Eranian if (ret == 0 && perf_stat_process_counter(&stat_config, counter)) 3203b3eb044SJiri Olsa pr_warning("failed to process counter %s\n", counter->name); 321106a94a0SJiri Olsa } 322106a94a0SJiri Olsa } 323106a94a0SJiri Olsa 324ba411a95SJiri Olsa static void process_interval(void) 32513370a9bSStephane Eranian { 32613370a9bSStephane Eranian struct timespec ts, rs; 32713370a9bSStephane Eranian 3283df33effSMark Rutland read_counters(); 32986ee6e18SStephane Eranian 33013370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ts); 33113370a9bSStephane Eranian diff_timespec(&rs, &ts, &ref_time); 33213370a9bSStephane Eranian 3337aad0c32SJiri Olsa if (STAT_RECORD) { 334bd48c63eSArnaldo Carvalho de Melo if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL)) 3357aad0c32SJiri Olsa pr_err("failed to write stat round event\n"); 3367aad0c32SJiri Olsa } 3377aad0c32SJiri Olsa 338b90f1333SAndi Kleen init_stats(&walltime_nsecs_stats); 339b90f1333SAndi Kleen update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000); 340d4f63a47SJiri Olsa print_counters(&rs, 0, NULL); 34113370a9bSStephane Eranian } 34213370a9bSStephane Eranian 34367ccdecdSJiri Olsa static void enable_counters(void) 34441191688SAndi Kleen { 345728c0ee0SJiri Olsa if (stat_config.initial_delay) 346728c0ee0SJiri Olsa usleep(stat_config.initial_delay * USEC_PER_MSEC); 34767ccdecdSJiri Olsa 34867ccdecdSJiri Olsa /* 34967ccdecdSJiri Olsa * We need to enable counters only if: 35067ccdecdSJiri Olsa * - we don't have tracee (attaching to task or cpu) 35167ccdecdSJiri Olsa * - we have initial delay configured 35267ccdecdSJiri Olsa */ 353728c0ee0SJiri Olsa if (!target__none(&target) || stat_config.initial_delay) 354ab46db0aSJiri Olsa perf_evlist__enable(evsel_list); 35541191688SAndi Kleen } 35641191688SAndi Kleen 3573df33effSMark Rutland static void disable_counters(void) 3583df33effSMark Rutland { 3593df33effSMark Rutland /* 3603df33effSMark Rutland * If we don't have tracee (attaching to task or cpu), counters may 3613df33effSMark Rutland * still be running. To get accurate group ratios, we must stop groups 3623df33effSMark Rutland * from counting before reading their constituent counters. 3633df33effSMark Rutland */ 3643df33effSMark Rutland if (!target__none(&target)) 3653df33effSMark Rutland perf_evlist__disable(evsel_list); 3663df33effSMark Rutland } 3673df33effSMark Rutland 368f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno; 3696af206fdSArnaldo Carvalho de Melo 3706af206fdSArnaldo Carvalho de Melo /* 3716af206fdSArnaldo Carvalho de Melo * perf_evlist__prepare_workload will send a SIGUSR1 3726af206fdSArnaldo Carvalho de Melo * if the fork fails, since we asked by setting its 3736af206fdSArnaldo Carvalho de Melo * want_signal to true. 3746af206fdSArnaldo Carvalho de Melo */ 375f33cbe72SArnaldo Carvalho de Melo static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info, 376f33cbe72SArnaldo Carvalho de Melo void *ucontext __maybe_unused) 3776af206fdSArnaldo Carvalho de Melo { 378f33cbe72SArnaldo Carvalho de Melo workload_exec_errno = info->si_value.sival_int; 3796af206fdSArnaldo Carvalho de Melo } 3806af206fdSArnaldo Carvalho de Melo 38182bf311eSJiri Olsa static bool perf_evsel__should_store_id(struct perf_evsel *counter) 38282bf311eSJiri Olsa { 38382bf311eSJiri Olsa return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID; 38482bf311eSJiri Olsa } 38582bf311eSJiri Olsa 386cbb5df7eSJiri Olsa static bool is_target_alive(struct target *_target, 387cbb5df7eSJiri Olsa struct thread_map *threads) 388cbb5df7eSJiri Olsa { 389cbb5df7eSJiri Olsa struct stat st; 390cbb5df7eSJiri Olsa int i; 391cbb5df7eSJiri Olsa 392cbb5df7eSJiri Olsa if (!target__has_task(_target)) 393cbb5df7eSJiri Olsa return true; 394cbb5df7eSJiri Olsa 395cbb5df7eSJiri Olsa for (i = 0; i < threads->nr; i++) { 396cbb5df7eSJiri Olsa char path[PATH_MAX]; 397cbb5df7eSJiri Olsa 398cbb5df7eSJiri Olsa scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(), 399cbb5df7eSJiri Olsa threads->map[i].pid); 400cbb5df7eSJiri Olsa 401cbb5df7eSJiri Olsa if (!stat(path, &st)) 402cbb5df7eSJiri Olsa return true; 403cbb5df7eSJiri Olsa } 404cbb5df7eSJiri Olsa 405cbb5df7eSJiri Olsa return false; 406cbb5df7eSJiri Olsa } 407cbb5df7eSJiri Olsa 408e55c14afSJiri Olsa static int __run_perf_stat(int argc, const char **argv, int run_idx) 40986470930SIngo Molnar { 410ec0d3d1fSJiri Olsa int interval = stat_config.interval; 411db06a269Syuzhoujian int times = stat_config.times; 412f1f8ad52Syuzhoujian int timeout = stat_config.timeout; 413d6195a6aSArnaldo Carvalho de Melo char msg[BUFSIZ]; 41486470930SIngo Molnar unsigned long long t0, t1; 415cac21425SJiri Olsa struct perf_evsel *counter; 41613370a9bSStephane Eranian struct timespec ts; 417410136f5SStephane Eranian size_t l; 41842202dd5SIngo Molnar int status = 0; 4196be2850eSZhang, Yanmin const bool forks = (argc > 0); 4208ceb41d7SJiri Olsa bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false; 4215d8bb1ecSMathieu Poirier struct perf_evsel_config_term *err_term; 42286470930SIngo Molnar 42313370a9bSStephane Eranian if (interval) { 424310ebb93SArnaldo Carvalho de Melo ts.tv_sec = interval / USEC_PER_MSEC; 425310ebb93SArnaldo Carvalho de Melo ts.tv_nsec = (interval % USEC_PER_MSEC) * NSEC_PER_MSEC; 426f1f8ad52Syuzhoujian } else if (timeout) { 427f1f8ad52Syuzhoujian ts.tv_sec = timeout / USEC_PER_MSEC; 428f1f8ad52Syuzhoujian ts.tv_nsec = (timeout % USEC_PER_MSEC) * NSEC_PER_MSEC; 42913370a9bSStephane Eranian } else { 43013370a9bSStephane Eranian ts.tv_sec = 1; 43113370a9bSStephane Eranian ts.tv_nsec = 0; 43213370a9bSStephane Eranian } 43313370a9bSStephane Eranian 434acf28922SNamhyung Kim if (forks) { 435664c98d4SJiri Olsa if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe, 436735f7e0bSArnaldo Carvalho de Melo workload_exec_failed_signal) < 0) { 437acf28922SNamhyung Kim perror("failed to prepare workload"); 438fceda7feSDavid Ahern return -1; 439051ae7f7SPaul Mackerras } 440d20a47e7SNamhyung Kim child_pid = evsel_list->workload.pid; 44160666c63SLiming Wang } 442051ae7f7SPaul Mackerras 4436a4bb04cSJiri Olsa if (group) 44463dab225SArnaldo Carvalho de Melo perf_evlist__set_leader(evsel_list); 4456a4bb04cSJiri Olsa 446e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evsel_list, counter) { 44742ef8a78SArnaldo Carvalho de Melo try_again: 448d09cefd2SJiri Olsa if (create_perf_stat_counter(counter, &stat_config, &target) < 0) { 4495a5dfe4bSAndi Kleen 4505a5dfe4bSAndi Kleen /* Weak group failed. Reset the group. */ 45135c1980eSAndi Kleen if ((errno == EINVAL || errno == EBADF) && 4525a5dfe4bSAndi Kleen counter->leader != counter && 4535a5dfe4bSAndi Kleen counter->weak_group) { 454c3537fc2SAndi Kleen counter = perf_evlist__reset_weak_group(evsel_list, counter); 4555a5dfe4bSAndi Kleen goto try_again; 4565a5dfe4bSAndi Kleen } 4575a5dfe4bSAndi Kleen 458979987a5SDavid Ahern /* 459979987a5SDavid Ahern * PPC returns ENXIO for HW counters until 2.6.37 460979987a5SDavid Ahern * (behavior changed with commit b0a873e). 461979987a5SDavid Ahern */ 46238f6ae1eSAnton Blanchard if (errno == EINVAL || errno == ENOSYS || 463979987a5SDavid Ahern errno == ENOENT || errno == EOPNOTSUPP || 464979987a5SDavid Ahern errno == ENXIO) { 465bb963e16SNamhyung Kim if (verbose > 0) 466c63ca0c0SDavid Ahern ui__warning("%s event is not supported by the kernel.\n", 4677289f83cSArnaldo Carvalho de Melo perf_evsel__name(counter)); 4682cee77c4SDavid Ahern counter->supported = false; 469cb5ef600SKan Liang 470cb5ef600SKan Liang if ((counter->leader != counter) || 471cb5ef600SKan Liang !(counter->leader->nr_members > 1)) 472ede70290SIngo Molnar continue; 47342ef8a78SArnaldo Carvalho de Melo } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { 474bb963e16SNamhyung Kim if (verbose > 0) 47542ef8a78SArnaldo Carvalho de Melo ui__warning("%s\n", msg); 47642ef8a78SArnaldo Carvalho de Melo goto try_again; 477ab6c79b8SJin Yao } else if (target__has_per_thread(&target) && 478ab6c79b8SJin Yao evsel_list->threads && 479ab6c79b8SJin Yao evsel_list->threads->err_thread != -1) { 480ab6c79b8SJin Yao /* 481ab6c79b8SJin Yao * For global --per-thread case, skip current 482ab6c79b8SJin Yao * error thread. 483ab6c79b8SJin Yao */ 484ab6c79b8SJin Yao if (!thread_map__remove(evsel_list->threads, 485ab6c79b8SJin Yao evsel_list->threads->err_thread)) { 486ab6c79b8SJin Yao evsel_list->threads->err_thread = -1; 487ab6c79b8SJin Yao goto try_again; 488ab6c79b8SJin Yao } 489c63ca0c0SDavid Ahern } 490ede70290SIngo Molnar 49156e52e85SArnaldo Carvalho de Melo perf_evsel__open_strerror(counter, &target, 49256e52e85SArnaldo Carvalho de Melo errno, msg, sizeof(msg)); 49356e52e85SArnaldo Carvalho de Melo ui__error("%s\n", msg); 49456e52e85SArnaldo Carvalho de Melo 495084ab9f8SArnaldo Carvalho de Melo if (child_pid != -1) 496084ab9f8SArnaldo Carvalho de Melo kill(child_pid, SIGTERM); 497fceda7feSDavid Ahern 498084ab9f8SArnaldo Carvalho de Melo return -1; 499084ab9f8SArnaldo Carvalho de Melo } 5002cee77c4SDavid Ahern counter->supported = true; 501410136f5SStephane Eranian 502410136f5SStephane Eranian l = strlen(counter->unit); 503df4f7b4dSJiri Olsa if (l > stat_config.unit_width) 504df4f7b4dSJiri Olsa stat_config.unit_width = l; 5052af4646dSJiri Olsa 50682bf311eSJiri Olsa if (perf_evsel__should_store_id(counter) && 507650d6220SJiri Olsa perf_evsel__store_ids(counter, evsel_list)) 5082af4646dSJiri Olsa return -1; 50948290609SArnaldo Carvalho de Melo } 51086470930SIngo Molnar 51123d4aad4SArnaldo Carvalho de Melo if (perf_evlist__apply_filters(evsel_list, &counter)) { 51262d94b00SArnaldo Carvalho de Melo pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", 51323d4aad4SArnaldo Carvalho de Melo counter->filter, perf_evsel__name(counter), errno, 514c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, msg, sizeof(msg))); 515cfd748aeSFrederic Weisbecker return -1; 516cfd748aeSFrederic Weisbecker } 517cfd748aeSFrederic Weisbecker 5185d8bb1ecSMathieu Poirier if (perf_evlist__apply_drv_configs(evsel_list, &counter, &err_term)) { 51962d94b00SArnaldo Carvalho de Melo pr_err("failed to set config \"%s\" on event %s with %d (%s)\n", 5205d8bb1ecSMathieu Poirier err_term->val.drv_cfg, perf_evsel__name(counter), errno, 5215d8bb1ecSMathieu Poirier str_error_r(errno, msg, sizeof(msg))); 5225d8bb1ecSMathieu Poirier return -1; 5235d8bb1ecSMathieu Poirier } 5245d8bb1ecSMathieu Poirier 5254979d0c7SJiri Olsa if (STAT_RECORD) { 5268ceb41d7SJiri Olsa int err, fd = perf_data__fd(&perf_stat.data); 5274979d0c7SJiri Olsa 528664c98d4SJiri Olsa if (is_pipe) { 5298ceb41d7SJiri Olsa err = perf_header__write_pipe(perf_data__fd(&perf_stat.data)); 530664c98d4SJiri Olsa } else { 5314979d0c7SJiri Olsa err = perf_session__write_header(perf_stat.session, evsel_list, 5324979d0c7SJiri Olsa fd, false); 533664c98d4SJiri Olsa } 534664c98d4SJiri Olsa 5354979d0c7SJiri Olsa if (err < 0) 5364979d0c7SJiri Olsa return err; 5378b99b1a4SJiri Olsa 5381c21e989SJiri Olsa err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list, 539c2c247f2SJiri Olsa process_synthesized_event, is_pipe); 5408b99b1a4SJiri Olsa if (err < 0) 5418b99b1a4SJiri Olsa return err; 5424979d0c7SJiri Olsa } 5434979d0c7SJiri Olsa 54486470930SIngo Molnar /* 54586470930SIngo Molnar * Enable counters and exec the command: 54686470930SIngo Molnar */ 54786470930SIngo Molnar t0 = rdclock(); 54813370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ref_time); 54986470930SIngo Molnar 55060666c63SLiming Wang if (forks) { 551acf28922SNamhyung Kim perf_evlist__start_workload(evsel_list); 55267ccdecdSJiri Olsa enable_counters(); 553acf28922SNamhyung Kim 554f1f8ad52Syuzhoujian if (interval || timeout) { 55513370a9bSStephane Eranian while (!waitpid(child_pid, &status, WNOHANG)) { 55613370a9bSStephane Eranian nanosleep(&ts, NULL); 557f1f8ad52Syuzhoujian if (timeout) 558f1f8ad52Syuzhoujian break; 559ba411a95SJiri Olsa process_interval(); 560db06a269Syuzhoujian if (interval_count && !(--times)) 561db06a269Syuzhoujian break; 56213370a9bSStephane Eranian } 56313370a9bSStephane Eranian } 5648897a891SJiri Olsa wait4(child_pid, &status, 0, &stat_config.ru_data); 5656af206fdSArnaldo Carvalho de Melo 566f33cbe72SArnaldo Carvalho de Melo if (workload_exec_errno) { 567c8b5f2c9SArnaldo Carvalho de Melo const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); 568f33cbe72SArnaldo Carvalho de Melo pr_err("Workload failed: %s\n", emsg); 5696af206fdSArnaldo Carvalho de Melo return -1; 570f33cbe72SArnaldo Carvalho de Melo } 5716af206fdSArnaldo Carvalho de Melo 57233e49ea7SAndi Kleen if (WIFSIGNALED(status)) 57333e49ea7SAndi Kleen psignal(WTERMSIG(status), argv[0]); 57460666c63SLiming Wang } else { 57567ccdecdSJiri Olsa enable_counters(); 57613370a9bSStephane Eranian while (!done) { 57713370a9bSStephane Eranian nanosleep(&ts, NULL); 578cbb5df7eSJiri Olsa if (!is_target_alive(&target, evsel_list->threads)) 579cbb5df7eSJiri Olsa break; 580f1f8ad52Syuzhoujian if (timeout) 581f1f8ad52Syuzhoujian break; 582db06a269Syuzhoujian if (interval) { 583ba411a95SJiri Olsa process_interval(); 584db06a269Syuzhoujian if (interval_count && !(--times)) 585db06a269Syuzhoujian break; 586db06a269Syuzhoujian } 58713370a9bSStephane Eranian } 58860666c63SLiming Wang } 58986470930SIngo Molnar 5903df33effSMark Rutland disable_counters(); 5913df33effSMark Rutland 59286470930SIngo Molnar t1 = rdclock(); 59386470930SIngo Molnar 59454ac0b1bSJiri Olsa if (stat_config.walltime_run_table) 59554ac0b1bSJiri Olsa stat_config.walltime_run[run_idx] = t1 - t0; 596e55c14afSJiri Olsa 5979e9772c4SPeter Zijlstra update_stats(&walltime_nsecs_stats, t1 - t0); 59842202dd5SIngo Molnar 5993df33effSMark Rutland /* 6003df33effSMark Rutland * Closing a group leader splits the group, and as we only disable 6013df33effSMark Rutland * group leaders, results in remaining events becoming enabled. To 6023df33effSMark Rutland * avoid arbitrary skew, we must read all counters before closing any 6033df33effSMark Rutland * group leaders. 6043df33effSMark Rutland */ 6053df33effSMark Rutland read_counters(); 6063df33effSMark Rutland perf_evlist__close(evsel_list); 607c52b12edSArnaldo Carvalho de Melo 60842202dd5SIngo Molnar return WEXITSTATUS(status); 60942202dd5SIngo Molnar } 61042202dd5SIngo Molnar 611e55c14afSJiri Olsa static int run_perf_stat(int argc, const char **argv, int run_idx) 6121f16c575SPeter Zijlstra { 6131f16c575SPeter Zijlstra int ret; 6141f16c575SPeter Zijlstra 6151f16c575SPeter Zijlstra if (pre_cmd) { 6161f16c575SPeter Zijlstra ret = system(pre_cmd); 6171f16c575SPeter Zijlstra if (ret) 6181f16c575SPeter Zijlstra return ret; 6191f16c575SPeter Zijlstra } 6201f16c575SPeter Zijlstra 6211f16c575SPeter Zijlstra if (sync_run) 6221f16c575SPeter Zijlstra sync(); 6231f16c575SPeter Zijlstra 624e55c14afSJiri Olsa ret = __run_perf_stat(argc, argv, run_idx); 6251f16c575SPeter Zijlstra if (ret) 6261f16c575SPeter Zijlstra return ret; 6271f16c575SPeter Zijlstra 6281f16c575SPeter Zijlstra if (post_cmd) { 6291f16c575SPeter Zijlstra ret = system(post_cmd); 6301f16c575SPeter Zijlstra if (ret) 6311f16c575SPeter Zijlstra return ret; 6321f16c575SPeter Zijlstra } 6331f16c575SPeter Zijlstra 6341f16c575SPeter Zijlstra return ret; 6351f16c575SPeter Zijlstra } 6361f16c575SPeter Zijlstra 637a5a9eac1SJiri Olsa static void print_counters(struct timespec *ts, int argc, const char **argv) 638a5a9eac1SJiri Olsa { 6390174820aSJiri Olsa /* Do not print anything if we record to the pipe. */ 6400174820aSJiri Olsa if (STAT_RECORD && perf_stat.data.is_pipe) 6410174820aSJiri Olsa return; 6420174820aSJiri Olsa 643c512e0eaSJiri Olsa perf_evlist__print_counters(evsel_list, &stat_config, &target, 644b64df7f3SJiri Olsa ts, argc, argv); 645a5a9eac1SJiri Olsa } 646a5a9eac1SJiri Olsa 647f7b7c26eSPeter Zijlstra static volatile int signr = -1; 648f7b7c26eSPeter Zijlstra 64986470930SIngo Molnar static void skip_signal(int signo) 65086470930SIngo Molnar { 651ec0d3d1fSJiri Olsa if ((child_pid == -1) || stat_config.interval) 65260666c63SLiming Wang done = 1; 65360666c63SLiming Wang 654f7b7c26eSPeter Zijlstra signr = signo; 655d07f0b12SStephane Eranian /* 656d07f0b12SStephane Eranian * render child_pid harmless 657d07f0b12SStephane Eranian * won't send SIGTERM to a random 658d07f0b12SStephane Eranian * process in case of race condition 659d07f0b12SStephane Eranian * and fast PID recycling 660d07f0b12SStephane Eranian */ 661d07f0b12SStephane Eranian child_pid = -1; 662f7b7c26eSPeter Zijlstra } 663f7b7c26eSPeter Zijlstra 664f7b7c26eSPeter Zijlstra static void sig_atexit(void) 665f7b7c26eSPeter Zijlstra { 666d07f0b12SStephane Eranian sigset_t set, oset; 667d07f0b12SStephane Eranian 668d07f0b12SStephane Eranian /* 669d07f0b12SStephane Eranian * avoid race condition with SIGCHLD handler 670d07f0b12SStephane Eranian * in skip_signal() which is modifying child_pid 671d07f0b12SStephane Eranian * goal is to avoid send SIGTERM to a random 672d07f0b12SStephane Eranian * process 673d07f0b12SStephane Eranian */ 674d07f0b12SStephane Eranian sigemptyset(&set); 675d07f0b12SStephane Eranian sigaddset(&set, SIGCHLD); 676d07f0b12SStephane Eranian sigprocmask(SIG_BLOCK, &set, &oset); 677d07f0b12SStephane Eranian 678933da83aSChris Wilson if (child_pid != -1) 679933da83aSChris Wilson kill(child_pid, SIGTERM); 680933da83aSChris Wilson 681d07f0b12SStephane Eranian sigprocmask(SIG_SETMASK, &oset, NULL); 682d07f0b12SStephane Eranian 683f7b7c26eSPeter Zijlstra if (signr == -1) 684f7b7c26eSPeter Zijlstra return; 685f7b7c26eSPeter Zijlstra 686f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 687f7b7c26eSPeter Zijlstra kill(getpid(), signr); 68886470930SIngo Molnar } 68986470930SIngo Molnar 6901d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused, 6911d037ca1SIrina Tirdea const char *s __maybe_unused, int unset) 692d7470b6aSStephane Eranian { 693d7470b6aSStephane Eranian big_num_opt = unset ? 0 : 1; 694d7470b6aSStephane Eranian return 0; 695d7470b6aSStephane Eranian } 696d7470b6aSStephane Eranian 69744b1e60aSAndi Kleen static int enable_metric_only(const struct option *opt __maybe_unused, 69844b1e60aSAndi Kleen const char *s __maybe_unused, int unset) 69944b1e60aSAndi Kleen { 70044b1e60aSAndi Kleen force_metric_only = true; 7010ce5aa02SJiri Olsa stat_config.metric_only = !unset; 70244b1e60aSAndi Kleen return 0; 70344b1e60aSAndi Kleen } 70444b1e60aSAndi Kleen 705b18f3e36SAndi Kleen static int parse_metric_groups(const struct option *opt, 706b18f3e36SAndi Kleen const char *str, 707b18f3e36SAndi Kleen int unset __maybe_unused) 708b18f3e36SAndi Kleen { 709d0192fdbSJiri Olsa return metricgroup__parse_groups(opt, str, &stat_config.metric_events); 710b18f3e36SAndi Kleen } 711b18f3e36SAndi Kleen 712e0547311SJiri Olsa static const struct option stat_options[] = { 713e0547311SJiri Olsa OPT_BOOLEAN('T', "transaction", &transaction_run, 714e0547311SJiri Olsa "hardware transaction statistics"), 715e0547311SJiri Olsa OPT_CALLBACK('e', "event", &evsel_list, "event", 716e0547311SJiri Olsa "event selector. use 'perf list' to list available events", 717e0547311SJiri Olsa parse_events_option), 718e0547311SJiri Olsa OPT_CALLBACK(0, "filter", &evsel_list, "filter", 719e0547311SJiri Olsa "event filter", parse_filter), 7205698f26bSJiri Olsa OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit, 721e0547311SJiri Olsa "child tasks do not inherit counters"), 722e0547311SJiri Olsa OPT_STRING('p', "pid", &target.pid, "pid", 723e0547311SJiri Olsa "stat events on existing process id"), 724e0547311SJiri Olsa OPT_STRING('t', "tid", &target.tid, "tid", 725e0547311SJiri Olsa "stat events on existing thread id"), 726e0547311SJiri Olsa OPT_BOOLEAN('a', "all-cpus", &target.system_wide, 727e0547311SJiri Olsa "system-wide collection from all CPUs"), 728e0547311SJiri Olsa OPT_BOOLEAN('g', "group", &group, 729e0547311SJiri Olsa "put the counters into a counter group"), 730e0547311SJiri Olsa OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"), 731e0547311SJiri Olsa OPT_INCR('v', "verbose", &verbose, 732e0547311SJiri Olsa "be more verbose (show counter open errors, etc)"), 733d97ae04bSJiri Olsa OPT_INTEGER('r', "repeat", &stat_config.run_count, 734e0547311SJiri Olsa "repeat command and print average + stddev (max: 100, forever: 0)"), 73554ac0b1bSJiri Olsa OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table, 736e55c14afSJiri Olsa "display details about each run (only with -r option)"), 737aea0dca1SJiri Olsa OPT_BOOLEAN('n', "null", &stat_config.null_run, 738e0547311SJiri Olsa "null run - dont start any counters"), 739e0547311SJiri Olsa OPT_INCR('d', "detailed", &detailed_run, 740e0547311SJiri Olsa "detailed run - start a lot of events"), 741e0547311SJiri Olsa OPT_BOOLEAN('S', "sync", &sync_run, 742e0547311SJiri Olsa "call sync() before starting a run"), 743e0547311SJiri Olsa OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 744e0547311SJiri Olsa "print large numbers with thousands\' separators", 745e0547311SJiri Olsa stat__set_big_num), 746e0547311SJiri Olsa OPT_STRING('C', "cpu", &target.cpu_list, "cpu", 747e0547311SJiri Olsa "list of cpus to monitor in system-wide"), 748e0547311SJiri Olsa OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode, 749e0547311SJiri Olsa "disable CPU count aggregation", AGGR_NONE), 750fdee335bSJiri Olsa OPT_BOOLEAN(0, "no-merge", &stat_config.no_merge, "Do not merge identical named events"), 751fa7070a3SJiri Olsa OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator", 752e0547311SJiri Olsa "print counts with custom separator"), 753e0547311SJiri Olsa OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 754e0547311SJiri Olsa "monitor event in cgroup name only", parse_cgroups), 755e0547311SJiri Olsa OPT_STRING('o', "output", &output_name, "file", "output file name"), 756e0547311SJiri Olsa OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), 757e0547311SJiri Olsa OPT_INTEGER(0, "log-fd", &output_fd, 758e0547311SJiri Olsa "log output to fd, instead of stderr"), 759e0547311SJiri Olsa OPT_STRING(0, "pre", &pre_cmd, "command", 760e0547311SJiri Olsa "command to run prior to the measured command"), 761e0547311SJiri Olsa OPT_STRING(0, "post", &post_cmd, "command", 762e0547311SJiri Olsa "command to run after to the measured command"), 763e0547311SJiri Olsa OPT_UINTEGER('I', "interval-print", &stat_config.interval, 7649dc9a95fSAlexey Budankov "print counts at regular interval in ms " 7659dc9a95fSAlexey Budankov "(overhead is possible for values <= 100ms)"), 766db06a269Syuzhoujian OPT_INTEGER(0, "interval-count", &stat_config.times, 767db06a269Syuzhoujian "print counts for fixed number of times"), 768132c6ba3SJiri Olsa OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear, 7699660e08eSJiri Olsa "clear screen in between new interval"), 770f1f8ad52Syuzhoujian OPT_UINTEGER(0, "timeout", &stat_config.timeout, 771f1f8ad52Syuzhoujian "stop workload and print counts after a timeout period in ms (>= 10ms)"), 772e0547311SJiri Olsa OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode, 773e0547311SJiri Olsa "aggregate counts per processor socket", AGGR_SOCKET), 774e0547311SJiri Olsa OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode, 775e0547311SJiri Olsa "aggregate counts per physical processor core", AGGR_CORE), 776e0547311SJiri Olsa OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode, 777e0547311SJiri Olsa "aggregate counts per thread", AGGR_THREAD), 778728c0ee0SJiri Olsa OPT_UINTEGER('D', "delay", &stat_config.initial_delay, 779e0547311SJiri Olsa "ms to wait before starting measurement after program start"), 7800ce5aa02SJiri Olsa OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL, 78144b1e60aSAndi Kleen "Only print computed metrics. No raw values", enable_metric_only), 78244b1e60aSAndi Kleen OPT_BOOLEAN(0, "topdown", &topdown_run, 78344b1e60aSAndi Kleen "measure topdown level 1 statistics"), 784daefd0bcSKan Liang OPT_BOOLEAN(0, "smi-cost", &smi_cost, 785daefd0bcSKan Liang "measure SMI cost"), 786b18f3e36SAndi Kleen OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list", 787b18f3e36SAndi Kleen "monitor specified metrics or metric groups (separated by ,)", 788b18f3e36SAndi Kleen parse_metric_groups), 789e0547311SJiri Olsa OPT_END() 790e0547311SJiri Olsa }; 791e0547311SJiri Olsa 7926f6b6594SJiri Olsa static int perf_stat__get_socket(struct perf_stat_config *config __maybe_unused, 7936f6b6594SJiri Olsa struct cpu_map *map, int cpu) 7941fe7a300SJiri Olsa { 7951fe7a300SJiri Olsa return cpu_map__get_socket(map, cpu, NULL); 7961fe7a300SJiri Olsa } 7971fe7a300SJiri Olsa 7986f6b6594SJiri Olsa static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused, 7996f6b6594SJiri Olsa struct cpu_map *map, int cpu) 8001fe7a300SJiri Olsa { 8011fe7a300SJiri Olsa return cpu_map__get_core(map, cpu, NULL); 8021fe7a300SJiri Olsa } 8031fe7a300SJiri Olsa 8041e5a2931SJiri Olsa static int cpu_map__get_max(struct cpu_map *map) 8051e5a2931SJiri Olsa { 8061e5a2931SJiri Olsa int i, max = -1; 8071e5a2931SJiri Olsa 8081e5a2931SJiri Olsa for (i = 0; i < map->nr; i++) { 8091e5a2931SJiri Olsa if (map->map[i] > max) 8101e5a2931SJiri Olsa max = map->map[i]; 8111e5a2931SJiri Olsa } 8121e5a2931SJiri Olsa 8131e5a2931SJiri Olsa return max; 8141e5a2931SJiri Olsa } 8151e5a2931SJiri Olsa 8166f6b6594SJiri Olsa static int perf_stat__get_aggr(struct perf_stat_config *config, 8176f6b6594SJiri Olsa aggr_get_id_t get_id, struct cpu_map *map, int idx) 8181e5a2931SJiri Olsa { 8191e5a2931SJiri Olsa int cpu; 8201e5a2931SJiri Olsa 8211e5a2931SJiri Olsa if (idx >= map->nr) 8221e5a2931SJiri Olsa return -1; 8231e5a2931SJiri Olsa 8241e5a2931SJiri Olsa cpu = map->map[idx]; 8251e5a2931SJiri Olsa 8266f6b6594SJiri Olsa if (config->cpus_aggr_map->map[cpu] == -1) 8276f6b6594SJiri Olsa config->cpus_aggr_map->map[cpu] = get_id(config, map, idx); 8281e5a2931SJiri Olsa 8296f6b6594SJiri Olsa return config->cpus_aggr_map->map[cpu]; 8301e5a2931SJiri Olsa } 8311e5a2931SJiri Olsa 8326f6b6594SJiri Olsa static int perf_stat__get_socket_cached(struct perf_stat_config *config, 8336f6b6594SJiri Olsa struct cpu_map *map, int idx) 8341e5a2931SJiri Olsa { 8356f6b6594SJiri Olsa return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx); 8361e5a2931SJiri Olsa } 8371e5a2931SJiri Olsa 8386f6b6594SJiri Olsa static int perf_stat__get_core_cached(struct perf_stat_config *config, 8396f6b6594SJiri Olsa struct cpu_map *map, int idx) 8401e5a2931SJiri Olsa { 8416f6b6594SJiri Olsa return perf_stat__get_aggr(config, perf_stat__get_core, map, idx); 8421e5a2931SJiri Olsa } 8431e5a2931SJiri Olsa 84486ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void) 84586ee6e18SStephane Eranian { 8461e5a2931SJiri Olsa int nr; 8471e5a2931SJiri Olsa 848421a50f3SJiri Olsa switch (stat_config.aggr_mode) { 84986ee6e18SStephane Eranian case AGGR_SOCKET: 8506f6b6594SJiri Olsa if (cpu_map__build_socket_map(evsel_list->cpus, &stat_config.aggr_map)) { 85186ee6e18SStephane Eranian perror("cannot build socket map"); 85286ee6e18SStephane Eranian return -1; 85386ee6e18SStephane Eranian } 8546f6b6594SJiri Olsa stat_config.aggr_get_id = perf_stat__get_socket_cached; 85586ee6e18SStephane Eranian break; 85612c08a9fSStephane Eranian case AGGR_CORE: 8576f6b6594SJiri Olsa if (cpu_map__build_core_map(evsel_list->cpus, &stat_config.aggr_map)) { 85812c08a9fSStephane Eranian perror("cannot build core map"); 85912c08a9fSStephane Eranian return -1; 86012c08a9fSStephane Eranian } 8616f6b6594SJiri Olsa stat_config.aggr_get_id = perf_stat__get_core_cached; 86212c08a9fSStephane Eranian break; 86386ee6e18SStephane Eranian case AGGR_NONE: 86486ee6e18SStephane Eranian case AGGR_GLOBAL: 86532b8af82SJiri Olsa case AGGR_THREAD: 866208df99eSJiri Olsa case AGGR_UNSET: 86786ee6e18SStephane Eranian default: 86886ee6e18SStephane Eranian break; 86986ee6e18SStephane Eranian } 8701e5a2931SJiri Olsa 8711e5a2931SJiri Olsa /* 8721e5a2931SJiri Olsa * The evsel_list->cpus is the base we operate on, 8731e5a2931SJiri Olsa * taking the highest cpu number to be the size of 8741e5a2931SJiri Olsa * the aggregation translate cpumap. 8751e5a2931SJiri Olsa */ 8761e5a2931SJiri Olsa nr = cpu_map__get_max(evsel_list->cpus); 8776f6b6594SJiri Olsa stat_config.cpus_aggr_map = cpu_map__empty_new(nr + 1); 8786f6b6594SJiri Olsa return stat_config.cpus_aggr_map ? 0 : -ENOMEM; 87986ee6e18SStephane Eranian } 88086ee6e18SStephane Eranian 881544c2ae7SMasami Hiramatsu static void perf_stat__exit_aggr_mode(void) 882544c2ae7SMasami Hiramatsu { 8836f6b6594SJiri Olsa cpu_map__put(stat_config.aggr_map); 8846f6b6594SJiri Olsa cpu_map__put(stat_config.cpus_aggr_map); 8856f6b6594SJiri Olsa stat_config.aggr_map = NULL; 8866f6b6594SJiri Olsa stat_config.cpus_aggr_map = NULL; 887544c2ae7SMasami Hiramatsu } 888544c2ae7SMasami Hiramatsu 88968d702f7SJiri Olsa static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, int idx) 89068d702f7SJiri Olsa { 89168d702f7SJiri Olsa int cpu; 89268d702f7SJiri Olsa 89368d702f7SJiri Olsa if (idx > map->nr) 89468d702f7SJiri Olsa return -1; 89568d702f7SJiri Olsa 89668d702f7SJiri Olsa cpu = map->map[idx]; 89768d702f7SJiri Olsa 898da8a58b5SJan Stancek if (cpu >= env->nr_cpus_avail) 89968d702f7SJiri Olsa return -1; 90068d702f7SJiri Olsa 90168d702f7SJiri Olsa return cpu; 90268d702f7SJiri Olsa } 90368d702f7SJiri Olsa 90468d702f7SJiri Olsa static int perf_env__get_socket(struct cpu_map *map, int idx, void *data) 90568d702f7SJiri Olsa { 90668d702f7SJiri Olsa struct perf_env *env = data; 90768d702f7SJiri Olsa int cpu = perf_env__get_cpu(env, map, idx); 90868d702f7SJiri Olsa 90968d702f7SJiri Olsa return cpu == -1 ? -1 : env->cpu[cpu].socket_id; 91068d702f7SJiri Olsa } 91168d702f7SJiri Olsa 91268d702f7SJiri Olsa static int perf_env__get_core(struct cpu_map *map, int idx, void *data) 91368d702f7SJiri Olsa { 91468d702f7SJiri Olsa struct perf_env *env = data; 91568d702f7SJiri Olsa int core = -1, cpu = perf_env__get_cpu(env, map, idx); 91668d702f7SJiri Olsa 91768d702f7SJiri Olsa if (cpu != -1) { 91868d702f7SJiri Olsa int socket_id = env->cpu[cpu].socket_id; 91968d702f7SJiri Olsa 92068d702f7SJiri Olsa /* 92168d702f7SJiri Olsa * Encode socket in upper 16 bits 92268d702f7SJiri Olsa * core_id is relative to socket, and 92368d702f7SJiri Olsa * we need a global id. So we combine 92468d702f7SJiri Olsa * socket + core id. 92568d702f7SJiri Olsa */ 92668d702f7SJiri Olsa core = (socket_id << 16) | (env->cpu[cpu].core_id & 0xffff); 92768d702f7SJiri Olsa } 92868d702f7SJiri Olsa 92968d702f7SJiri Olsa return core; 93068d702f7SJiri Olsa } 93168d702f7SJiri Olsa 93268d702f7SJiri Olsa static int perf_env__build_socket_map(struct perf_env *env, struct cpu_map *cpus, 93368d702f7SJiri Olsa struct cpu_map **sockp) 93468d702f7SJiri Olsa { 93568d702f7SJiri Olsa return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env); 93668d702f7SJiri Olsa } 93768d702f7SJiri Olsa 93868d702f7SJiri Olsa static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus, 93968d702f7SJiri Olsa struct cpu_map **corep) 94068d702f7SJiri Olsa { 94168d702f7SJiri Olsa return cpu_map__build_map(cpus, corep, perf_env__get_core, env); 94268d702f7SJiri Olsa } 94368d702f7SJiri Olsa 9446f6b6594SJiri Olsa static int perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused, 9456f6b6594SJiri Olsa struct cpu_map *map, int idx) 94668d702f7SJiri Olsa { 94768d702f7SJiri Olsa return perf_env__get_socket(map, idx, &perf_stat.session->header.env); 94868d702f7SJiri Olsa } 94968d702f7SJiri Olsa 9506f6b6594SJiri Olsa static int perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused, 9516f6b6594SJiri Olsa struct cpu_map *map, int idx) 95268d702f7SJiri Olsa { 95368d702f7SJiri Olsa return perf_env__get_core(map, idx, &perf_stat.session->header.env); 95468d702f7SJiri Olsa } 95568d702f7SJiri Olsa 95668d702f7SJiri Olsa static int perf_stat_init_aggr_mode_file(struct perf_stat *st) 95768d702f7SJiri Olsa { 95868d702f7SJiri Olsa struct perf_env *env = &st->session->header.env; 95968d702f7SJiri Olsa 96068d702f7SJiri Olsa switch (stat_config.aggr_mode) { 96168d702f7SJiri Olsa case AGGR_SOCKET: 9626f6b6594SJiri Olsa if (perf_env__build_socket_map(env, evsel_list->cpus, &stat_config.aggr_map)) { 96368d702f7SJiri Olsa perror("cannot build socket map"); 96468d702f7SJiri Olsa return -1; 96568d702f7SJiri Olsa } 9666f6b6594SJiri Olsa stat_config.aggr_get_id = perf_stat__get_socket_file; 96768d702f7SJiri Olsa break; 96868d702f7SJiri Olsa case AGGR_CORE: 9696f6b6594SJiri Olsa if (perf_env__build_core_map(env, evsel_list->cpus, &stat_config.aggr_map)) { 97068d702f7SJiri Olsa perror("cannot build core map"); 97168d702f7SJiri Olsa return -1; 97268d702f7SJiri Olsa } 9736f6b6594SJiri Olsa stat_config.aggr_get_id = perf_stat__get_core_file; 97468d702f7SJiri Olsa break; 97568d702f7SJiri Olsa case AGGR_NONE: 97668d702f7SJiri Olsa case AGGR_GLOBAL: 97768d702f7SJiri Olsa case AGGR_THREAD: 97868d702f7SJiri Olsa case AGGR_UNSET: 97968d702f7SJiri Olsa default: 98068d702f7SJiri Olsa break; 98168d702f7SJiri Olsa } 98268d702f7SJiri Olsa 98368d702f7SJiri Olsa return 0; 98468d702f7SJiri Olsa } 98568d702f7SJiri Olsa 98644b1e60aSAndi Kleen static int topdown_filter_events(const char **attr, char **str, bool use_group) 98744b1e60aSAndi Kleen { 98844b1e60aSAndi Kleen int off = 0; 98944b1e60aSAndi Kleen int i; 99044b1e60aSAndi Kleen int len = 0; 99144b1e60aSAndi Kleen char *s; 99244b1e60aSAndi Kleen 99344b1e60aSAndi Kleen for (i = 0; attr[i]; i++) { 99444b1e60aSAndi Kleen if (pmu_have_event("cpu", attr[i])) { 99544b1e60aSAndi Kleen len += strlen(attr[i]) + 1; 99644b1e60aSAndi Kleen attr[i - off] = attr[i]; 99744b1e60aSAndi Kleen } else 99844b1e60aSAndi Kleen off++; 99944b1e60aSAndi Kleen } 100044b1e60aSAndi Kleen attr[i - off] = NULL; 100144b1e60aSAndi Kleen 100244b1e60aSAndi Kleen *str = malloc(len + 1 + 2); 100344b1e60aSAndi Kleen if (!*str) 100444b1e60aSAndi Kleen return -1; 100544b1e60aSAndi Kleen s = *str; 100644b1e60aSAndi Kleen if (i - off == 0) { 100744b1e60aSAndi Kleen *s = 0; 100844b1e60aSAndi Kleen return 0; 100944b1e60aSAndi Kleen } 101044b1e60aSAndi Kleen if (use_group) 101144b1e60aSAndi Kleen *s++ = '{'; 101244b1e60aSAndi Kleen for (i = 0; attr[i]; i++) { 101344b1e60aSAndi Kleen strcpy(s, attr[i]); 101444b1e60aSAndi Kleen s += strlen(s); 101544b1e60aSAndi Kleen *s++ = ','; 101644b1e60aSAndi Kleen } 101744b1e60aSAndi Kleen if (use_group) { 101844b1e60aSAndi Kleen s[-1] = '}'; 101944b1e60aSAndi Kleen *s = 0; 102044b1e60aSAndi Kleen } else 102144b1e60aSAndi Kleen s[-1] = 0; 102244b1e60aSAndi Kleen return 0; 102344b1e60aSAndi Kleen } 102444b1e60aSAndi Kleen 102544b1e60aSAndi Kleen __weak bool arch_topdown_check_group(bool *warn) 102644b1e60aSAndi Kleen { 102744b1e60aSAndi Kleen *warn = false; 102844b1e60aSAndi Kleen return false; 102944b1e60aSAndi Kleen } 103044b1e60aSAndi Kleen 103144b1e60aSAndi Kleen __weak void arch_topdown_group_warn(void) 103244b1e60aSAndi Kleen { 103344b1e60aSAndi Kleen } 103444b1e60aSAndi Kleen 10352cba3ffbSIngo Molnar /* 10362cba3ffbSIngo Molnar * Add default attributes, if there were no attributes specified or 10372cba3ffbSIngo Molnar * if -d/--detailed, -d -d or -d -d -d is used: 10382cba3ffbSIngo Molnar */ 10392cba3ffbSIngo Molnar static int add_default_attributes(void) 10402cba3ffbSIngo Molnar { 104144b1e60aSAndi Kleen int err; 10429dec4473SAndi Kleen struct perf_event_attr default_attrs0[] = { 1043b070a547SArnaldo Carvalho de Melo 1044b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 1045b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 1046b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 1047b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 1048b070a547SArnaldo Carvalho de Melo 1049b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 10509dec4473SAndi Kleen }; 10519dec4473SAndi Kleen struct perf_event_attr frontend_attrs[] = { 1052b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 10539dec4473SAndi Kleen }; 10549dec4473SAndi Kleen struct perf_event_attr backend_attrs[] = { 1055b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 10569dec4473SAndi Kleen }; 10579dec4473SAndi Kleen struct perf_event_attr default_attrs1[] = { 1058b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 1059b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 1060b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 1061b070a547SArnaldo Carvalho de Melo 1062b070a547SArnaldo Carvalho de Melo }; 1063b070a547SArnaldo Carvalho de Melo 1064b070a547SArnaldo Carvalho de Melo /* 1065b070a547SArnaldo Carvalho de Melo * Detailed stats (-d), covering the L1 and last level data caches: 1066b070a547SArnaldo Carvalho de Melo */ 1067b070a547SArnaldo Carvalho de Melo struct perf_event_attr detailed_attrs[] = { 1068b070a547SArnaldo Carvalho de Melo 1069b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1070b070a547SArnaldo Carvalho de Melo .config = 1071b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1072b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1073b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1074b070a547SArnaldo Carvalho de Melo 1075b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1076b070a547SArnaldo Carvalho de Melo .config = 1077b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1078b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1079b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1080b070a547SArnaldo Carvalho de Melo 1081b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1082b070a547SArnaldo Carvalho de Melo .config = 1083b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1084b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1085b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1086b070a547SArnaldo Carvalho de Melo 1087b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1088b070a547SArnaldo Carvalho de Melo .config = 1089b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1090b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1091b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1092b070a547SArnaldo Carvalho de Melo }; 1093b070a547SArnaldo Carvalho de Melo 1094b070a547SArnaldo Carvalho de Melo /* 1095b070a547SArnaldo Carvalho de Melo * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: 1096b070a547SArnaldo Carvalho de Melo */ 1097b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_detailed_attrs[] = { 1098b070a547SArnaldo Carvalho de Melo 1099b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1100b070a547SArnaldo Carvalho de Melo .config = 1101b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1102b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1103b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1104b070a547SArnaldo Carvalho de Melo 1105b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1106b070a547SArnaldo Carvalho de Melo .config = 1107b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1108b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1109b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1110b070a547SArnaldo Carvalho de Melo 1111b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1112b070a547SArnaldo Carvalho de Melo .config = 1113b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1114b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1115b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1116b070a547SArnaldo Carvalho de Melo 1117b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1118b070a547SArnaldo Carvalho de Melo .config = 1119b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1120b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1121b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1122b070a547SArnaldo Carvalho de Melo 1123b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1124b070a547SArnaldo Carvalho de Melo .config = 1125b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1126b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1127b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1128b070a547SArnaldo Carvalho de Melo 1129b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1130b070a547SArnaldo Carvalho de Melo .config = 1131b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1132b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1133b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1134b070a547SArnaldo Carvalho de Melo 1135b070a547SArnaldo Carvalho de Melo }; 1136b070a547SArnaldo Carvalho de Melo 1137b070a547SArnaldo Carvalho de Melo /* 1138b070a547SArnaldo Carvalho de Melo * Very, very detailed stats (-d -d -d), adding prefetch events: 1139b070a547SArnaldo Carvalho de Melo */ 1140b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_very_detailed_attrs[] = { 1141b070a547SArnaldo Carvalho de Melo 1142b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1143b070a547SArnaldo Carvalho de Melo .config = 1144b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1145b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1146b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1147b070a547SArnaldo Carvalho de Melo 1148b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1149b070a547SArnaldo Carvalho de Melo .config = 1150b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1151b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1152b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1153b070a547SArnaldo Carvalho de Melo }; 1154a5cfa621SJiri Olsa struct parse_events_error errinfo; 1155b070a547SArnaldo Carvalho de Melo 11562cba3ffbSIngo Molnar /* Set attrs if no event is selected and !null_run: */ 1157aea0dca1SJiri Olsa if (stat_config.null_run) 11582cba3ffbSIngo Molnar return 0; 11592cba3ffbSIngo Molnar 11604cabc3d1SAndi Kleen if (transaction_run) { 1161742d92ffSThomas Richter /* Handle -T as -M transaction. Once platform specific metrics 1162742d92ffSThomas Richter * support has been added to the json files, all archictures 1163742d92ffSThomas Richter * will use this approach. To determine transaction support 1164742d92ffSThomas Richter * on an architecture test for such a metric name. 1165742d92ffSThomas Richter */ 1166742d92ffSThomas Richter if (metricgroup__has_metric("transaction")) { 1167742d92ffSThomas Richter struct option opt = { .value = &evsel_list }; 1168742d92ffSThomas Richter 1169742d92ffSThomas Richter return metricgroup__parse_groups(&opt, "transaction", 1170d0192fdbSJiri Olsa &stat_config.metric_events); 1171742d92ffSThomas Richter } 1172742d92ffSThomas Richter 11734cabc3d1SAndi Kleen if (pmu_have_event("cpu", "cycles-ct") && 11744cabc3d1SAndi Kleen pmu_have_event("cpu", "el-start")) 1175fca32340SThomas Richter err = parse_events(evsel_list, transaction_attrs, 1176fca32340SThomas Richter &errinfo); 11774cabc3d1SAndi Kleen else 1178fca32340SThomas Richter err = parse_events(evsel_list, 1179fca32340SThomas Richter transaction_limited_attrs, 1180fca32340SThomas Richter &errinfo); 1181a454742cSJiri Olsa if (err) { 11824cabc3d1SAndi Kleen fprintf(stderr, "Cannot set up transaction events\n"); 1183a5cfa621SJiri Olsa parse_events_print_error(&errinfo, transaction_attrs); 11844cabc3d1SAndi Kleen return -1; 11854cabc3d1SAndi Kleen } 11864cabc3d1SAndi Kleen return 0; 11874cabc3d1SAndi Kleen } 11884cabc3d1SAndi Kleen 1189daefd0bcSKan Liang if (smi_cost) { 1190daefd0bcSKan Liang int smi; 1191daefd0bcSKan Liang 1192daefd0bcSKan Liang if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) { 1193daefd0bcSKan Liang fprintf(stderr, "freeze_on_smi is not supported.\n"); 1194daefd0bcSKan Liang return -1; 1195daefd0bcSKan Liang } 1196daefd0bcSKan Liang 1197daefd0bcSKan Liang if (!smi) { 1198daefd0bcSKan Liang if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) { 1199daefd0bcSKan Liang fprintf(stderr, "Failed to set freeze_on_smi.\n"); 1200daefd0bcSKan Liang return -1; 1201daefd0bcSKan Liang } 1202daefd0bcSKan Liang smi_reset = true; 1203daefd0bcSKan Liang } 1204daefd0bcSKan Liang 1205daefd0bcSKan Liang if (pmu_have_event("msr", "aperf") && 1206daefd0bcSKan Liang pmu_have_event("msr", "smi")) { 1207daefd0bcSKan Liang if (!force_metric_only) 12080ce5aa02SJiri Olsa stat_config.metric_only = true; 1209a5cfa621SJiri Olsa err = parse_events(evsel_list, smi_cost_attrs, &errinfo); 1210daefd0bcSKan Liang } else { 1211daefd0bcSKan Liang fprintf(stderr, "To measure SMI cost, it needs " 1212daefd0bcSKan Liang "msr/aperf/, msr/smi/ and cpu/cycles/ support\n"); 1213a5cfa621SJiri Olsa parse_events_print_error(&errinfo, smi_cost_attrs); 1214daefd0bcSKan Liang return -1; 1215daefd0bcSKan Liang } 1216daefd0bcSKan Liang if (err) { 1217daefd0bcSKan Liang fprintf(stderr, "Cannot set up SMI cost events\n"); 1218daefd0bcSKan Liang return -1; 1219daefd0bcSKan Liang } 1220daefd0bcSKan Liang return 0; 1221daefd0bcSKan Liang } 1222daefd0bcSKan Liang 122344b1e60aSAndi Kleen if (topdown_run) { 122444b1e60aSAndi Kleen char *str = NULL; 122544b1e60aSAndi Kleen bool warn = false; 122644b1e60aSAndi Kleen 122744b1e60aSAndi Kleen if (stat_config.aggr_mode != AGGR_GLOBAL && 122844b1e60aSAndi Kleen stat_config.aggr_mode != AGGR_CORE) { 122944b1e60aSAndi Kleen pr_err("top down event configuration requires --per-core mode\n"); 123044b1e60aSAndi Kleen return -1; 123144b1e60aSAndi Kleen } 123244b1e60aSAndi Kleen stat_config.aggr_mode = AGGR_CORE; 123344b1e60aSAndi Kleen if (nr_cgroups || !target__has_cpu(&target)) { 123444b1e60aSAndi Kleen pr_err("top down event configuration requires system-wide mode (-a)\n"); 123544b1e60aSAndi Kleen return -1; 123644b1e60aSAndi Kleen } 123744b1e60aSAndi Kleen 123844b1e60aSAndi Kleen if (!force_metric_only) 12390ce5aa02SJiri Olsa stat_config.metric_only = true; 124044b1e60aSAndi Kleen if (topdown_filter_events(topdown_attrs, &str, 124144b1e60aSAndi Kleen arch_topdown_check_group(&warn)) < 0) { 124244b1e60aSAndi Kleen pr_err("Out of memory\n"); 124344b1e60aSAndi Kleen return -1; 124444b1e60aSAndi Kleen } 124544b1e60aSAndi Kleen if (topdown_attrs[0] && str) { 124644b1e60aSAndi Kleen if (warn) 124744b1e60aSAndi Kleen arch_topdown_group_warn(); 1248a5cfa621SJiri Olsa err = parse_events(evsel_list, str, &errinfo); 124944b1e60aSAndi Kleen if (err) { 125044b1e60aSAndi Kleen fprintf(stderr, 125144b1e60aSAndi Kleen "Cannot set up top down events %s: %d\n", 125244b1e60aSAndi Kleen str, err); 125344b1e60aSAndi Kleen free(str); 1254a5cfa621SJiri Olsa parse_events_print_error(&errinfo, str); 125544b1e60aSAndi Kleen return -1; 125644b1e60aSAndi Kleen } 125744b1e60aSAndi Kleen } else { 125844b1e60aSAndi Kleen fprintf(stderr, "System does not support topdown\n"); 125944b1e60aSAndi Kleen return -1; 126044b1e60aSAndi Kleen } 126144b1e60aSAndi Kleen free(str); 126244b1e60aSAndi Kleen } 126344b1e60aSAndi Kleen 12642cba3ffbSIngo Molnar if (!evsel_list->nr_entries) { 1265a1f3d567SNamhyung Kim if (target__has_cpu(&target)) 1266a1f3d567SNamhyung Kim default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK; 1267a1f3d567SNamhyung Kim 12689dec4473SAndi Kleen if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0) 12699dec4473SAndi Kleen return -1; 12709dec4473SAndi Kleen if (pmu_have_event("cpu", "stalled-cycles-frontend")) { 12719dec4473SAndi Kleen if (perf_evlist__add_default_attrs(evsel_list, 12729dec4473SAndi Kleen frontend_attrs) < 0) 12739dec4473SAndi Kleen return -1; 12749dec4473SAndi Kleen } 12759dec4473SAndi Kleen if (pmu_have_event("cpu", "stalled-cycles-backend")) { 12769dec4473SAndi Kleen if (perf_evlist__add_default_attrs(evsel_list, 12779dec4473SAndi Kleen backend_attrs) < 0) 12789dec4473SAndi Kleen return -1; 12799dec4473SAndi Kleen } 12809dec4473SAndi Kleen if (perf_evlist__add_default_attrs(evsel_list, default_attrs1) < 0) 12812cba3ffbSIngo Molnar return -1; 12822cba3ffbSIngo Molnar } 12832cba3ffbSIngo Molnar 12842cba3ffbSIngo Molnar /* Detailed events get appended to the event list: */ 12852cba3ffbSIngo Molnar 12862cba3ffbSIngo Molnar if (detailed_run < 1) 12872cba3ffbSIngo Molnar return 0; 12882cba3ffbSIngo Molnar 12892cba3ffbSIngo Molnar /* Append detailed run extra attributes: */ 129079695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) 12912cba3ffbSIngo Molnar return -1; 12922cba3ffbSIngo Molnar 12932cba3ffbSIngo Molnar if (detailed_run < 2) 12942cba3ffbSIngo Molnar return 0; 12952cba3ffbSIngo Molnar 12962cba3ffbSIngo Molnar /* Append very detailed run extra attributes: */ 129779695e1bSArnaldo Carvalho de Melo if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) 12982cba3ffbSIngo Molnar return -1; 12992cba3ffbSIngo Molnar 13002cba3ffbSIngo Molnar if (detailed_run < 3) 13012cba3ffbSIngo Molnar return 0; 13022cba3ffbSIngo Molnar 13032cba3ffbSIngo Molnar /* Append very, very detailed run extra attributes: */ 130479695e1bSArnaldo Carvalho de Melo return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); 13052cba3ffbSIngo Molnar } 13062cba3ffbSIngo Molnar 13078a59f3ccSJiri Olsa static const char * const stat_record_usage[] = { 13084979d0c7SJiri Olsa "perf stat record [<options>]", 13094979d0c7SJiri Olsa NULL, 13104979d0c7SJiri Olsa }; 13114979d0c7SJiri Olsa 13123ba78bd0SJiri Olsa static void init_features(struct perf_session *session) 13133ba78bd0SJiri Olsa { 13143ba78bd0SJiri Olsa int feat; 13153ba78bd0SJiri Olsa 13163ba78bd0SJiri Olsa for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) 13173ba78bd0SJiri Olsa perf_header__set_feat(&session->header, feat); 13183ba78bd0SJiri Olsa 13193ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_BUILD_ID); 13203ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); 13213ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 13223ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_AUXTRACE); 13233ba78bd0SJiri Olsa } 13243ba78bd0SJiri Olsa 13254979d0c7SJiri Olsa static int __cmd_record(int argc, const char **argv) 13264979d0c7SJiri Olsa { 13274979d0c7SJiri Olsa struct perf_session *session; 13288ceb41d7SJiri Olsa struct perf_data *data = &perf_stat.data; 13294979d0c7SJiri Olsa 13308a59f3ccSJiri Olsa argc = parse_options(argc, argv, stat_options, stat_record_usage, 13314979d0c7SJiri Olsa PARSE_OPT_STOP_AT_NON_OPTION); 13324979d0c7SJiri Olsa 13334979d0c7SJiri Olsa if (output_name) 1334eae8ad80SJiri Olsa data->file.path = output_name; 13354979d0c7SJiri Olsa 1336d97ae04bSJiri Olsa if (stat_config.run_count != 1 || forever) { 1337e9d6db8eSJiri Olsa pr_err("Cannot use -r option with perf stat record.\n"); 1338e9d6db8eSJiri Olsa return -1; 1339e9d6db8eSJiri Olsa } 1340e9d6db8eSJiri Olsa 13418ceb41d7SJiri Olsa session = perf_session__new(data, false, NULL); 13424979d0c7SJiri Olsa if (session == NULL) { 13434979d0c7SJiri Olsa pr_err("Perf session creation failed.\n"); 13444979d0c7SJiri Olsa return -1; 13454979d0c7SJiri Olsa } 13464979d0c7SJiri Olsa 13473ba78bd0SJiri Olsa init_features(session); 13483ba78bd0SJiri Olsa 13494979d0c7SJiri Olsa session->evlist = evsel_list; 13504979d0c7SJiri Olsa perf_stat.session = session; 13514979d0c7SJiri Olsa perf_stat.record = true; 13524979d0c7SJiri Olsa return argc; 13534979d0c7SJiri Olsa } 13544979d0c7SJiri Olsa 135589f1688aSJiri Olsa static int process_stat_round_event(struct perf_session *session, 135689f1688aSJiri Olsa union perf_event *event) 1357a56f9390SJiri Olsa { 1358e3b03b6cSAndi Kleen struct stat_round_event *stat_round = &event->stat_round; 1359a56f9390SJiri Olsa struct perf_evsel *counter; 1360a56f9390SJiri Olsa struct timespec tsh, *ts = NULL; 1361a56f9390SJiri Olsa const char **argv = session->header.env.cmdline_argv; 1362a56f9390SJiri Olsa int argc = session->header.env.nr_cmdline; 1363a56f9390SJiri Olsa 1364e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evsel_list, counter) 1365a56f9390SJiri Olsa perf_stat_process_counter(&stat_config, counter); 1366a56f9390SJiri Olsa 1367e3b03b6cSAndi Kleen if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL) 1368e3b03b6cSAndi Kleen update_stats(&walltime_nsecs_stats, stat_round->time); 1369a56f9390SJiri Olsa 1370e3b03b6cSAndi Kleen if (stat_config.interval && stat_round->time) { 1371bd48c63eSArnaldo Carvalho de Melo tsh.tv_sec = stat_round->time / NSEC_PER_SEC; 1372bd48c63eSArnaldo Carvalho de Melo tsh.tv_nsec = stat_round->time % NSEC_PER_SEC; 1373a56f9390SJiri Olsa ts = &tsh; 1374a56f9390SJiri Olsa } 1375a56f9390SJiri Olsa 1376a56f9390SJiri Olsa print_counters(ts, argc, argv); 1377a56f9390SJiri Olsa return 0; 1378a56f9390SJiri Olsa } 1379a56f9390SJiri Olsa 138062ba18baSJiri Olsa static 138189f1688aSJiri Olsa int process_stat_config_event(struct perf_session *session, 138289f1688aSJiri Olsa union perf_event *event) 138362ba18baSJiri Olsa { 138489f1688aSJiri Olsa struct perf_tool *tool = session->tool; 138568d702f7SJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 138668d702f7SJiri Olsa 138762ba18baSJiri Olsa perf_event__read_stat_config(&stat_config, &event->stat_config); 138868d702f7SJiri Olsa 138989af4e05SJiri Olsa if (cpu_map__empty(st->cpus)) { 139089af4e05SJiri Olsa if (st->aggr_mode != AGGR_UNSET) 139189af4e05SJiri Olsa pr_warning("warning: processing task data, aggregation mode not set\n"); 139289af4e05SJiri Olsa return 0; 139389af4e05SJiri Olsa } 139489af4e05SJiri Olsa 139589af4e05SJiri Olsa if (st->aggr_mode != AGGR_UNSET) 139689af4e05SJiri Olsa stat_config.aggr_mode = st->aggr_mode; 139789af4e05SJiri Olsa 13988ceb41d7SJiri Olsa if (perf_stat.data.is_pipe) 139968d702f7SJiri Olsa perf_stat_init_aggr_mode(); 140068d702f7SJiri Olsa else 140168d702f7SJiri Olsa perf_stat_init_aggr_mode_file(st); 140268d702f7SJiri Olsa 140362ba18baSJiri Olsa return 0; 140462ba18baSJiri Olsa } 140562ba18baSJiri Olsa 14061975d36eSJiri Olsa static int set_maps(struct perf_stat *st) 14071975d36eSJiri Olsa { 14081975d36eSJiri Olsa if (!st->cpus || !st->threads) 14091975d36eSJiri Olsa return 0; 14101975d36eSJiri Olsa 14111975d36eSJiri Olsa if (WARN_ONCE(st->maps_allocated, "stats double allocation\n")) 14121975d36eSJiri Olsa return -EINVAL; 14131975d36eSJiri Olsa 14141975d36eSJiri Olsa perf_evlist__set_maps(evsel_list, st->cpus, st->threads); 14151975d36eSJiri Olsa 14161975d36eSJiri Olsa if (perf_evlist__alloc_stats(evsel_list, true)) 14171975d36eSJiri Olsa return -ENOMEM; 14181975d36eSJiri Olsa 14191975d36eSJiri Olsa st->maps_allocated = true; 14201975d36eSJiri Olsa return 0; 14211975d36eSJiri Olsa } 14221975d36eSJiri Olsa 14231975d36eSJiri Olsa static 142489f1688aSJiri Olsa int process_thread_map_event(struct perf_session *session, 142589f1688aSJiri Olsa union perf_event *event) 14261975d36eSJiri Olsa { 142789f1688aSJiri Olsa struct perf_tool *tool = session->tool; 14281975d36eSJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 14291975d36eSJiri Olsa 14301975d36eSJiri Olsa if (st->threads) { 14311975d36eSJiri Olsa pr_warning("Extra thread map event, ignoring.\n"); 14321975d36eSJiri Olsa return 0; 14331975d36eSJiri Olsa } 14341975d36eSJiri Olsa 14351975d36eSJiri Olsa st->threads = thread_map__new_event(&event->thread_map); 14361975d36eSJiri Olsa if (!st->threads) 14371975d36eSJiri Olsa return -ENOMEM; 14381975d36eSJiri Olsa 14391975d36eSJiri Olsa return set_maps(st); 14401975d36eSJiri Olsa } 14411975d36eSJiri Olsa 14421975d36eSJiri Olsa static 144389f1688aSJiri Olsa int process_cpu_map_event(struct perf_session *session, 144489f1688aSJiri Olsa union perf_event *event) 14451975d36eSJiri Olsa { 144689f1688aSJiri Olsa struct perf_tool *tool = session->tool; 14471975d36eSJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 14481975d36eSJiri Olsa struct cpu_map *cpus; 14491975d36eSJiri Olsa 14501975d36eSJiri Olsa if (st->cpus) { 14511975d36eSJiri Olsa pr_warning("Extra cpu map event, ignoring.\n"); 14521975d36eSJiri Olsa return 0; 14531975d36eSJiri Olsa } 14541975d36eSJiri Olsa 14551975d36eSJiri Olsa cpus = cpu_map__new_data(&event->cpu_map.data); 14561975d36eSJiri Olsa if (!cpus) 14571975d36eSJiri Olsa return -ENOMEM; 14581975d36eSJiri Olsa 14591975d36eSJiri Olsa st->cpus = cpus; 14601975d36eSJiri Olsa return set_maps(st); 14611975d36eSJiri Olsa } 14621975d36eSJiri Olsa 146356739444SJin Yao static int runtime_stat_new(struct perf_stat_config *config, int nthreads) 146456739444SJin Yao { 146556739444SJin Yao int i; 146656739444SJin Yao 146756739444SJin Yao config->stats = calloc(nthreads, sizeof(struct runtime_stat)); 146856739444SJin Yao if (!config->stats) 146956739444SJin Yao return -1; 147056739444SJin Yao 147156739444SJin Yao config->stats_num = nthreads; 147256739444SJin Yao 147356739444SJin Yao for (i = 0; i < nthreads; i++) 147456739444SJin Yao runtime_stat__init(&config->stats[i]); 147556739444SJin Yao 147656739444SJin Yao return 0; 147756739444SJin Yao } 147856739444SJin Yao 147956739444SJin Yao static void runtime_stat_delete(struct perf_stat_config *config) 148056739444SJin Yao { 148156739444SJin Yao int i; 148256739444SJin Yao 148356739444SJin Yao if (!config->stats) 148456739444SJin Yao return; 148556739444SJin Yao 148656739444SJin Yao for (i = 0; i < config->stats_num; i++) 148756739444SJin Yao runtime_stat__exit(&config->stats[i]); 148856739444SJin Yao 148956739444SJin Yao free(config->stats); 149056739444SJin Yao } 149156739444SJin Yao 14928a59f3ccSJiri Olsa static const char * const stat_report_usage[] = { 1493ba6039b6SJiri Olsa "perf stat report [<options>]", 1494ba6039b6SJiri Olsa NULL, 1495ba6039b6SJiri Olsa }; 1496ba6039b6SJiri Olsa 1497ba6039b6SJiri Olsa static struct perf_stat perf_stat = { 1498ba6039b6SJiri Olsa .tool = { 1499ba6039b6SJiri Olsa .attr = perf_event__process_attr, 1500fa6ea781SJiri Olsa .event_update = perf_event__process_event_update, 15011975d36eSJiri Olsa .thread_map = process_thread_map_event, 15021975d36eSJiri Olsa .cpu_map = process_cpu_map_event, 150362ba18baSJiri Olsa .stat_config = process_stat_config_event, 1504a56f9390SJiri Olsa .stat = perf_event__process_stat_event, 1505a56f9390SJiri Olsa .stat_round = process_stat_round_event, 1506ba6039b6SJiri Olsa }, 150789af4e05SJiri Olsa .aggr_mode = AGGR_UNSET, 1508ba6039b6SJiri Olsa }; 1509ba6039b6SJiri Olsa 1510ba6039b6SJiri Olsa static int __cmd_report(int argc, const char **argv) 1511ba6039b6SJiri Olsa { 1512ba6039b6SJiri Olsa struct perf_session *session; 1513ba6039b6SJiri Olsa const struct option options[] = { 1514ba6039b6SJiri Olsa OPT_STRING('i', "input", &input_name, "file", "input file name"), 151589af4e05SJiri Olsa OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode, 151689af4e05SJiri Olsa "aggregate counts per processor socket", AGGR_SOCKET), 151789af4e05SJiri Olsa OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode, 151889af4e05SJiri Olsa "aggregate counts per physical processor core", AGGR_CORE), 151989af4e05SJiri Olsa OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode, 152089af4e05SJiri Olsa "disable CPU count aggregation", AGGR_NONE), 1521ba6039b6SJiri Olsa OPT_END() 1522ba6039b6SJiri Olsa }; 1523ba6039b6SJiri Olsa struct stat st; 1524ba6039b6SJiri Olsa int ret; 1525ba6039b6SJiri Olsa 15268a59f3ccSJiri Olsa argc = parse_options(argc, argv, options, stat_report_usage, 0); 1527ba6039b6SJiri Olsa 1528ba6039b6SJiri Olsa if (!input_name || !strlen(input_name)) { 1529ba6039b6SJiri Olsa if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) 1530ba6039b6SJiri Olsa input_name = "-"; 1531ba6039b6SJiri Olsa else 1532ba6039b6SJiri Olsa input_name = "perf.data"; 1533ba6039b6SJiri Olsa } 1534ba6039b6SJiri Olsa 1535eae8ad80SJiri Olsa perf_stat.data.file.path = input_name; 15368ceb41d7SJiri Olsa perf_stat.data.mode = PERF_DATA_MODE_READ; 1537ba6039b6SJiri Olsa 15388ceb41d7SJiri Olsa session = perf_session__new(&perf_stat.data, false, &perf_stat.tool); 1539ba6039b6SJiri Olsa if (session == NULL) 1540ba6039b6SJiri Olsa return -1; 1541ba6039b6SJiri Olsa 1542ba6039b6SJiri Olsa perf_stat.session = session; 1543ba6039b6SJiri Olsa stat_config.output = stderr; 1544ba6039b6SJiri Olsa evsel_list = session->evlist; 1545ba6039b6SJiri Olsa 1546ba6039b6SJiri Olsa ret = perf_session__process_events(session); 1547ba6039b6SJiri Olsa if (ret) 1548ba6039b6SJiri Olsa return ret; 1549ba6039b6SJiri Olsa 1550ba6039b6SJiri Olsa perf_session__delete(session); 1551ba6039b6SJiri Olsa return 0; 1552ba6039b6SJiri Olsa } 1553ba6039b6SJiri Olsa 1554e3ba76deSJiri Olsa static void setup_system_wide(int forks) 1555e3ba76deSJiri Olsa { 1556e3ba76deSJiri Olsa /* 1557e3ba76deSJiri Olsa * Make system wide (-a) the default target if 1558e3ba76deSJiri Olsa * no target was specified and one of following 1559e3ba76deSJiri Olsa * conditions is met: 1560e3ba76deSJiri Olsa * 1561e3ba76deSJiri Olsa * - there's no workload specified 1562e3ba76deSJiri Olsa * - there is workload specified but all requested 1563e3ba76deSJiri Olsa * events are system wide events 1564e3ba76deSJiri Olsa */ 1565e3ba76deSJiri Olsa if (!target__none(&target)) 1566e3ba76deSJiri Olsa return; 1567e3ba76deSJiri Olsa 1568e3ba76deSJiri Olsa if (!forks) 1569e3ba76deSJiri Olsa target.system_wide = true; 1570e3ba76deSJiri Olsa else { 1571e3ba76deSJiri Olsa struct perf_evsel *counter; 1572e3ba76deSJiri Olsa 1573e3ba76deSJiri Olsa evlist__for_each_entry(evsel_list, counter) { 1574e3ba76deSJiri Olsa if (!counter->system_wide) 1575e3ba76deSJiri Olsa return; 1576e3ba76deSJiri Olsa } 1577e3ba76deSJiri Olsa 1578e3ba76deSJiri Olsa if (evsel_list->nr_entries) 1579e3ba76deSJiri Olsa target.system_wide = true; 1580e3ba76deSJiri Olsa } 1581e3ba76deSJiri Olsa } 1582e3ba76deSJiri Olsa 1583b0ad8ea6SArnaldo Carvalho de Melo int cmd_stat(int argc, const char **argv) 158486470930SIngo Molnar { 1585b070a547SArnaldo Carvalho de Melo const char * const stat_usage[] = { 1586b070a547SArnaldo Carvalho de Melo "perf stat [<options>] [<command>]", 1587b070a547SArnaldo Carvalho de Melo NULL 1588b070a547SArnaldo Carvalho de Melo }; 1589cc03c542SNamhyung Kim int status = -EINVAL, run_idx; 15904aa9015fSStephane Eranian const char *mode; 15915821522eSJiri Olsa FILE *output = stderr; 1592f1f8ad52Syuzhoujian unsigned int interval, timeout; 1593ba6039b6SJiri Olsa const char * const stat_subcommands[] = { "record", "report" }; 159442202dd5SIngo Molnar 15955af52b51SStephane Eranian setlocale(LC_ALL, ""); 15965af52b51SStephane Eranian 1597334fe7a3SNamhyung Kim evsel_list = perf_evlist__new(); 1598361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 1599361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 1600361c99a6SArnaldo Carvalho de Melo 16011669e509SWang Nan parse_events__shrink_config_terms(); 16024979d0c7SJiri Olsa argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands, 16034979d0c7SJiri Olsa (const char **) stat_usage, 1604a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 160537932c18SAndi Kleen perf_stat__collect_metric_expr(evsel_list); 1606fb4605baSAndi Kleen perf_stat__init_shadow_stats(); 1607d7470b6aSStephane Eranian 1608fa7070a3SJiri Olsa if (stat_config.csv_sep) { 1609fa7070a3SJiri Olsa stat_config.csv_output = true; 1610fa7070a3SJiri Olsa if (!strcmp(stat_config.csv_sep, "\\t")) 1611fa7070a3SJiri Olsa stat_config.csv_sep = "\t"; 16126edb78a2SJiri Olsa } else 1613fa7070a3SJiri Olsa stat_config.csv_sep = DEFAULT_SEPARATOR; 16146edb78a2SJiri Olsa 16154979d0c7SJiri Olsa if (argc && !strncmp(argv[0], "rec", 3)) { 16164979d0c7SJiri Olsa argc = __cmd_record(argc, argv); 16174979d0c7SJiri Olsa if (argc < 0) 16184979d0c7SJiri Olsa return -1; 1619ba6039b6SJiri Olsa } else if (argc && !strncmp(argv[0], "rep", 3)) 1620ba6039b6SJiri Olsa return __cmd_report(argc, argv); 16214979d0c7SJiri Olsa 1622ec0d3d1fSJiri Olsa interval = stat_config.interval; 1623f1f8ad52Syuzhoujian timeout = stat_config.timeout; 1624ec0d3d1fSJiri Olsa 16254979d0c7SJiri Olsa /* 16264979d0c7SJiri Olsa * For record command the -o is already taken care of. 16274979d0c7SJiri Olsa */ 16284979d0c7SJiri Olsa if (!STAT_RECORD && output_name && strcmp(output_name, "-")) 16294aa9015fSStephane Eranian output = NULL; 16304aa9015fSStephane Eranian 163156f3bae7SJim Cromie if (output_name && output_fd) { 163256f3bae7SJim Cromie fprintf(stderr, "cannot use both --output and --log-fd\n"); 1633e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "o", 1); 1634e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "log-fd", 0); 1635cc03c542SNamhyung Kim goto out; 163656f3bae7SJim Cromie } 1637fc3e4d07SStephane Eranian 16380ce5aa02SJiri Olsa if (stat_config.metric_only && stat_config.aggr_mode == AGGR_THREAD) { 163954b50916SAndi Kleen fprintf(stderr, "--metric-only is not supported with --per-thread\n"); 164054b50916SAndi Kleen goto out; 164154b50916SAndi Kleen } 164254b50916SAndi Kleen 1643d97ae04bSJiri Olsa if (stat_config.metric_only && stat_config.run_count > 1) { 164454b50916SAndi Kleen fprintf(stderr, "--metric-only is not supported with -r\n"); 164554b50916SAndi Kleen goto out; 164654b50916SAndi Kleen } 164754b50916SAndi Kleen 164854ac0b1bSJiri Olsa if (stat_config.walltime_run_table && stat_config.run_count <= 1) { 1649e55c14afSJiri Olsa fprintf(stderr, "--table is only supported with -r\n"); 1650e55c14afSJiri Olsa parse_options_usage(stat_usage, stat_options, "r", 1); 1651e55c14afSJiri Olsa parse_options_usage(NULL, stat_options, "table", 0); 1652e55c14afSJiri Olsa goto out; 1653e55c14afSJiri Olsa } 1654e55c14afSJiri Olsa 1655fc3e4d07SStephane Eranian if (output_fd < 0) { 1656fc3e4d07SStephane Eranian fprintf(stderr, "argument to --log-fd must be a > 0\n"); 1657e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "log-fd", 0); 1658cc03c542SNamhyung Kim goto out; 1659fc3e4d07SStephane Eranian } 1660fc3e4d07SStephane Eranian 16614aa9015fSStephane Eranian if (!output) { 16624aa9015fSStephane Eranian struct timespec tm; 16634aa9015fSStephane Eranian mode = append_file ? "a" : "w"; 16644aa9015fSStephane Eranian 16654aa9015fSStephane Eranian output = fopen(output_name, mode); 16664aa9015fSStephane Eranian if (!output) { 16674aa9015fSStephane Eranian perror("failed to create output file"); 1668fceda7feSDavid Ahern return -1; 16694aa9015fSStephane Eranian } 16704aa9015fSStephane Eranian clock_gettime(CLOCK_REALTIME, &tm); 16714aa9015fSStephane Eranian fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 1672fc3e4d07SStephane Eranian } else if (output_fd > 0) { 167356f3bae7SJim Cromie mode = append_file ? "a" : "w"; 167456f3bae7SJim Cromie output = fdopen(output_fd, mode); 167556f3bae7SJim Cromie if (!output) { 167656f3bae7SJim Cromie perror("Failed opening logfd"); 167756f3bae7SJim Cromie return -errno; 167856f3bae7SJim Cromie } 16794aa9015fSStephane Eranian } 16804aa9015fSStephane Eranian 16815821522eSJiri Olsa stat_config.output = output; 16825821522eSJiri Olsa 1683d7470b6aSStephane Eranian /* 1684d7470b6aSStephane Eranian * let the spreadsheet do the pretty-printing 1685d7470b6aSStephane Eranian */ 1686fa7070a3SJiri Olsa if (stat_config.csv_output) { 168761a9f324SJim Cromie /* User explicitly passed -B? */ 1688d7470b6aSStephane Eranian if (big_num_opt == 1) { 1689d7470b6aSStephane Eranian fprintf(stderr, "-B option not supported with -x\n"); 1690e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "B", 1); 1691e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "x", 1); 1692cc03c542SNamhyung Kim goto out; 1693d7470b6aSStephane Eranian } else /* Nope, so disable big number formatting */ 169434ff0866SJiri Olsa stat_config.big_num = false; 1695d7470b6aSStephane Eranian } else if (big_num_opt == 0) /* User passed --no-big-num */ 169634ff0866SJiri Olsa stat_config.big_num = false; 1697d7470b6aSStephane Eranian 1698e3ba76deSJiri Olsa setup_system_wide(argc); 1699ac3063bdSDavid Ahern 17000ce2da14SJiri Olsa /* 17010ce2da14SJiri Olsa * Display user/system times only for single 17020ce2da14SJiri Olsa * run and when there's specified tracee. 17030ce2da14SJiri Olsa */ 1704d97ae04bSJiri Olsa if ((stat_config.run_count == 1) && target__none(&target)) 17058897a891SJiri Olsa stat_config.ru_display = true; 17060ce2da14SJiri Olsa 1707d97ae04bSJiri Olsa if (stat_config.run_count < 0) { 1708cc03c542SNamhyung Kim pr_err("Run count must be a positive number\n"); 1709e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "r", 1); 1710cc03c542SNamhyung Kim goto out; 1711d97ae04bSJiri Olsa } else if (stat_config.run_count == 0) { 1712a7e191c3SFrederik Deweerdt forever = true; 1713d97ae04bSJiri Olsa stat_config.run_count = 1; 1714a7e191c3SFrederik Deweerdt } 171586470930SIngo Molnar 171654ac0b1bSJiri Olsa if (stat_config.walltime_run_table) { 171754ac0b1bSJiri Olsa stat_config.walltime_run = zalloc(stat_config.run_count * sizeof(stat_config.walltime_run[0])); 171854ac0b1bSJiri Olsa if (!stat_config.walltime_run) { 1719e55c14afSJiri Olsa pr_err("failed to setup -r option"); 1720e55c14afSJiri Olsa goto out; 1721e55c14afSJiri Olsa } 1722e55c14afSJiri Olsa } 1723e55c14afSJiri Olsa 17241d9f8d1bSJin Yao if ((stat_config.aggr_mode == AGGR_THREAD) && 17251d9f8d1bSJin Yao !target__has_task(&target)) { 17261d9f8d1bSJin Yao if (!target.system_wide || target.cpu_list) { 17271d9f8d1bSJin Yao fprintf(stderr, "The --per-thread option is only " 17281d9f8d1bSJin Yao "available when monitoring via -p -t -a " 17291d9f8d1bSJin Yao "options or only --per-thread.\n"); 1730e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "p", 1); 1731e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "t", 1); 173232b8af82SJiri Olsa goto out; 173332b8af82SJiri Olsa } 17341d9f8d1bSJin Yao } 173532b8af82SJiri Olsa 173632b8af82SJiri Olsa /* 173732b8af82SJiri Olsa * no_aggr, cgroup are for system-wide only 173832b8af82SJiri Olsa * --per-thread is aggregated per thread, we dont mix it with cpu mode 173932b8af82SJiri Olsa */ 1740421a50f3SJiri Olsa if (((stat_config.aggr_mode != AGGR_GLOBAL && 1741421a50f3SJiri Olsa stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) && 1742602ad878SArnaldo Carvalho de Melo !target__has_cpu(&target)) { 1743023695d9SStephane Eranian fprintf(stderr, "both cgroup and no-aggregation " 1744023695d9SStephane Eranian "modes only available in system-wide mode\n"); 1745023695d9SStephane Eranian 1746e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "G", 1); 1747e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "A", 1); 1748e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "a", 1); 1749cc03c542SNamhyung Kim goto out; 1750d7e7a451SStephane Eranian } 1751d7e7a451SStephane Eranian 17522cba3ffbSIngo Molnar if (add_default_attributes()) 1753c6264defSIngo Molnar goto out; 175486470930SIngo Molnar 1755602ad878SArnaldo Carvalho de Melo target__validate(&target); 17565c98d466SArnaldo Carvalho de Melo 17571d9f8d1bSJin Yao if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide)) 17581d9f8d1bSJin Yao target.per_thread = true; 17591d9f8d1bSJin Yao 176077a6f014SNamhyung Kim if (perf_evlist__create_maps(evsel_list, &target) < 0) { 1761602ad878SArnaldo Carvalho de Melo if (target__has_task(&target)) { 17625c98d466SArnaldo Carvalho de Melo pr_err("Problems finding threads of monitor\n"); 1763e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "p", 1); 1764e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "t", 1); 1765602ad878SArnaldo Carvalho de Melo } else if (target__has_cpu(&target)) { 176660d567e2SArnaldo Carvalho de Melo perror("failed to parse CPUs map"); 1767e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "C", 1); 1768e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "a", 1); 1769cc03c542SNamhyung Kim } 1770cc03c542SNamhyung Kim goto out; 177160d567e2SArnaldo Carvalho de Melo } 177232b8af82SJiri Olsa 177332b8af82SJiri Olsa /* 177432b8af82SJiri Olsa * Initialize thread_map with comm names, 177532b8af82SJiri Olsa * so we could print it out on output. 177632b8af82SJiri Olsa */ 177756739444SJin Yao if (stat_config.aggr_mode == AGGR_THREAD) { 177832b8af82SJiri Olsa thread_map__read_comms(evsel_list->threads); 177956739444SJin Yao if (target.system_wide) { 178056739444SJin Yao if (runtime_stat_new(&stat_config, 178156739444SJin Yao thread_map__nr(evsel_list->threads))) { 178256739444SJin Yao goto out; 178356739444SJin Yao } 178456739444SJin Yao } 178556739444SJin Yao } 178632b8af82SJiri Olsa 1787db06a269Syuzhoujian if (stat_config.times && interval) 1788db06a269Syuzhoujian interval_count = true; 1789db06a269Syuzhoujian else if (stat_config.times && !interval) { 1790db06a269Syuzhoujian pr_err("interval-count option should be used together with " 1791db06a269Syuzhoujian "interval-print.\n"); 1792db06a269Syuzhoujian parse_options_usage(stat_usage, stat_options, "interval-count", 0); 1793db06a269Syuzhoujian parse_options_usage(stat_usage, stat_options, "I", 1); 1794db06a269Syuzhoujian goto out; 1795db06a269Syuzhoujian } 1796c45c6ea2SStephane Eranian 1797f1f8ad52Syuzhoujian if (timeout && timeout < 100) { 1798f1f8ad52Syuzhoujian if (timeout < 10) { 1799f1f8ad52Syuzhoujian pr_err("timeout must be >= 10ms.\n"); 1800f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "timeout", 0); 1801f1f8ad52Syuzhoujian goto out; 1802f1f8ad52Syuzhoujian } else 1803f1f8ad52Syuzhoujian pr_warning("timeout < 100ms. " 1804f1f8ad52Syuzhoujian "The overhead percentage could be high in some cases. " 1805f1f8ad52Syuzhoujian "Please proceed with caution.\n"); 1806f1f8ad52Syuzhoujian } 1807f1f8ad52Syuzhoujian if (timeout && interval) { 1808f1f8ad52Syuzhoujian pr_err("timeout option is not supported with interval-print.\n"); 1809f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "timeout", 0); 1810f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "I", 1); 1811f1f8ad52Syuzhoujian goto out; 1812f1f8ad52Syuzhoujian } 1813f1f8ad52Syuzhoujian 1814d134ffb9SArnaldo Carvalho de Melo if (perf_evlist__alloc_stats(evsel_list, interval)) 181503ad9747SArnaldo Carvalho de Melo goto out; 1816d6d901c2SZhang, Yanmin 181786ee6e18SStephane Eranian if (perf_stat_init_aggr_mode()) 181803ad9747SArnaldo Carvalho de Melo goto out; 181986ee6e18SStephane Eranian 182086470930SIngo Molnar /* 18217d9ad16aSJiri Olsa * Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless 18227d9ad16aSJiri Olsa * while avoiding that older tools show confusing messages. 18237d9ad16aSJiri Olsa * 18247d9ad16aSJiri Olsa * However for pipe sessions we need to keep it zero, 18257d9ad16aSJiri Olsa * because script's perf_evsel__check_attr is triggered 18267d9ad16aSJiri Olsa * by attr->sample_type != 0, and we can't run it on 18277d9ad16aSJiri Olsa * stat sessions. 18287d9ad16aSJiri Olsa */ 18297d9ad16aSJiri Olsa stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe); 18307d9ad16aSJiri Olsa 18317d9ad16aSJiri Olsa /* 183286470930SIngo Molnar * We dont want to block the signals - that would cause 183386470930SIngo Molnar * child tasks to inherit that and Ctrl-C would not work. 183486470930SIngo Molnar * What we want is for Ctrl-C to work in the exec()-ed 183586470930SIngo Molnar * task, but being ignored by perf stat itself: 183686470930SIngo Molnar */ 1837f7b7c26eSPeter Zijlstra atexit(sig_atexit); 1838a7e191c3SFrederik Deweerdt if (!forever) 183986470930SIngo Molnar signal(SIGINT, skip_signal); 184013370a9bSStephane Eranian signal(SIGCHLD, skip_signal); 184186470930SIngo Molnar signal(SIGALRM, skip_signal); 184286470930SIngo Molnar signal(SIGABRT, skip_signal); 184386470930SIngo Molnar 184442202dd5SIngo Molnar status = 0; 1845d97ae04bSJiri Olsa for (run_idx = 0; forever || run_idx < stat_config.run_count; run_idx++) { 1846d97ae04bSJiri Olsa if (stat_config.run_count != 1 && verbose > 0) 18474aa9015fSStephane Eranian fprintf(output, "[ perf stat: executing run #%d ... ]\n", 18484aa9015fSStephane Eranian run_idx + 1); 1849f9cef0a9SIngo Molnar 1850e55c14afSJiri Olsa status = run_perf_stat(argc, argv, run_idx); 1851a7e191c3SFrederik Deweerdt if (forever && status != -1) { 1852d4f63a47SJiri Olsa print_counters(NULL, argc, argv); 1853254ecbc7SJiri Olsa perf_stat__reset_stats(); 1854a7e191c3SFrederik Deweerdt } 185542202dd5SIngo Molnar } 185642202dd5SIngo Molnar 1857a7e191c3SFrederik Deweerdt if (!forever && status != -1 && !interval) 1858d4f63a47SJiri Olsa print_counters(NULL, argc, argv); 1859d134ffb9SArnaldo Carvalho de Melo 18604979d0c7SJiri Olsa if (STAT_RECORD) { 18614979d0c7SJiri Olsa /* 18624979d0c7SJiri Olsa * We synthesize the kernel mmap record just so that older tools 18634979d0c7SJiri Olsa * don't emit warnings about not being able to resolve symbols 18644979d0c7SJiri Olsa * due to /proc/sys/kernel/kptr_restrict settings and instear provide 18654979d0c7SJiri Olsa * a saner message about no samples being in the perf.data file. 18664979d0c7SJiri Olsa * 18674979d0c7SJiri Olsa * This also serves to suppress a warning about f_header.data.size == 0 18688b99b1a4SJiri Olsa * in header.c at the moment 'perf stat record' gets introduced, which 18698b99b1a4SJiri Olsa * is not really needed once we start adding the stat specific PERF_RECORD_ 18708b99b1a4SJiri Olsa * records, but the need to suppress the kptr_restrict messages in older 18718b99b1a4SJiri Olsa * tools remain -acme 18724979d0c7SJiri Olsa */ 18738ceb41d7SJiri Olsa int fd = perf_data__fd(&perf_stat.data); 18744979d0c7SJiri Olsa int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat, 18754979d0c7SJiri Olsa process_synthesized_event, 18764979d0c7SJiri Olsa &perf_stat.session->machines.host); 18774979d0c7SJiri Olsa if (err) { 18784979d0c7SJiri Olsa pr_warning("Couldn't synthesize the kernel mmap record, harmless, " 18794979d0c7SJiri Olsa "older tools may produce warnings about this file\n."); 18804979d0c7SJiri Olsa } 18814979d0c7SJiri Olsa 18827aad0c32SJiri Olsa if (!interval) { 18837aad0c32SJiri Olsa if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL)) 18847aad0c32SJiri Olsa pr_err("failed to write stat round event\n"); 18857aad0c32SJiri Olsa } 18867aad0c32SJiri Olsa 18878ceb41d7SJiri Olsa if (!perf_stat.data.is_pipe) { 18884979d0c7SJiri Olsa perf_stat.session->header.data_size += perf_stat.bytes_written; 18894979d0c7SJiri Olsa perf_session__write_header(perf_stat.session, evsel_list, fd, true); 1890664c98d4SJiri Olsa } 18914979d0c7SJiri Olsa 18924979d0c7SJiri Olsa perf_session__delete(perf_stat.session); 18934979d0c7SJiri Olsa } 18944979d0c7SJiri Olsa 1895544c2ae7SMasami Hiramatsu perf_stat__exit_aggr_mode(); 1896d134ffb9SArnaldo Carvalho de Melo perf_evlist__free_stats(evsel_list); 18970015e2e1SArnaldo Carvalho de Melo out: 189854ac0b1bSJiri Olsa free(stat_config.walltime_run); 1899e55c14afSJiri Olsa 1900daefd0bcSKan Liang if (smi_cost && smi_reset) 1901daefd0bcSKan Liang sysfs__write_int(FREEZE_ON_SMI_PATH, 0); 1902daefd0bcSKan Liang 19030015e2e1SArnaldo Carvalho de Melo perf_evlist__delete(evsel_list); 190456739444SJin Yao 190556739444SJin Yao runtime_stat_delete(&stat_config); 190656739444SJin Yao 190742202dd5SIngo Molnar return status; 190886470930SIngo Molnar } 1909