191007045SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 286470930SIngo Molnar /* 386470930SIngo Molnar * builtin-stat.c 486470930SIngo Molnar * 586470930SIngo Molnar * Builtin stat command: Give a precise performance counters summary 686470930SIngo Molnar * overview about any workload, CPU or specific PID. 786470930SIngo Molnar * 886470930SIngo Molnar * Sample output: 986470930SIngo Molnar 102cba3ffbSIngo Molnar $ perf stat ./hackbench 10 1186470930SIngo Molnar 122cba3ffbSIngo Molnar Time: 0.118 1386470930SIngo Molnar 142cba3ffbSIngo Molnar Performance counter stats for './hackbench 10': 1586470930SIngo Molnar 162cba3ffbSIngo Molnar 1708.761321 task-clock # 11.037 CPUs utilized 172cba3ffbSIngo Molnar 41,190 context-switches # 0.024 M/sec 182cba3ffbSIngo Molnar 6,735 CPU-migrations # 0.004 M/sec 192cba3ffbSIngo Molnar 17,318 page-faults # 0.010 M/sec 202cba3ffbSIngo Molnar 5,205,202,243 cycles # 3.046 GHz 212cba3ffbSIngo Molnar 3,856,436,920 stalled-cycles-frontend # 74.09% frontend cycles idle 222cba3ffbSIngo Molnar 1,600,790,871 stalled-cycles-backend # 30.75% backend cycles idle 232cba3ffbSIngo Molnar 2,603,501,247 instructions # 0.50 insns per cycle 242cba3ffbSIngo Molnar # 1.48 stalled cycles per insn 252cba3ffbSIngo Molnar 484,357,498 branches # 283.455 M/sec 262cba3ffbSIngo Molnar 6,388,934 branch-misses # 1.32% of all branches 272cba3ffbSIngo Molnar 282cba3ffbSIngo Molnar 0.154822978 seconds time elapsed 2986470930SIngo Molnar 3086470930SIngo Molnar * 312cba3ffbSIngo Molnar * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 3286470930SIngo Molnar * 3386470930SIngo Molnar * Improvements and fixes by: 3486470930SIngo Molnar * 3586470930SIngo Molnar * Arjan van de Ven <arjan@linux.intel.com> 3686470930SIngo Molnar * Yanmin Zhang <yanmin.zhang@intel.com> 3786470930SIngo Molnar * Wu Fengguang <fengguang.wu@intel.com> 3886470930SIngo Molnar * Mike Galbraith <efault@gmx.de> 3986470930SIngo Molnar * Paul Mackerras <paulus@samba.org> 406e750a8fSJaswinder Singh Rajput * Jaswinder Singh Rajput <jaswinder@kernel.org> 4186470930SIngo Molnar */ 4286470930SIngo Molnar 4386470930SIngo Molnar #include "builtin.h" 44c1a604dfSArnaldo Carvalho de Melo #include "perf.h" 45f14d5707SArnaldo Carvalho de Melo #include "util/cgroup.h" 464b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 4786470930SIngo Molnar #include "util/parse-events.h" 484cabc3d1SAndi Kleen #include "util/pmu.h" 498f28827aSFrederic Weisbecker #include "util/event.h" 50361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h" 51660e533eSJin Yao #include "util/evlist-hybrid.h" 5269aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h" 538f28827aSFrederic Weisbecker #include "util/debug.h" 54a5d243d0SIngo Molnar #include "util/color.h" 550007eceaSXiao Guangrong #include "util/stat.h" 5660666c63SLiming Wang #include "util/header.h" 57a12b51c4SPaul Mackerras #include "util/cpumap.h" 58fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h" 59d809560bSJiri Olsa #include "util/counts.h" 60687986bbSKan Liang #include "util/topdown.h" 614979d0c7SJiri Olsa #include "util/session.h" 62ba6039b6SJiri Olsa #include "util/tool.h" 63a067558eSArnaldo Carvalho de Melo #include "util/string2.h" 64b18f3e36SAndi Kleen #include "util/metricgroup.h" 65ea49e01cSArnaldo Carvalho de Melo #include "util/synthetic-events.h" 66aeb00b1aSArnaldo Carvalho de Melo #include "util/target.h" 67f3711020SArnaldo Carvalho de Melo #include "util/time-utils.h" 689660e08eSJiri Olsa #include "util/top.h" 694804e011SAndi Kleen #include "util/affinity.h" 7070943490SStephane Eranian #include "util/pfm.h" 71fa853c4bSSong Liu #include "util/bpf_counter.h" 72f07952b1SAlexander Antonov #include "util/iostat.h" 7312279429SJin Yao #include "util/pmu-hybrid.h" 74ba6039b6SJiri Olsa #include "asm/bug.h" 7586470930SIngo Molnar 76bd48c63eSArnaldo Carvalho de Melo #include <linux/time64.h> 777f7c536fSArnaldo Carvalho de Melo #include <linux/zalloc.h> 7844b1e60aSAndi Kleen #include <api/fs/fs.h> 79a43783aeSArnaldo Carvalho de Melo #include <errno.h> 809607ad3aSArnaldo Carvalho de Melo #include <signal.h> 811f16c575SPeter Zijlstra #include <stdlib.h> 8286470930SIngo Molnar #include <sys/prctl.h> 83fd20e811SArnaldo Carvalho de Melo #include <inttypes.h> 845af52b51SStephane Eranian #include <locale.h> 85e3b03b6cSAndi Kleen #include <math.h> 867a8ef4c4SArnaldo Carvalho de Melo #include <sys/types.h> 877a8ef4c4SArnaldo Carvalho de Melo #include <sys/stat.h> 884208735dSArnaldo Carvalho de Melo #include <sys/wait.h> 897a8ef4c4SArnaldo Carvalho de Melo #include <unistd.h> 900ce2da14SJiri Olsa #include <sys/time.h> 910ce2da14SJiri Olsa #include <sys/resource.h> 926ef81c55SMamatha Inamdar #include <linux/err.h> 9386470930SIngo Molnar 943052ba56SArnaldo Carvalho de Melo #include <linux/ctype.h> 95453fa030SJiri Olsa #include <perf/evlist.h> 963d689ed6SArnaldo Carvalho de Melo 97d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR " " 98daefd0bcSKan Liang #define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi" 99d7470b6aSStephane Eranian 100d4f63a47SJiri Olsa static void print_counters(struct timespec *ts, int argc, const char **argv); 10113370a9bSStephane Eranian 1024cabc3d1SAndi Kleen /* Default events used for perf stat -T */ 103a454742cSJiri Olsa static const char *transaction_attrs = { 104a454742cSJiri Olsa "task-clock," 1054cabc3d1SAndi Kleen "{" 1064cabc3d1SAndi Kleen "instructions," 1074cabc3d1SAndi Kleen "cycles," 1084cabc3d1SAndi Kleen "cpu/cycles-t/," 1094cabc3d1SAndi Kleen "cpu/tx-start/," 1104cabc3d1SAndi Kleen "cpu/el-start/," 1114cabc3d1SAndi Kleen "cpu/cycles-ct/" 1124cabc3d1SAndi Kleen "}" 1134cabc3d1SAndi Kleen }; 1144cabc3d1SAndi Kleen 1154cabc3d1SAndi Kleen /* More limited version when the CPU does not have all events. */ 116a454742cSJiri Olsa static const char * transaction_limited_attrs = { 117a454742cSJiri Olsa "task-clock," 1184cabc3d1SAndi Kleen "{" 1194cabc3d1SAndi Kleen "instructions," 1204cabc3d1SAndi Kleen "cycles," 1214cabc3d1SAndi Kleen "cpu/cycles-t/," 1224cabc3d1SAndi Kleen "cpu/tx-start/" 1234cabc3d1SAndi Kleen "}" 1244cabc3d1SAndi Kleen }; 1254cabc3d1SAndi Kleen 12644b1e60aSAndi Kleen static const char * topdown_attrs[] = { 12744b1e60aSAndi Kleen "topdown-total-slots", 12844b1e60aSAndi Kleen "topdown-slots-retired", 12944b1e60aSAndi Kleen "topdown-recovery-bubbles", 13044b1e60aSAndi Kleen "topdown-fetch-bubbles", 13144b1e60aSAndi Kleen "topdown-slots-issued", 13244b1e60aSAndi Kleen NULL, 13344b1e60aSAndi Kleen }; 13444b1e60aSAndi Kleen 13555c36a9fSAndi Kleen static const char *topdown_metric_attrs[] = { 13655c36a9fSAndi Kleen "slots", 13755c36a9fSAndi Kleen "topdown-retiring", 13855c36a9fSAndi Kleen "topdown-bad-spec", 13955c36a9fSAndi Kleen "topdown-fe-bound", 14055c36a9fSAndi Kleen "topdown-be-bound", 14155c36a9fSAndi Kleen NULL, 14255c36a9fSAndi Kleen }; 14355c36a9fSAndi Kleen 14463e39aa6SKan Liang static const char *topdown_metric_L2_attrs[] = { 14563e39aa6SKan Liang "slots", 14663e39aa6SKan Liang "topdown-retiring", 14763e39aa6SKan Liang "topdown-bad-spec", 14863e39aa6SKan Liang "topdown-fe-bound", 14963e39aa6SKan Liang "topdown-be-bound", 15063e39aa6SKan Liang "topdown-heavy-ops", 15163e39aa6SKan Liang "topdown-br-mispredict", 15263e39aa6SKan Liang "topdown-fetch-lat", 15363e39aa6SKan Liang "topdown-mem-bound", 15463e39aa6SKan Liang NULL, 15563e39aa6SKan Liang }; 15663e39aa6SKan Liang 1575f148e7cSKan Liang #define TOPDOWN_MAX_LEVEL 2 1585f148e7cSKan Liang 159daefd0bcSKan Liang static const char *smi_cost_attrs = { 160daefd0bcSKan Liang "{" 161daefd0bcSKan Liang "msr/aperf/," 162daefd0bcSKan Liang "msr/smi/," 163daefd0bcSKan Liang "cycles" 164daefd0bcSKan Liang "}" 165daefd0bcSKan Liang }; 166daefd0bcSKan Liang 16763503dbaSJiri Olsa static struct evlist *evsel_list; 168112cb561SSong Liu static bool all_counters_use_bpf = true; 169361c99a6SArnaldo Carvalho de Melo 170602ad878SArnaldo Carvalho de Melo static struct target target = { 17177a6f014SNamhyung Kim .uid = UINT_MAX, 17277a6f014SNamhyung Kim }; 17342202dd5SIngo Molnar 174c1a1f5d9SJiri Olsa #define METRIC_ONLY_LEN 20 175c1a1f5d9SJiri Olsa 176d07f0b12SStephane Eranian static volatile pid_t child_pid = -1; 1772cba3ffbSIngo Molnar static int detailed_run = 0; 1784cabc3d1SAndi Kleen static bool transaction_run; 17944b1e60aSAndi Kleen static bool topdown_run = false; 180daefd0bcSKan Liang static bool smi_cost = false; 181daefd0bcSKan Liang static bool smi_reset = false; 182d7470b6aSStephane Eranian static int big_num_opt = -1; 18343bece79SLin Ming static bool group = false; 1841f16c575SPeter Zijlstra static const char *pre_cmd = NULL; 1851f16c575SPeter Zijlstra static const char *post_cmd = NULL; 1861f16c575SPeter Zijlstra static bool sync_run = false; 187a7e191c3SFrederik Deweerdt static bool forever = false; 18844b1e60aSAndi Kleen static bool force_metric_only = false; 18913370a9bSStephane Eranian static struct timespec ref_time; 190e0547311SJiri Olsa static bool append_file; 191db06a269Syuzhoujian static bool interval_count; 192e0547311SJiri Olsa static const char *output_name; 193e0547311SJiri Olsa static int output_fd; 1945af52b51SStephane Eranian 1954979d0c7SJiri Olsa struct perf_stat { 1964979d0c7SJiri Olsa bool record; 1978ceb41d7SJiri Olsa struct perf_data data; 1984979d0c7SJiri Olsa struct perf_session *session; 1994979d0c7SJiri Olsa u64 bytes_written; 200ba6039b6SJiri Olsa struct perf_tool tool; 2011975d36eSJiri Olsa bool maps_allocated; 202f854839bSJiri Olsa struct perf_cpu_map *cpus; 2039749b90eSJiri Olsa struct perf_thread_map *threads; 20489af4e05SJiri Olsa enum aggr_mode aggr_mode; 2054979d0c7SJiri Olsa }; 2064979d0c7SJiri Olsa 2074979d0c7SJiri Olsa static struct perf_stat perf_stat; 2084979d0c7SJiri Olsa #define STAT_RECORD perf_stat.record 2094979d0c7SJiri Olsa 21060666c63SLiming Wang static volatile int done = 0; 21160666c63SLiming Wang 212421a50f3SJiri Olsa static struct perf_stat_config stat_config = { 213421a50f3SJiri Olsa .aggr_mode = AGGR_GLOBAL, 214711a572eSJiri Olsa .scale = true, 215df4f7b4dSJiri Olsa .unit_width = 4, /* strlen("unit") */ 216d97ae04bSJiri Olsa .run_count = 1, 217ee1760e2SJiri Olsa .metric_only_len = METRIC_ONLY_LEN, 21826893a60SJiri Olsa .walltime_nsecs_stats = &walltime_nsecs_stats, 21934ff0866SJiri Olsa .big_num = true, 22027e9769aSAlexey Budankov .ctl_fd = -1, 221f07952b1SAlexander Antonov .ctl_fd_ack = -1, 222f07952b1SAlexander Antonov .iostat_run = false, 223421a50f3SJiri Olsa }; 224421a50f3SJiri Olsa 225a9a17902SJiri Olsa static bool cpus_map_matched(struct evsel *a, struct evsel *b) 226a9a17902SJiri Olsa { 227a9a17902SJiri Olsa if (!a->core.cpus && !b->core.cpus) 228a9a17902SJiri Olsa return true; 229a9a17902SJiri Olsa 230a9a17902SJiri Olsa if (!a->core.cpus || !b->core.cpus) 231a9a17902SJiri Olsa return false; 232a9a17902SJiri Olsa 233a9a17902SJiri Olsa if (a->core.cpus->nr != b->core.cpus->nr) 234a9a17902SJiri Olsa return false; 235a9a17902SJiri Olsa 236a9a17902SJiri Olsa for (int i = 0; i < a->core.cpus->nr; i++) { 237a9a17902SJiri Olsa if (a->core.cpus->map[i] != b->core.cpus->map[i]) 238a9a17902SJiri Olsa return false; 239a9a17902SJiri Olsa } 240a9a17902SJiri Olsa 241a9a17902SJiri Olsa return true; 242a9a17902SJiri Olsa } 243a9a17902SJiri Olsa 244a9a17902SJiri Olsa static void evlist__check_cpu_maps(struct evlist *evlist) 245a9a17902SJiri Olsa { 246a9a17902SJiri Olsa struct evsel *evsel, *pos, *leader; 247a9a17902SJiri Olsa char buf[1024]; 248a9a17902SJiri Olsa 249660e533eSJin Yao if (evlist__has_hybrid(evlist)) 250660e533eSJin Yao evlist__warn_hybrid_group(evlist); 251660e533eSJin Yao 252a9a17902SJiri Olsa evlist__for_each_entry(evlist, evsel) { 253fba7c866SJiri Olsa leader = evsel__leader(evsel); 254a9a17902SJiri Olsa 255a9a17902SJiri Olsa /* Check that leader matches cpus with each member. */ 256a9a17902SJiri Olsa if (leader == evsel) 257a9a17902SJiri Olsa continue; 258a9a17902SJiri Olsa if (cpus_map_matched(leader, evsel)) 259a9a17902SJiri Olsa continue; 260a9a17902SJiri Olsa 261a9a17902SJiri Olsa /* If there's mismatch disable the group and warn user. */ 262a9a17902SJiri Olsa WARN_ONCE(1, "WARNING: grouped events cpus do not match, disabling group:\n"); 263a9a17902SJiri Olsa evsel__group_desc(leader, buf, sizeof(buf)); 264a9a17902SJiri Olsa pr_warning(" %s\n", buf); 265a9a17902SJiri Olsa 266a9a17902SJiri Olsa if (verbose) { 267a9a17902SJiri Olsa cpu_map__snprint(leader->core.cpus, buf, sizeof(buf)); 268a9a17902SJiri Olsa pr_warning(" %s: %s\n", leader->name, buf); 269a9a17902SJiri Olsa cpu_map__snprint(evsel->core.cpus, buf, sizeof(buf)); 270a9a17902SJiri Olsa pr_warning(" %s: %s\n", evsel->name, buf); 271a9a17902SJiri Olsa } 272a9a17902SJiri Olsa 273a9a17902SJiri Olsa for_each_group_evsel(pos, leader) { 274fba7c866SJiri Olsa evsel__set_leader(pos, pos); 275a9a17902SJiri Olsa pos->core.nr_members = 0; 276a9a17902SJiri Olsa } 277fba7c866SJiri Olsa evsel->core.leader->nr_members = 0; 278a9a17902SJiri Olsa } 279a9a17902SJiri Olsa } 280a9a17902SJiri Olsa 28113370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a, 28213370a9bSStephane Eranian struct timespec *b) 28313370a9bSStephane Eranian { 28413370a9bSStephane Eranian r->tv_sec = a->tv_sec - b->tv_sec; 28513370a9bSStephane Eranian if (a->tv_nsec < b->tv_nsec) { 286310ebb93SArnaldo Carvalho de Melo r->tv_nsec = a->tv_nsec + NSEC_PER_SEC - b->tv_nsec; 28713370a9bSStephane Eranian r->tv_sec--; 28813370a9bSStephane Eranian } else { 28913370a9bSStephane Eranian r->tv_nsec = a->tv_nsec - b->tv_nsec ; 29013370a9bSStephane Eranian } 29113370a9bSStephane Eranian } 29213370a9bSStephane Eranian 293254ecbc7SJiri Olsa static void perf_stat__reset_stats(void) 294254ecbc7SJiri Olsa { 29556739444SJin Yao int i; 29656739444SJin Yao 29753f5e908SArnaldo Carvalho de Melo evlist__reset_stats(evsel_list); 298f87027b9SJiri Olsa perf_stat__reset_shadow_stats(); 29956739444SJin Yao 30056739444SJin Yao for (i = 0; i < stat_config.stats_num; i++) 30156739444SJin Yao perf_stat__reset_shadow_per_stat(&stat_config.stats[i]); 3021eda3b21SJiri Olsa } 3031eda3b21SJiri Olsa 3048b99b1a4SJiri Olsa static int process_synthesized_event(struct perf_tool *tool __maybe_unused, 3054979d0c7SJiri Olsa union perf_event *event, 3064979d0c7SJiri Olsa struct perf_sample *sample __maybe_unused, 3074979d0c7SJiri Olsa struct machine *machine __maybe_unused) 3084979d0c7SJiri Olsa { 3098ceb41d7SJiri Olsa if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) { 3108b99b1a4SJiri Olsa pr_err("failed to write perf data, error: %m\n"); 3118b99b1a4SJiri Olsa return -1; 3128b99b1a4SJiri Olsa } 3138b99b1a4SJiri Olsa 3148b99b1a4SJiri Olsa perf_stat.bytes_written += event->header.size; 3158b99b1a4SJiri Olsa return 0; 3164979d0c7SJiri Olsa } 3174979d0c7SJiri Olsa 3181975d36eSJiri Olsa static int write_stat_round_event(u64 tm, u64 type) 3197aad0c32SJiri Olsa { 3201975d36eSJiri Olsa return perf_event__synthesize_stat_round(NULL, tm, type, 3217aad0c32SJiri Olsa process_synthesized_event, 3227aad0c32SJiri Olsa NULL); 3237aad0c32SJiri Olsa } 3247aad0c32SJiri Olsa 3257aad0c32SJiri Olsa #define WRITE_STAT_ROUND_EVENT(time, interval) \ 3267aad0c32SJiri Olsa write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval) 3277aad0c32SJiri Olsa 3288cd36f3eSJiri Olsa #define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y) 3295a6ea81bSJiri Olsa 330ddc6999eSArnaldo Carvalho de Melo static int evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread, 3315a6ea81bSJiri Olsa struct perf_counts_values *count) 3325a6ea81bSJiri Olsa { 3335a6ea81bSJiri Olsa struct perf_sample_id *sid = SID(counter, cpu, thread); 3345a6ea81bSJiri Olsa 3355a6ea81bSJiri Olsa return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count, 3365a6ea81bSJiri Olsa process_synthesized_event, NULL); 3375a6ea81bSJiri Olsa } 3385a6ea81bSJiri Olsa 33932dcd021SJiri Olsa static int read_single_counter(struct evsel *counter, int cpu, 340f0fbb114SAndi Kleen int thread, struct timespec *rs) 341f0fbb114SAndi Kleen { 342f0fbb114SAndi Kleen if (counter->tool_event == PERF_TOOL_DURATION_TIME) { 343f0fbb114SAndi Kleen u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL; 344f0fbb114SAndi Kleen struct perf_counts_values *count = 345f0fbb114SAndi Kleen perf_counts(counter->counts, cpu, thread); 346f0fbb114SAndi Kleen count->ena = count->run = val; 347f0fbb114SAndi Kleen count->val = val; 348f0fbb114SAndi Kleen return 0; 349f0fbb114SAndi Kleen } 350ea089692SArnaldo Carvalho de Melo return evsel__read_counter(counter, cpu, thread); 351f0fbb114SAndi Kleen } 352f0fbb114SAndi Kleen 353f5b4a9c3SStephane Eranian /* 354f5b4a9c3SStephane Eranian * Read out the results of a single counter: 355f5b4a9c3SStephane Eranian * do not aggregate counts across CPUs in system-wide mode 356f5b4a9c3SStephane Eranian */ 3574b49ab70SAndi Kleen static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu) 358f5b4a9c3SStephane Eranian { 359a2f354e3SJiri Olsa int nthreads = perf_thread_map__nr(evsel_list->core.threads); 3604b49ab70SAndi Kleen int thread; 361f5b4a9c3SStephane Eranian 3623b4331d9SSuzuki K. Poulose if (!counter->supported) 3633b4331d9SSuzuki K. Poulose return -ENOENT; 3643b4331d9SSuzuki K. Poulose 365648b5af3SJiri Olsa if (counter->core.system_wide) 3669bf1a529SJiri Olsa nthreads = 1; 3679bf1a529SJiri Olsa 3689bf1a529SJiri Olsa for (thread = 0; thread < nthreads; thread++) { 3693b3eb044SJiri Olsa struct perf_counts_values *count; 3703b3eb044SJiri Olsa 3713b3eb044SJiri Olsa count = perf_counts(counter->counts, cpu, thread); 37282bf311eSJiri Olsa 37382bf311eSJiri Olsa /* 37482bf311eSJiri Olsa * The leader's group read loads data into its group members 375ea089692SArnaldo Carvalho de Melo * (via evsel__read_counter()) and sets their count->loaded. 37682bf311eSJiri Olsa */ 377df1d6856SJiri Olsa if (!perf_counts__is_loaded(counter->counts, cpu, thread) && 378f0fbb114SAndi Kleen read_single_counter(counter, cpu, thread, rs)) { 379db49a717SStephane Eranian counter->counts->scaled = -1; 380db49a717SStephane Eranian perf_counts(counter->counts, cpu, thread)->ena = 0; 381db49a717SStephane Eranian perf_counts(counter->counts, cpu, thread)->run = 0; 382c52b12edSArnaldo Carvalho de Melo return -1; 383db49a717SStephane Eranian } 3845a6ea81bSJiri Olsa 385df1d6856SJiri Olsa perf_counts__set_loaded(counter->counts, cpu, thread, false); 38682bf311eSJiri Olsa 3875a6ea81bSJiri Olsa if (STAT_RECORD) { 388ddc6999eSArnaldo Carvalho de Melo if (evsel__write_stat_event(counter, cpu, thread, count)) { 3895a6ea81bSJiri Olsa pr_err("failed to write stat event\n"); 3905a6ea81bSJiri Olsa return -1; 3915a6ea81bSJiri Olsa } 3925a6ea81bSJiri Olsa } 3930b1abbf4SAndi Kleen 3940b1abbf4SAndi Kleen if (verbose > 1) { 3950b1abbf4SAndi Kleen fprintf(stat_config.output, 3960b1abbf4SAndi Kleen "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 3978ab2e96dSArnaldo Carvalho de Melo evsel__name(counter), 3980b1abbf4SAndi Kleen cpu, 3990b1abbf4SAndi Kleen count->val, count->ena, count->run); 4000b1abbf4SAndi Kleen } 401f5b4a9c3SStephane Eranian } 402c52b12edSArnaldo Carvalho de Melo 403c52b12edSArnaldo Carvalho de Melo return 0; 40486470930SIngo Molnar } 40586470930SIngo Molnar 406c7e5b328SJin Yao static int read_affinity_counters(struct timespec *rs) 407106a94a0SJiri Olsa { 40832dcd021SJiri Olsa struct evsel *counter; 4094b49ab70SAndi Kleen struct affinity affinity; 4104b49ab70SAndi Kleen int i, ncpus, cpu; 4114b49ab70SAndi Kleen 412112cb561SSong Liu if (all_counters_use_bpf) 413112cb561SSong Liu return 0; 414112cb561SSong Liu 4154b49ab70SAndi Kleen if (affinity__setup(&affinity) < 0) 416c7e5b328SJin Yao return -1; 4174b49ab70SAndi Kleen 4184b49ab70SAndi Kleen ncpus = perf_cpu_map__nr(evsel_list->core.all_cpus); 4194b49ab70SAndi Kleen if (!target__has_cpu(&target) || target__has_per_thread(&target)) 4204b49ab70SAndi Kleen ncpus = 1; 4214b49ab70SAndi Kleen evlist__for_each_cpu(evsel_list, i, cpu) { 4224b49ab70SAndi Kleen if (i >= ncpus) 4234b49ab70SAndi Kleen break; 4244b49ab70SAndi Kleen affinity__set(&affinity, cpu); 425106a94a0SJiri Olsa 426e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evsel_list, counter) { 4274b49ab70SAndi Kleen if (evsel__cpu_iter_skip(counter, cpu)) 4284b49ab70SAndi Kleen continue; 429112cb561SSong Liu if (evsel__is_bpf(counter)) 430112cb561SSong Liu continue; 4314b49ab70SAndi Kleen if (!counter->err) { 4324b49ab70SAndi Kleen counter->err = read_counter_cpu(counter, rs, 4334b49ab70SAndi Kleen counter->cpu_iter - 1); 4344b49ab70SAndi Kleen } 4354b49ab70SAndi Kleen } 4364b49ab70SAndi Kleen } 4374b49ab70SAndi Kleen affinity__cleanup(&affinity); 438c7e5b328SJin Yao return 0; 439c7e5b328SJin Yao } 440c7e5b328SJin Yao 441fa853c4bSSong Liu static int read_bpf_map_counters(void) 442fa853c4bSSong Liu { 443fa853c4bSSong Liu struct evsel *counter; 444fa853c4bSSong Liu int err; 445fa853c4bSSong Liu 446fa853c4bSSong Liu evlist__for_each_entry(evsel_list, counter) { 447112cb561SSong Liu if (!evsel__is_bpf(counter)) 448112cb561SSong Liu continue; 449112cb561SSong Liu 450fa853c4bSSong Liu err = bpf_counter__read(counter); 451fa853c4bSSong Liu if (err) 452fa853c4bSSong Liu return err; 453fa853c4bSSong Liu } 454fa853c4bSSong Liu return 0; 455fa853c4bSSong Liu } 456fa853c4bSSong Liu 457c7e5b328SJin Yao static void read_counters(struct timespec *rs) 458c7e5b328SJin Yao { 459c7e5b328SJin Yao struct evsel *counter; 460c7e5b328SJin Yao 461fa853c4bSSong Liu if (!stat_config.stop_read_counter) { 462112cb561SSong Liu if (read_bpf_map_counters() || 463112cb561SSong Liu read_affinity_counters(rs)) 464c7e5b328SJin Yao return; 465fa853c4bSSong Liu } 4663b3eb044SJiri Olsa 4674b49ab70SAndi Kleen evlist__for_each_entry(evsel_list, counter) { 4684b49ab70SAndi Kleen if (counter->err) 4694b49ab70SAndi Kleen pr_debug("failed to read counter %s\n", counter->name); 4704b49ab70SAndi Kleen if (counter->err == 0 && perf_stat_process_counter(&stat_config, counter)) 4713b3eb044SJiri Olsa pr_warning("failed to process counter %s\n", counter->name); 4724b49ab70SAndi Kleen counter->err = 0; 473106a94a0SJiri Olsa } 474106a94a0SJiri Olsa } 475106a94a0SJiri Olsa 47672f02a94SJin Yao static int runtime_stat_new(struct perf_stat_config *config, int nthreads) 47772f02a94SJin Yao { 47872f02a94SJin Yao int i; 47972f02a94SJin Yao 48072f02a94SJin Yao config->stats = calloc(nthreads, sizeof(struct runtime_stat)); 48172f02a94SJin Yao if (!config->stats) 48272f02a94SJin Yao return -1; 48372f02a94SJin Yao 48472f02a94SJin Yao config->stats_num = nthreads; 48572f02a94SJin Yao 48672f02a94SJin Yao for (i = 0; i < nthreads; i++) 48772f02a94SJin Yao runtime_stat__init(&config->stats[i]); 48872f02a94SJin Yao 48972f02a94SJin Yao return 0; 49072f02a94SJin Yao } 49172f02a94SJin Yao 49272f02a94SJin Yao static void runtime_stat_delete(struct perf_stat_config *config) 49372f02a94SJin Yao { 49472f02a94SJin Yao int i; 49572f02a94SJin Yao 49672f02a94SJin Yao if (!config->stats) 49772f02a94SJin Yao return; 49872f02a94SJin Yao 49972f02a94SJin Yao for (i = 0; i < config->stats_num; i++) 50072f02a94SJin Yao runtime_stat__exit(&config->stats[i]); 50172f02a94SJin Yao 50272f02a94SJin Yao zfree(&config->stats); 50372f02a94SJin Yao } 50472f02a94SJin Yao 50572f02a94SJin Yao static void runtime_stat_reset(struct perf_stat_config *config) 50672f02a94SJin Yao { 50772f02a94SJin Yao int i; 50872f02a94SJin Yao 50972f02a94SJin Yao if (!config->stats) 51072f02a94SJin Yao return; 51172f02a94SJin Yao 51272f02a94SJin Yao for (i = 0; i < config->stats_num; i++) 51372f02a94SJin Yao perf_stat__reset_shadow_per_stat(&config->stats[i]); 51472f02a94SJin Yao } 51572f02a94SJin Yao 516ba411a95SJiri Olsa static void process_interval(void) 51713370a9bSStephane Eranian { 51813370a9bSStephane Eranian struct timespec ts, rs; 51913370a9bSStephane Eranian 52013370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ts); 52113370a9bSStephane Eranian diff_timespec(&rs, &ts, &ref_time); 52213370a9bSStephane Eranian 523197ba86fSJin Yao perf_stat__reset_shadow_per_stat(&rt_stat); 52472f02a94SJin Yao runtime_stat_reset(&stat_config); 525f0fbb114SAndi Kleen read_counters(&rs); 526f0fbb114SAndi Kleen 5277aad0c32SJiri Olsa if (STAT_RECORD) { 528bd48c63eSArnaldo Carvalho de Melo if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL)) 5297aad0c32SJiri Olsa pr_err("failed to write stat round event\n"); 5307aad0c32SJiri Olsa } 5317aad0c32SJiri Olsa 532b90f1333SAndi Kleen init_stats(&walltime_nsecs_stats); 533ea9eb1f4SJiri Olsa update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000ULL); 534d4f63a47SJiri Olsa print_counters(&rs, 0, NULL); 53513370a9bSStephane Eranian } 53613370a9bSStephane Eranian 537dece3a4dSAlexey Budankov static bool handle_interval(unsigned int interval, int *times) 538dece3a4dSAlexey Budankov { 539dece3a4dSAlexey Budankov if (interval) { 540dece3a4dSAlexey Budankov process_interval(); 541dece3a4dSAlexey Budankov if (interval_count && !(--(*times))) 542dece3a4dSAlexey Budankov return true; 543dece3a4dSAlexey Budankov } 544dece3a4dSAlexey Budankov return false; 545dece3a4dSAlexey Budankov } 546dece3a4dSAlexey Budankov 547fa853c4bSSong Liu static int enable_counters(void) 54841191688SAndi Kleen { 549fa853c4bSSong Liu struct evsel *evsel; 550fa853c4bSSong Liu int err; 551fa853c4bSSong Liu 552fa853c4bSSong Liu evlist__for_each_entry(evsel_list, evsel) { 553112cb561SSong Liu if (!evsel__is_bpf(evsel)) 554112cb561SSong Liu continue; 555112cb561SSong Liu 556fa853c4bSSong Liu err = bpf_counter__enable(evsel); 557fa853c4bSSong Liu if (err) 558fa853c4bSSong Liu return err; 559fa853c4bSSong Liu } 560fa853c4bSSong Liu 5612162b9c6SAlexey Budankov if (stat_config.initial_delay < 0) { 5622162b9c6SAlexey Budankov pr_info(EVLIST_DISABLED_MSG); 563fa853c4bSSong Liu return 0; 5642162b9c6SAlexey Budankov } 5652162b9c6SAlexey Budankov 5662162b9c6SAlexey Budankov if (stat_config.initial_delay > 0) { 5672162b9c6SAlexey Budankov pr_info(EVLIST_DISABLED_MSG); 568728c0ee0SJiri Olsa usleep(stat_config.initial_delay * USEC_PER_MSEC); 5692162b9c6SAlexey Budankov } 57067ccdecdSJiri Olsa 57167ccdecdSJiri Olsa /* 57267ccdecdSJiri Olsa * We need to enable counters only if: 57367ccdecdSJiri Olsa * - we don't have tracee (attaching to task or cpu) 57467ccdecdSJiri Olsa * - we have initial delay configured 57567ccdecdSJiri Olsa */ 5762162b9c6SAlexey Budankov if (!target__none(&target) || stat_config.initial_delay) { 577f8b61bd2SSong Liu if (!all_counters_use_bpf) 5781c87f165SJiri Olsa evlist__enable(evsel_list); 5792162b9c6SAlexey Budankov if (stat_config.initial_delay > 0) 5802162b9c6SAlexey Budankov pr_info(EVLIST_ENABLED_MSG); 5812162b9c6SAlexey Budankov } 582fa853c4bSSong Liu return 0; 58341191688SAndi Kleen } 58441191688SAndi Kleen 5853df33effSMark Rutland static void disable_counters(void) 5863df33effSMark Rutland { 587f8b61bd2SSong Liu struct evsel *counter; 588f8b61bd2SSong Liu 5893df33effSMark Rutland /* 5903df33effSMark Rutland * If we don't have tracee (attaching to task or cpu), counters may 5913df33effSMark Rutland * still be running. To get accurate group ratios, we must stop groups 5923df33effSMark Rutland * from counting before reading their constituent counters. 5933df33effSMark Rutland */ 594f8b61bd2SSong Liu if (!target__none(&target)) { 595f8b61bd2SSong Liu evlist__for_each_entry(evsel_list, counter) 596f8b61bd2SSong Liu bpf_counter__disable(counter); 597f8b61bd2SSong Liu if (!all_counters_use_bpf) 598e74676deSJiri Olsa evlist__disable(evsel_list); 5993df33effSMark Rutland } 600f8b61bd2SSong Liu } 6013df33effSMark Rutland 602f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno; 6036af206fdSArnaldo Carvalho de Melo 6046af206fdSArnaldo Carvalho de Melo /* 6057b392ef0SArnaldo Carvalho de Melo * evlist__prepare_workload will send a SIGUSR1 6066af206fdSArnaldo Carvalho de Melo * if the fork fails, since we asked by setting its 6076af206fdSArnaldo Carvalho de Melo * want_signal to true. 6086af206fdSArnaldo Carvalho de Melo */ 609f33cbe72SArnaldo Carvalho de Melo static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info, 610f33cbe72SArnaldo Carvalho de Melo void *ucontext __maybe_unused) 6116af206fdSArnaldo Carvalho de Melo { 612f33cbe72SArnaldo Carvalho de Melo workload_exec_errno = info->si_value.sival_int; 6136af206fdSArnaldo Carvalho de Melo } 6146af206fdSArnaldo Carvalho de Melo 615ddc6999eSArnaldo Carvalho de Melo static bool evsel__should_store_id(struct evsel *counter) 61682bf311eSJiri Olsa { 6171fc632ceSJiri Olsa return STAT_RECORD || counter->core.attr.read_format & PERF_FORMAT_ID; 61882bf311eSJiri Olsa } 61982bf311eSJiri Olsa 620cbb5df7eSJiri Olsa static bool is_target_alive(struct target *_target, 6219749b90eSJiri Olsa struct perf_thread_map *threads) 622cbb5df7eSJiri Olsa { 623cbb5df7eSJiri Olsa struct stat st; 624cbb5df7eSJiri Olsa int i; 625cbb5df7eSJiri Olsa 626cbb5df7eSJiri Olsa if (!target__has_task(_target)) 627cbb5df7eSJiri Olsa return true; 628cbb5df7eSJiri Olsa 629cbb5df7eSJiri Olsa for (i = 0; i < threads->nr; i++) { 630cbb5df7eSJiri Olsa char path[PATH_MAX]; 631cbb5df7eSJiri Olsa 632cbb5df7eSJiri Olsa scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(), 633cbb5df7eSJiri Olsa threads->map[i].pid); 634cbb5df7eSJiri Olsa 635cbb5df7eSJiri Olsa if (!stat(path, &st)) 636cbb5df7eSJiri Olsa return true; 637cbb5df7eSJiri Olsa } 638cbb5df7eSJiri Olsa 639cbb5df7eSJiri Olsa return false; 640cbb5df7eSJiri Olsa } 641cbb5df7eSJiri Olsa 642bee328cbSAlexey Budankov static void process_evlist(struct evlist *evlist, unsigned int interval) 643bee328cbSAlexey Budankov { 644bee328cbSAlexey Budankov enum evlist_ctl_cmd cmd = EVLIST_CTL_CMD_UNSUPPORTED; 645bee328cbSAlexey Budankov 646bee328cbSAlexey Budankov if (evlist__ctlfd_process(evlist, &cmd) > 0) { 647bee328cbSAlexey Budankov switch (cmd) { 648bee328cbSAlexey Budankov case EVLIST_CTL_CMD_ENABLE: 649bee328cbSAlexey Budankov if (interval) 650bee328cbSAlexey Budankov process_interval(); 651bee328cbSAlexey Budankov break; 652bee328cbSAlexey Budankov case EVLIST_CTL_CMD_DISABLE: 653bee328cbSAlexey Budankov if (interval) 654bee328cbSAlexey Budankov process_interval(); 655bee328cbSAlexey Budankov break; 656d20aff15SAdrian Hunter case EVLIST_CTL_CMD_SNAPSHOT: 657bee328cbSAlexey Budankov case EVLIST_CTL_CMD_ACK: 658bee328cbSAlexey Budankov case EVLIST_CTL_CMD_UNSUPPORTED: 659142544a9SJiri Olsa case EVLIST_CTL_CMD_EVLIST: 660f186cd61SJiri Olsa case EVLIST_CTL_CMD_STOP: 66147fddcb4SJiri Olsa case EVLIST_CTL_CMD_PING: 662bee328cbSAlexey Budankov default: 663bee328cbSAlexey Budankov break; 664bee328cbSAlexey Budankov } 665bee328cbSAlexey Budankov } 666bee328cbSAlexey Budankov } 667bee328cbSAlexey Budankov 668bee328cbSAlexey Budankov static void compute_tts(struct timespec *time_start, struct timespec *time_stop, 669bee328cbSAlexey Budankov int *time_to_sleep) 670bee328cbSAlexey Budankov { 671bee328cbSAlexey Budankov int tts = *time_to_sleep; 672bee328cbSAlexey Budankov struct timespec time_diff; 673bee328cbSAlexey Budankov 674bee328cbSAlexey Budankov diff_timespec(&time_diff, time_stop, time_start); 675bee328cbSAlexey Budankov 676bee328cbSAlexey Budankov tts -= time_diff.tv_sec * MSEC_PER_SEC + 677bee328cbSAlexey Budankov time_diff.tv_nsec / NSEC_PER_MSEC; 678bee328cbSAlexey Budankov 679bee328cbSAlexey Budankov if (tts < 0) 680bee328cbSAlexey Budankov tts = 0; 681bee328cbSAlexey Budankov 682bee328cbSAlexey Budankov *time_to_sleep = tts; 683bee328cbSAlexey Budankov } 684bee328cbSAlexey Budankov 685bee328cbSAlexey Budankov static int dispatch_events(bool forks, int timeout, int interval, int *times) 686987b8238SAlexey Budankov { 687987b8238SAlexey Budankov int child_exited = 0, status = 0; 688bee328cbSAlexey Budankov int time_to_sleep, sleep_time; 689bee328cbSAlexey Budankov struct timespec time_start, time_stop; 690bee328cbSAlexey Budankov 691bee328cbSAlexey Budankov if (interval) 692bee328cbSAlexey Budankov sleep_time = interval; 693bee328cbSAlexey Budankov else if (timeout) 694bee328cbSAlexey Budankov sleep_time = timeout; 695bee328cbSAlexey Budankov else 696bee328cbSAlexey Budankov sleep_time = 1000; 697bee328cbSAlexey Budankov 698bee328cbSAlexey Budankov time_to_sleep = sleep_time; 699987b8238SAlexey Budankov 700987b8238SAlexey Budankov while (!done) { 701987b8238SAlexey Budankov if (forks) 702987b8238SAlexey Budankov child_exited = waitpid(child_pid, &status, WNOHANG); 703987b8238SAlexey Budankov else 704987b8238SAlexey Budankov child_exited = !is_target_alive(&target, evsel_list->core.threads) ? 1 : 0; 705987b8238SAlexey Budankov 706987b8238SAlexey Budankov if (child_exited) 707987b8238SAlexey Budankov break; 708987b8238SAlexey Budankov 709bee328cbSAlexey Budankov clock_gettime(CLOCK_MONOTONIC, &time_start); 710bee328cbSAlexey Budankov if (!(evlist__poll(evsel_list, time_to_sleep) > 0)) { /* poll timeout or EINTR */ 711987b8238SAlexey Budankov if (timeout || handle_interval(interval, times)) 712987b8238SAlexey Budankov break; 713bee328cbSAlexey Budankov time_to_sleep = sleep_time; 714bee328cbSAlexey Budankov } else { /* fd revent */ 715bee328cbSAlexey Budankov process_evlist(evsel_list, interval); 716bee328cbSAlexey Budankov clock_gettime(CLOCK_MONOTONIC, &time_stop); 717bee328cbSAlexey Budankov compute_tts(&time_start, &time_stop, &time_to_sleep); 718bee328cbSAlexey Budankov } 719987b8238SAlexey Budankov } 720987b8238SAlexey Budankov 721987b8238SAlexey Budankov return status; 722987b8238SAlexey Budankov } 723987b8238SAlexey Budankov 724e0e6a6caSAndi Kleen enum counter_recovery { 725e0e6a6caSAndi Kleen COUNTER_SKIP, 726e0e6a6caSAndi Kleen COUNTER_RETRY, 727e0e6a6caSAndi Kleen COUNTER_FATAL, 728e0e6a6caSAndi Kleen }; 729e0e6a6caSAndi Kleen 730e0e6a6caSAndi Kleen static enum counter_recovery stat_handle_error(struct evsel *counter) 731e0e6a6caSAndi Kleen { 732e0e6a6caSAndi Kleen char msg[BUFSIZ]; 733e0e6a6caSAndi Kleen /* 734e0e6a6caSAndi Kleen * PPC returns ENXIO for HW counters until 2.6.37 735e0e6a6caSAndi Kleen * (behavior changed with commit b0a873e). 736e0e6a6caSAndi Kleen */ 737e0e6a6caSAndi Kleen if (errno == EINVAL || errno == ENOSYS || 738e0e6a6caSAndi Kleen errno == ENOENT || errno == EOPNOTSUPP || 739e0e6a6caSAndi Kleen errno == ENXIO) { 740e0e6a6caSAndi Kleen if (verbose > 0) 741e0e6a6caSAndi Kleen ui__warning("%s event is not supported by the kernel.\n", 7428ab2e96dSArnaldo Carvalho de Melo evsel__name(counter)); 743e0e6a6caSAndi Kleen counter->supported = false; 7444804e011SAndi Kleen /* 7454804e011SAndi Kleen * errored is a sticky flag that means one of the counter's 7464804e011SAndi Kleen * cpu event had a problem and needs to be reexamined. 7474804e011SAndi Kleen */ 7484804e011SAndi Kleen counter->errored = true; 749e0e6a6caSAndi Kleen 750fba7c866SJiri Olsa if ((evsel__leader(counter) != counter) || 751fba7c866SJiri Olsa !(counter->core.leader->nr_members > 1)) 752e0e6a6caSAndi Kleen return COUNTER_SKIP; 753ae430892SArnaldo Carvalho de Melo } else if (evsel__fallback(counter, errno, msg, sizeof(msg))) { 754e0e6a6caSAndi Kleen if (verbose > 0) 755e0e6a6caSAndi Kleen ui__warning("%s\n", msg); 756e0e6a6caSAndi Kleen return COUNTER_RETRY; 757e0e6a6caSAndi Kleen } else if (target__has_per_thread(&target) && 758e0e6a6caSAndi Kleen evsel_list->core.threads && 759e0e6a6caSAndi Kleen evsel_list->core.threads->err_thread != -1) { 760e0e6a6caSAndi Kleen /* 761e0e6a6caSAndi Kleen * For global --per-thread case, skip current 762e0e6a6caSAndi Kleen * error thread. 763e0e6a6caSAndi Kleen */ 764e0e6a6caSAndi Kleen if (!thread_map__remove(evsel_list->core.threads, 765e0e6a6caSAndi Kleen evsel_list->core.threads->err_thread)) { 766e0e6a6caSAndi Kleen evsel_list->core.threads->err_thread = -1; 767e0e6a6caSAndi Kleen return COUNTER_RETRY; 768e0e6a6caSAndi Kleen } 769e0e6a6caSAndi Kleen } 770e0e6a6caSAndi Kleen 7712bb72dbbSArnaldo Carvalho de Melo evsel__open_strerror(counter, &target, errno, msg, sizeof(msg)); 772e0e6a6caSAndi Kleen ui__error("%s\n", msg); 773e0e6a6caSAndi Kleen 774e0e6a6caSAndi Kleen if (child_pid != -1) 775e0e6a6caSAndi Kleen kill(child_pid, SIGTERM); 776e0e6a6caSAndi Kleen return COUNTER_FATAL; 777e0e6a6caSAndi Kleen } 778e0e6a6caSAndi Kleen 779e55c14afSJiri Olsa static int __run_perf_stat(int argc, const char **argv, int run_idx) 78086470930SIngo Molnar { 781ec0d3d1fSJiri Olsa int interval = stat_config.interval; 782db06a269Syuzhoujian int times = stat_config.times; 783f1f8ad52Syuzhoujian int timeout = stat_config.timeout; 784d6195a6aSArnaldo Carvalho de Melo char msg[BUFSIZ]; 78586470930SIngo Molnar unsigned long long t0, t1; 78632dcd021SJiri Olsa struct evsel *counter; 787410136f5SStephane Eranian size_t l; 78842202dd5SIngo Molnar int status = 0; 7896be2850eSZhang, Yanmin const bool forks = (argc > 0); 7908ceb41d7SJiri Olsa bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false; 7914804e011SAndi Kleen struct affinity affinity; 792fa853c4bSSong Liu int i, cpu, err; 7934804e011SAndi Kleen bool second_pass = false; 79486470930SIngo Molnar 795acf28922SNamhyung Kim if (forks) { 7967b392ef0SArnaldo Carvalho de Melo if (evlist__prepare_workload(evsel_list, &target, argv, is_pipe, workload_exec_failed_signal) < 0) { 797acf28922SNamhyung Kim perror("failed to prepare workload"); 798fceda7feSDavid Ahern return -1; 799051ae7f7SPaul Mackerras } 800d20a47e7SNamhyung Kim child_pid = evsel_list->workload.pid; 80160666c63SLiming Wang } 802051ae7f7SPaul Mackerras 8036a4bb04cSJiri Olsa if (group) 804a622eafaSArnaldo Carvalho de Melo evlist__set_leader(evsel_list); 8056a4bb04cSJiri Olsa 8064804e011SAndi Kleen if (affinity__setup(&affinity) < 0) 8074804e011SAndi Kleen return -1; 8085a5dfe4bSAndi Kleen 809fa853c4bSSong Liu evlist__for_each_entry(evsel_list, counter) { 810fa853c4bSSong Liu if (bpf_counter__load(counter, &target)) 811fa853c4bSSong Liu return -1; 812112cb561SSong Liu if (!evsel__is_bpf(counter)) 813112cb561SSong Liu all_counters_use_bpf = false; 814fa853c4bSSong Liu } 815fa853c4bSSong Liu 8164804e011SAndi Kleen evlist__for_each_cpu (evsel_list, i, cpu) { 8177fac83aaSSong Liu /* 8187fac83aaSSong Liu * bperf calls evsel__open_per_cpu() in bperf__load(), so 8197fac83aaSSong Liu * no need to call it again here. 8207fac83aaSSong Liu */ 8217fac83aaSSong Liu if (target.use_bpf) 8227fac83aaSSong Liu break; 8234804e011SAndi Kleen affinity__set(&affinity, cpu); 8244804e011SAndi Kleen 8254804e011SAndi Kleen evlist__for_each_entry(evsel_list, counter) { 8264804e011SAndi Kleen if (evsel__cpu_iter_skip(counter, cpu)) 8274804e011SAndi Kleen continue; 8284804e011SAndi Kleen if (counter->reset_group || counter->errored) 8294804e011SAndi Kleen continue; 830112cb561SSong Liu if (evsel__is_bpf(counter)) 831112cb561SSong Liu continue; 8324804e011SAndi Kleen try_again: 8334804e011SAndi Kleen if (create_perf_stat_counter(counter, &stat_config, &target, 8344804e011SAndi Kleen counter->cpu_iter - 1) < 0) { 8354804e011SAndi Kleen 8364804e011SAndi Kleen /* 8374804e011SAndi Kleen * Weak group failed. We cannot just undo this here 8384804e011SAndi Kleen * because earlier CPUs might be in group mode, and the kernel 8394804e011SAndi Kleen * doesn't support mixing group and non group reads. Defer 8404804e011SAndi Kleen * it to later. 8414804e011SAndi Kleen * Don't close here because we're in the wrong affinity. 8424804e011SAndi Kleen */ 84335c1980eSAndi Kleen if ((errno == EINVAL || errno == EBADF) && 844fba7c866SJiri Olsa evsel__leader(counter) != counter && 8455a5dfe4bSAndi Kleen counter->weak_group) { 84664b4778bSArnaldo Carvalho de Melo evlist__reset_weak_group(evsel_list, counter, false); 8474804e011SAndi Kleen assert(counter->reset_group); 8484804e011SAndi Kleen second_pass = true; 8494804e011SAndi Kleen continue; 8505a5dfe4bSAndi Kleen } 8515a5dfe4bSAndi Kleen 852e0e6a6caSAndi Kleen switch (stat_handle_error(counter)) { 853e0e6a6caSAndi Kleen case COUNTER_FATAL: 854084ab9f8SArnaldo Carvalho de Melo return -1; 855e0e6a6caSAndi Kleen case COUNTER_RETRY: 856e0e6a6caSAndi Kleen goto try_again; 857e0e6a6caSAndi Kleen case COUNTER_SKIP: 858e0e6a6caSAndi Kleen continue; 859e0e6a6caSAndi Kleen default: 860e0e6a6caSAndi Kleen break; 861e0e6a6caSAndi Kleen } 8624804e011SAndi Kleen 863084ab9f8SArnaldo Carvalho de Melo } 8642cee77c4SDavid Ahern counter->supported = true; 8654804e011SAndi Kleen } 8664804e011SAndi Kleen } 8674804e011SAndi Kleen 8684804e011SAndi Kleen if (second_pass) { 8694804e011SAndi Kleen /* 8704804e011SAndi Kleen * Now redo all the weak group after closing them, 8714804e011SAndi Kleen * and also close errored counters. 8724804e011SAndi Kleen */ 8734804e011SAndi Kleen 8744804e011SAndi Kleen evlist__for_each_cpu(evsel_list, i, cpu) { 8754804e011SAndi Kleen affinity__set(&affinity, cpu); 8764804e011SAndi Kleen /* First close errored or weak retry */ 8774804e011SAndi Kleen evlist__for_each_entry(evsel_list, counter) { 8784804e011SAndi Kleen if (!counter->reset_group && !counter->errored) 8794804e011SAndi Kleen continue; 8804804e011SAndi Kleen if (evsel__cpu_iter_skip_no_inc(counter, cpu)) 8814804e011SAndi Kleen continue; 8824804e011SAndi Kleen perf_evsel__close_cpu(&counter->core, counter->cpu_iter); 8834804e011SAndi Kleen } 8844804e011SAndi Kleen /* Now reopen weak */ 8854804e011SAndi Kleen evlist__for_each_entry(evsel_list, counter) { 8864804e011SAndi Kleen if (!counter->reset_group && !counter->errored) 8874804e011SAndi Kleen continue; 8884804e011SAndi Kleen if (evsel__cpu_iter_skip(counter, cpu)) 8894804e011SAndi Kleen continue; 8904804e011SAndi Kleen if (!counter->reset_group) 8914804e011SAndi Kleen continue; 8924804e011SAndi Kleen try_again_reset: 8938ab2e96dSArnaldo Carvalho de Melo pr_debug2("reopening weak %s\n", evsel__name(counter)); 8944804e011SAndi Kleen if (create_perf_stat_counter(counter, &stat_config, &target, 8954804e011SAndi Kleen counter->cpu_iter - 1) < 0) { 8964804e011SAndi Kleen 8974804e011SAndi Kleen switch (stat_handle_error(counter)) { 8984804e011SAndi Kleen case COUNTER_FATAL: 8994804e011SAndi Kleen return -1; 9004804e011SAndi Kleen case COUNTER_RETRY: 9014804e011SAndi Kleen goto try_again_reset; 9024804e011SAndi Kleen case COUNTER_SKIP: 9034804e011SAndi Kleen continue; 9044804e011SAndi Kleen default: 9054804e011SAndi Kleen break; 9064804e011SAndi Kleen } 9074804e011SAndi Kleen } 9084804e011SAndi Kleen counter->supported = true; 9094804e011SAndi Kleen } 9104804e011SAndi Kleen } 9114804e011SAndi Kleen } 9124804e011SAndi Kleen affinity__cleanup(&affinity); 9134804e011SAndi Kleen 9144804e011SAndi Kleen evlist__for_each_entry(evsel_list, counter) { 9154804e011SAndi Kleen if (!counter->supported) { 9164804e011SAndi Kleen perf_evsel__free_fd(&counter->core); 9174804e011SAndi Kleen continue; 9184804e011SAndi Kleen } 919410136f5SStephane Eranian 920410136f5SStephane Eranian l = strlen(counter->unit); 921df4f7b4dSJiri Olsa if (l > stat_config.unit_width) 922df4f7b4dSJiri Olsa stat_config.unit_width = l; 9232af4646dSJiri Olsa 924ddc6999eSArnaldo Carvalho de Melo if (evsel__should_store_id(counter) && 92534397753SArnaldo Carvalho de Melo evsel__store_ids(counter, evsel_list)) 9262af4646dSJiri Olsa return -1; 92748290609SArnaldo Carvalho de Melo } 92886470930SIngo Molnar 92924bf91a7SArnaldo Carvalho de Melo if (evlist__apply_filters(evsel_list, &counter)) { 93062d94b00SArnaldo Carvalho de Melo pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", 9318ab2e96dSArnaldo Carvalho de Melo counter->filter, evsel__name(counter), errno, 932c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, msg, sizeof(msg))); 933cfd748aeSFrederic Weisbecker return -1; 934cfd748aeSFrederic Weisbecker } 935cfd748aeSFrederic Weisbecker 9364979d0c7SJiri Olsa if (STAT_RECORD) { 937fa853c4bSSong Liu int fd = perf_data__fd(&perf_stat.data); 9384979d0c7SJiri Olsa 939664c98d4SJiri Olsa if (is_pipe) { 9408ceb41d7SJiri Olsa err = perf_header__write_pipe(perf_data__fd(&perf_stat.data)); 941664c98d4SJiri Olsa } else { 9424979d0c7SJiri Olsa err = perf_session__write_header(perf_stat.session, evsel_list, 9434979d0c7SJiri Olsa fd, false); 944664c98d4SJiri Olsa } 945664c98d4SJiri Olsa 9464979d0c7SJiri Olsa if (err < 0) 9474979d0c7SJiri Olsa return err; 9488b99b1a4SJiri Olsa 949b251892dSArnaldo Carvalho de Melo err = perf_event__synthesize_stat_events(&stat_config, NULL, evsel_list, 950c2c247f2SJiri Olsa process_synthesized_event, is_pipe); 9518b99b1a4SJiri Olsa if (err < 0) 9528b99b1a4SJiri Olsa return err; 9534979d0c7SJiri Olsa } 9544979d0c7SJiri Olsa 95586470930SIngo Molnar /* 95686470930SIngo Molnar * Enable counters and exec the command: 95786470930SIngo Molnar */ 95860666c63SLiming Wang if (forks) { 9597b392ef0SArnaldo Carvalho de Melo evlist__start_workload(evsel_list); 960fa853c4bSSong Liu err = enable_counters(); 961fa853c4bSSong Liu if (err) 962fa853c4bSSong Liu return -1; 963acf28922SNamhyung Kim 964435b46efSSong Liu t0 = rdclock(); 965435b46efSSong Liu clock_gettime(CLOCK_MONOTONIC, &ref_time); 966435b46efSSong Liu 96727e9769aSAlexey Budankov if (interval || timeout || evlist__ctlfd_initialized(evsel_list)) 968bee328cbSAlexey Budankov status = dispatch_events(forks, timeout, interval, ×); 969cfbd41b7SArnaldo Carvalho de Melo if (child_pid != -1) { 970cfbd41b7SArnaldo Carvalho de Melo if (timeout) 971cfbd41b7SArnaldo Carvalho de Melo kill(child_pid, SIGTERM); 9728897a891SJiri Olsa wait4(child_pid, &status, 0, &stat_config.ru_data); 973cfbd41b7SArnaldo Carvalho de Melo } 9746af206fdSArnaldo Carvalho de Melo 975f33cbe72SArnaldo Carvalho de Melo if (workload_exec_errno) { 976c8b5f2c9SArnaldo Carvalho de Melo const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); 977f33cbe72SArnaldo Carvalho de Melo pr_err("Workload failed: %s\n", emsg); 9786af206fdSArnaldo Carvalho de Melo return -1; 979f33cbe72SArnaldo Carvalho de Melo } 9806af206fdSArnaldo Carvalho de Melo 98133e49ea7SAndi Kleen if (WIFSIGNALED(status)) 98233e49ea7SAndi Kleen psignal(WTERMSIG(status), argv[0]); 98360666c63SLiming Wang } else { 984fa853c4bSSong Liu err = enable_counters(); 985fa853c4bSSong Liu if (err) 986fa853c4bSSong Liu return -1; 987435b46efSSong Liu 988435b46efSSong Liu t0 = rdclock(); 989435b46efSSong Liu clock_gettime(CLOCK_MONOTONIC, &ref_time); 990435b46efSSong Liu 991bee328cbSAlexey Budankov status = dispatch_events(forks, timeout, interval, ×); 99260666c63SLiming Wang } 99386470930SIngo Molnar 9943df33effSMark Rutland disable_counters(); 9953df33effSMark Rutland 99686470930SIngo Molnar t1 = rdclock(); 99786470930SIngo Molnar 99854ac0b1bSJiri Olsa if (stat_config.walltime_run_table) 99954ac0b1bSJiri Olsa stat_config.walltime_run[run_idx] = t1 - t0; 1000e55c14afSJiri Olsa 1001ee6a9614SJin Yao if (interval && stat_config.summary) { 1002c7e5b328SJin Yao stat_config.interval = 0; 1003ee6a9614SJin Yao stat_config.stop_read_counter = true; 1004c7e5b328SJin Yao init_stats(&walltime_nsecs_stats); 1005c7e5b328SJin Yao update_stats(&walltime_nsecs_stats, t1 - t0); 1006c7e5b328SJin Yao 1007c7e5b328SJin Yao if (stat_config.aggr_mode == AGGR_GLOBAL) 100853f5e908SArnaldo Carvalho de Melo evlist__save_aggr_prev_raw_counts(evsel_list); 1009c7e5b328SJin Yao 101053f5e908SArnaldo Carvalho de Melo evlist__copy_prev_raw_counts(evsel_list); 101153f5e908SArnaldo Carvalho de Melo evlist__reset_prev_raw_counts(evsel_list); 1012c7e5b328SJin Yao runtime_stat_reset(&stat_config); 1013c7e5b328SJin Yao perf_stat__reset_shadow_per_stat(&rt_stat); 1014c7e5b328SJin Yao } else 10159e9772c4SPeter Zijlstra update_stats(&walltime_nsecs_stats, t1 - t0); 101642202dd5SIngo Molnar 10173df33effSMark Rutland /* 10183df33effSMark Rutland * Closing a group leader splits the group, and as we only disable 10193df33effSMark Rutland * group leaders, results in remaining events becoming enabled. To 10203df33effSMark Rutland * avoid arbitrary skew, we must read all counters before closing any 10213df33effSMark Rutland * group leaders. 10223df33effSMark Rutland */ 1023f0fbb114SAndi Kleen read_counters(&(struct timespec) { .tv_nsec = t1-t0 }); 102408ef3af1SJiri Olsa 102508ef3af1SJiri Olsa /* 102608ef3af1SJiri Olsa * We need to keep evsel_list alive, because it's processed 102708ef3af1SJiri Olsa * later the evsel_list will be closed after. 102808ef3af1SJiri Olsa */ 102908ef3af1SJiri Olsa if (!STAT_RECORD) 1030750b4edeSJiri Olsa evlist__close(evsel_list); 1031c52b12edSArnaldo Carvalho de Melo 103242202dd5SIngo Molnar return WEXITSTATUS(status); 103342202dd5SIngo Molnar } 103442202dd5SIngo Molnar 1035e55c14afSJiri Olsa static int run_perf_stat(int argc, const char **argv, int run_idx) 10361f16c575SPeter Zijlstra { 10371f16c575SPeter Zijlstra int ret; 10381f16c575SPeter Zijlstra 10391f16c575SPeter Zijlstra if (pre_cmd) { 10401f16c575SPeter Zijlstra ret = system(pre_cmd); 10411f16c575SPeter Zijlstra if (ret) 10421f16c575SPeter Zijlstra return ret; 10431f16c575SPeter Zijlstra } 10441f16c575SPeter Zijlstra 10451f16c575SPeter Zijlstra if (sync_run) 10461f16c575SPeter Zijlstra sync(); 10471f16c575SPeter Zijlstra 1048e55c14afSJiri Olsa ret = __run_perf_stat(argc, argv, run_idx); 10491f16c575SPeter Zijlstra if (ret) 10501f16c575SPeter Zijlstra return ret; 10511f16c575SPeter Zijlstra 10521f16c575SPeter Zijlstra if (post_cmd) { 10531f16c575SPeter Zijlstra ret = system(post_cmd); 10541f16c575SPeter Zijlstra if (ret) 10551f16c575SPeter Zijlstra return ret; 10561f16c575SPeter Zijlstra } 10571f16c575SPeter Zijlstra 10581f16c575SPeter Zijlstra return ret; 10591f16c575SPeter Zijlstra } 10601f16c575SPeter Zijlstra 1061a5a9eac1SJiri Olsa static void print_counters(struct timespec *ts, int argc, const char **argv) 1062a5a9eac1SJiri Olsa { 10630174820aSJiri Olsa /* Do not print anything if we record to the pipe. */ 10640174820aSJiri Olsa if (STAT_RECORD && perf_stat.data.is_pipe) 10650174820aSJiri Olsa return; 106655a4de94SAndi Kleen if (stat_config.quiet) 106755a4de94SAndi Kleen return; 10680174820aSJiri Olsa 106971273724SArnaldo Carvalho de Melo evlist__print_counters(evsel_list, &stat_config, &target, ts, argc, argv); 1070a5a9eac1SJiri Olsa } 1071a5a9eac1SJiri Olsa 1072f7b7c26eSPeter Zijlstra static volatile int signr = -1; 1073f7b7c26eSPeter Zijlstra 107486470930SIngo Molnar static void skip_signal(int signo) 107586470930SIngo Molnar { 1076ec0d3d1fSJiri Olsa if ((child_pid == -1) || stat_config.interval) 107760666c63SLiming Wang done = 1; 107860666c63SLiming Wang 1079f7b7c26eSPeter Zijlstra signr = signo; 1080d07f0b12SStephane Eranian /* 1081d07f0b12SStephane Eranian * render child_pid harmless 1082d07f0b12SStephane Eranian * won't send SIGTERM to a random 1083d07f0b12SStephane Eranian * process in case of race condition 1084d07f0b12SStephane Eranian * and fast PID recycling 1085d07f0b12SStephane Eranian */ 1086d07f0b12SStephane Eranian child_pid = -1; 1087f7b7c26eSPeter Zijlstra } 1088f7b7c26eSPeter Zijlstra 1089f7b7c26eSPeter Zijlstra static void sig_atexit(void) 1090f7b7c26eSPeter Zijlstra { 1091d07f0b12SStephane Eranian sigset_t set, oset; 1092d07f0b12SStephane Eranian 1093d07f0b12SStephane Eranian /* 1094d07f0b12SStephane Eranian * avoid race condition with SIGCHLD handler 1095d07f0b12SStephane Eranian * in skip_signal() which is modifying child_pid 1096d07f0b12SStephane Eranian * goal is to avoid send SIGTERM to a random 1097d07f0b12SStephane Eranian * process 1098d07f0b12SStephane Eranian */ 1099d07f0b12SStephane Eranian sigemptyset(&set); 1100d07f0b12SStephane Eranian sigaddset(&set, SIGCHLD); 1101d07f0b12SStephane Eranian sigprocmask(SIG_BLOCK, &set, &oset); 1102d07f0b12SStephane Eranian 1103933da83aSChris Wilson if (child_pid != -1) 1104933da83aSChris Wilson kill(child_pid, SIGTERM); 1105933da83aSChris Wilson 1106d07f0b12SStephane Eranian sigprocmask(SIG_SETMASK, &oset, NULL); 1107d07f0b12SStephane Eranian 1108f7b7c26eSPeter Zijlstra if (signr == -1) 1109f7b7c26eSPeter Zijlstra return; 1110f7b7c26eSPeter Zijlstra 1111f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 1112f7b7c26eSPeter Zijlstra kill(getpid(), signr); 111386470930SIngo Molnar } 111486470930SIngo Molnar 1115d778a778SPaul A. Clarke void perf_stat__set_big_num(int set) 1116d778a778SPaul A. Clarke { 1117d778a778SPaul A. Clarke stat_config.big_num = (set != 0); 1118d778a778SPaul A. Clarke } 1119d778a778SPaul A. Clarke 11200bdad978SJin Yao void perf_stat__set_no_csv_summary(int set) 11210bdad978SJin Yao { 11220bdad978SJin Yao stat_config.no_csv_summary = (set != 0); 11230bdad978SJin Yao } 11240bdad978SJin Yao 11251d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused, 11261d037ca1SIrina Tirdea const char *s __maybe_unused, int unset) 1127d7470b6aSStephane Eranian { 1128d7470b6aSStephane Eranian big_num_opt = unset ? 0 : 1; 1129d778a778SPaul A. Clarke perf_stat__set_big_num(!unset); 1130d7470b6aSStephane Eranian return 0; 1131d7470b6aSStephane Eranian } 1132d7470b6aSStephane Eranian 113344b1e60aSAndi Kleen static int enable_metric_only(const struct option *opt __maybe_unused, 113444b1e60aSAndi Kleen const char *s __maybe_unused, int unset) 113544b1e60aSAndi Kleen { 113644b1e60aSAndi Kleen force_metric_only = true; 11370ce5aa02SJiri Olsa stat_config.metric_only = !unset; 113844b1e60aSAndi Kleen return 0; 113944b1e60aSAndi Kleen } 114044b1e60aSAndi Kleen 1141b18f3e36SAndi Kleen static int parse_metric_groups(const struct option *opt, 1142b18f3e36SAndi Kleen const char *str, 1143b18f3e36SAndi Kleen int unset __maybe_unused) 1144b18f3e36SAndi Kleen { 114505530a79SIan Rogers return metricgroup__parse_groups(opt, str, 114605530a79SIan Rogers stat_config.metric_no_group, 114705530a79SIan Rogers stat_config.metric_no_merge, 114805530a79SIan Rogers &stat_config.metric_events); 1149b18f3e36SAndi Kleen } 1150b18f3e36SAndi Kleen 115127e9769aSAlexey Budankov static int parse_control_option(const struct option *opt, 115227e9769aSAlexey Budankov const char *str, 115327e9769aSAlexey Budankov int unset __maybe_unused) 115427e9769aSAlexey Budankov { 11559864a66dSAdrian Hunter struct perf_stat_config *config = opt->value; 115627e9769aSAlexey Budankov 1157a8fcbd26SAdrian Hunter return evlist__parse_control(str, &config->ctl_fd, &config->ctl_fd_ack, &config->ctl_fd_close); 1158a8fcbd26SAdrian Hunter } 1159a8fcbd26SAdrian Hunter 1160d1c5a0e8SNamhyung Kim static int parse_stat_cgroups(const struct option *opt, 1161d1c5a0e8SNamhyung Kim const char *str, int unset) 1162d1c5a0e8SNamhyung Kim { 1163d1c5a0e8SNamhyung Kim if (stat_config.cgroup_list) { 1164d1c5a0e8SNamhyung Kim pr_err("--cgroup and --for-each-cgroup cannot be used together\n"); 1165d1c5a0e8SNamhyung Kim return -1; 1166d1c5a0e8SNamhyung Kim } 1167d1c5a0e8SNamhyung Kim 1168d1c5a0e8SNamhyung Kim return parse_cgroups(opt, str, unset); 1169d1c5a0e8SNamhyung Kim } 1170d1c5a0e8SNamhyung Kim 117151433eadSMichael Petlan static struct option stat_options[] = { 1172e0547311SJiri Olsa OPT_BOOLEAN('T', "transaction", &transaction_run, 1173e0547311SJiri Olsa "hardware transaction statistics"), 1174e0547311SJiri Olsa OPT_CALLBACK('e', "event", &evsel_list, "event", 1175e0547311SJiri Olsa "event selector. use 'perf list' to list available events", 1176e0547311SJiri Olsa parse_events_option), 1177e0547311SJiri Olsa OPT_CALLBACK(0, "filter", &evsel_list, "filter", 1178e0547311SJiri Olsa "event filter", parse_filter), 11795698f26bSJiri Olsa OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit, 1180e0547311SJiri Olsa "child tasks do not inherit counters"), 1181e0547311SJiri Olsa OPT_STRING('p', "pid", &target.pid, "pid", 1182e0547311SJiri Olsa "stat events on existing process id"), 1183e0547311SJiri Olsa OPT_STRING('t', "tid", &target.tid, "tid", 1184e0547311SJiri Olsa "stat events on existing thread id"), 1185fa853c4bSSong Liu #ifdef HAVE_BPF_SKEL 1186fa853c4bSSong Liu OPT_STRING('b', "bpf-prog", &target.bpf_str, "bpf-prog-id", 1187fa853c4bSSong Liu "stat events on existing bpf program id"), 11887fac83aaSSong Liu OPT_BOOLEAN(0, "bpf-counters", &target.use_bpf, 11897fac83aaSSong Liu "use bpf program to count events"), 11907fac83aaSSong Liu OPT_STRING(0, "bpf-attr-map", &target.attr_map, "attr-map-path", 11917fac83aaSSong Liu "path to perf_event_attr map"), 1192fa853c4bSSong Liu #endif 1193e0547311SJiri Olsa OPT_BOOLEAN('a', "all-cpus", &target.system_wide, 1194e0547311SJiri Olsa "system-wide collection from all CPUs"), 1195e0547311SJiri Olsa OPT_BOOLEAN('g', "group", &group, 1196e0547311SJiri Olsa "put the counters into a counter group"), 119775998bb2SAndi Kleen OPT_BOOLEAN(0, "scale", &stat_config.scale, 119875998bb2SAndi Kleen "Use --no-scale to disable counter scaling for multiplexing"), 1199e0547311SJiri Olsa OPT_INCR('v', "verbose", &verbose, 1200e0547311SJiri Olsa "be more verbose (show counter open errors, etc)"), 1201d97ae04bSJiri Olsa OPT_INTEGER('r', "repeat", &stat_config.run_count, 1202e0547311SJiri Olsa "repeat command and print average + stddev (max: 100, forever: 0)"), 120354ac0b1bSJiri Olsa OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table, 1204e55c14afSJiri Olsa "display details about each run (only with -r option)"), 1205aea0dca1SJiri Olsa OPT_BOOLEAN('n', "null", &stat_config.null_run, 1206e0547311SJiri Olsa "null run - dont start any counters"), 1207e0547311SJiri Olsa OPT_INCR('d', "detailed", &detailed_run, 1208e0547311SJiri Olsa "detailed run - start a lot of events"), 1209e0547311SJiri Olsa OPT_BOOLEAN('S', "sync", &sync_run, 1210e0547311SJiri Olsa "call sync() before starting a run"), 1211e0547311SJiri Olsa OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 1212e0547311SJiri Olsa "print large numbers with thousands\' separators", 1213e0547311SJiri Olsa stat__set_big_num), 1214e0547311SJiri Olsa OPT_STRING('C', "cpu", &target.cpu_list, "cpu", 1215e0547311SJiri Olsa "list of cpus to monitor in system-wide"), 1216e0547311SJiri Olsa OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode, 1217e0547311SJiri Olsa "disable CPU count aggregation", AGGR_NONE), 1218fdee335bSJiri Olsa OPT_BOOLEAN(0, "no-merge", &stat_config.no_merge, "Do not merge identical named events"), 1219fa7070a3SJiri Olsa OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator", 1220e0547311SJiri Olsa "print counts with custom separator"), 1221e0547311SJiri Olsa OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1222d1c5a0e8SNamhyung Kim "monitor event in cgroup name only", parse_stat_cgroups), 1223d1c5a0e8SNamhyung Kim OPT_STRING(0, "for-each-cgroup", &stat_config.cgroup_list, "name", 1224d1c5a0e8SNamhyung Kim "expand events for each cgroup"), 1225e0547311SJiri Olsa OPT_STRING('o', "output", &output_name, "file", "output file name"), 1226e0547311SJiri Olsa OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), 1227e0547311SJiri Olsa OPT_INTEGER(0, "log-fd", &output_fd, 1228e0547311SJiri Olsa "log output to fd, instead of stderr"), 1229e0547311SJiri Olsa OPT_STRING(0, "pre", &pre_cmd, "command", 1230e0547311SJiri Olsa "command to run prior to the measured command"), 1231e0547311SJiri Olsa OPT_STRING(0, "post", &post_cmd, "command", 1232e0547311SJiri Olsa "command to run after to the measured command"), 1233e0547311SJiri Olsa OPT_UINTEGER('I', "interval-print", &stat_config.interval, 12349dc9a95fSAlexey Budankov "print counts at regular interval in ms " 12359dc9a95fSAlexey Budankov "(overhead is possible for values <= 100ms)"), 1236db06a269Syuzhoujian OPT_INTEGER(0, "interval-count", &stat_config.times, 1237db06a269Syuzhoujian "print counts for fixed number of times"), 1238132c6ba3SJiri Olsa OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear, 12399660e08eSJiri Olsa "clear screen in between new interval"), 1240f1f8ad52Syuzhoujian OPT_UINTEGER(0, "timeout", &stat_config.timeout, 1241f1f8ad52Syuzhoujian "stop workload and print counts after a timeout period in ms (>= 10ms)"), 1242e0547311SJiri Olsa OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode, 1243e0547311SJiri Olsa "aggregate counts per processor socket", AGGR_SOCKET), 1244db5742b6SKan Liang OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode, 1245db5742b6SKan Liang "aggregate counts per processor die", AGGR_DIE), 1246e0547311SJiri Olsa OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode, 1247e0547311SJiri Olsa "aggregate counts per physical processor core", AGGR_CORE), 1248e0547311SJiri Olsa OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode, 1249e0547311SJiri Olsa "aggregate counts per thread", AGGR_THREAD), 125086895b48SJiri Olsa OPT_SET_UINT(0, "per-node", &stat_config.aggr_mode, 125186895b48SJiri Olsa "aggregate counts per numa node", AGGR_NODE), 12522162b9c6SAlexey Budankov OPT_INTEGER('D', "delay", &stat_config.initial_delay, 12532162b9c6SAlexey Budankov "ms to wait before starting measurement after program start (-1: start with events disabled)"), 12540ce5aa02SJiri Olsa OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL, 125544b1e60aSAndi Kleen "Only print computed metrics. No raw values", enable_metric_only), 125605530a79SIan Rogers OPT_BOOLEAN(0, "metric-no-group", &stat_config.metric_no_group, 125705530a79SIan Rogers "don't group metric events, impacts multiplexing"), 125805530a79SIan Rogers OPT_BOOLEAN(0, "metric-no-merge", &stat_config.metric_no_merge, 125905530a79SIan Rogers "don't try to share events between metrics in a group"), 126044b1e60aSAndi Kleen OPT_BOOLEAN(0, "topdown", &topdown_run, 126163e39aa6SKan Liang "measure top-down statistics"), 126263e39aa6SKan Liang OPT_UINTEGER(0, "td-level", &stat_config.topdown_level, 126363e39aa6SKan Liang "Set the metrics level for the top-down statistics (0: max level)"), 1264daefd0bcSKan Liang OPT_BOOLEAN(0, "smi-cost", &smi_cost, 1265daefd0bcSKan Liang "measure SMI cost"), 1266b18f3e36SAndi Kleen OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list", 1267b18f3e36SAndi Kleen "monitor specified metrics or metric groups (separated by ,)", 1268b18f3e36SAndi Kleen parse_metric_groups), 1269dd071024SJin Yao OPT_BOOLEAN_FLAG(0, "all-kernel", &stat_config.all_kernel, 1270dd071024SJin Yao "Configure all used events to run in kernel space.", 1271dd071024SJin Yao PARSE_OPT_EXCLUSIVE), 1272dd071024SJin Yao OPT_BOOLEAN_FLAG(0, "all-user", &stat_config.all_user, 1273dd071024SJin Yao "Configure all used events to run in user space.", 1274dd071024SJin Yao PARSE_OPT_EXCLUSIVE), 12751af62ce6SJin Yao OPT_BOOLEAN(0, "percore-show-thread", &stat_config.percore_show_thread, 12761af62ce6SJin Yao "Use with 'percore' event qualifier to show the event " 12771af62ce6SJin Yao "counts of one hardware thread by sum up total hardware " 12781af62ce6SJin Yao "threads of same physical core"), 1279ee6a9614SJin Yao OPT_BOOLEAN(0, "summary", &stat_config.summary, 1280ee6a9614SJin Yao "print summary for interval mode"), 12810bdad978SJin Yao OPT_BOOLEAN(0, "no-csv-summary", &stat_config.no_csv_summary, 12820bdad978SJin Yao "don't print 'summary' for CSV summary output"), 128355a4de94SAndi Kleen OPT_BOOLEAN(0, "quiet", &stat_config.quiet, 128455a4de94SAndi Kleen "don't print output (useful with record)"), 128570943490SStephane Eranian #ifdef HAVE_LIBPFM 128670943490SStephane Eranian OPT_CALLBACK(0, "pfm-events", &evsel_list, "event", 128770943490SStephane Eranian "libpfm4 event selector. use 'perf list' to list available events", 128870943490SStephane Eranian parse_libpfm_events_option), 128970943490SStephane Eranian #endif 1290a8fcbd26SAdrian Hunter OPT_CALLBACK(0, "control", &stat_config, "fd:ctl-fd[,ack-fd] or fifo:ctl-fifo[,ack-fifo]", 129127e9769aSAlexey Budankov "Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events).\n" 1292a8fcbd26SAdrian Hunter "\t\t\t Optionally send control command completion ('ack\\n') to ack-fd descriptor.\n" 1293a8fcbd26SAdrian Hunter "\t\t\t Alternatively, ctl-fifo / ack-fifo will be opened and used as ctl-fd / ack-fd.", 129427e9769aSAlexey Budankov parse_control_option), 1295f07952b1SAlexander Antonov OPT_CALLBACK_OPTARG(0, "iostat", &evsel_list, &stat_config, "default", 1296f07952b1SAlexander Antonov "measure I/O performance metrics provided by arch/platform", 1297f07952b1SAlexander Antonov iostat_parse), 1298e0547311SJiri Olsa OPT_END() 1299e0547311SJiri Olsa }; 1300e0547311SJiri Olsa 13012760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_socket(struct perf_stat_config *config __maybe_unused, 1302f854839bSJiri Olsa struct perf_cpu_map *map, int cpu) 13031fe7a300SJiri Olsa { 13041fe7a300SJiri Olsa return cpu_map__get_socket(map, cpu, NULL); 13051fe7a300SJiri Olsa } 13061fe7a300SJiri Olsa 13072760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_die(struct perf_stat_config *config __maybe_unused, 1308f854839bSJiri Olsa struct perf_cpu_map *map, int cpu) 1309db5742b6SKan Liang { 1310db5742b6SKan Liang return cpu_map__get_die(map, cpu, NULL); 1311db5742b6SKan Liang } 1312db5742b6SKan Liang 13132760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused, 1314f854839bSJiri Olsa struct perf_cpu_map *map, int cpu) 13151fe7a300SJiri Olsa { 13161fe7a300SJiri Olsa return cpu_map__get_core(map, cpu, NULL); 13171fe7a300SJiri Olsa } 13181fe7a300SJiri Olsa 13192760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_node(struct perf_stat_config *config __maybe_unused, 132086895b48SJiri Olsa struct perf_cpu_map *map, int cpu) 132186895b48SJiri Olsa { 132286895b48SJiri Olsa return cpu_map__get_node(map, cpu, NULL); 132386895b48SJiri Olsa } 132486895b48SJiri Olsa 13252760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config, 1326f854839bSJiri Olsa aggr_get_id_t get_id, struct perf_cpu_map *map, int idx) 13271e5a2931SJiri Olsa { 13281e5a2931SJiri Olsa int cpu; 13292760f5a1SJames Clark struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id(); 13301e5a2931SJiri Olsa 13311e5a2931SJiri Olsa if (idx >= map->nr) 13322760f5a1SJames Clark return id; 13331e5a2931SJiri Olsa 13341e5a2931SJiri Olsa cpu = map->map[idx]; 13351e5a2931SJiri Olsa 1336ff523295SJames Clark if (cpu_map__aggr_cpu_id_is_empty(config->cpus_aggr_map->map[cpu])) 1337ff523295SJames Clark config->cpus_aggr_map->map[cpu] = get_id(config, map, idx); 13381e5a2931SJiri Olsa 1339ff523295SJames Clark id = config->cpus_aggr_map->map[cpu]; 13402760f5a1SJames Clark return id; 13411e5a2931SJiri Olsa } 13421e5a2931SJiri Olsa 13432760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_socket_cached(struct perf_stat_config *config, 1344f854839bSJiri Olsa struct perf_cpu_map *map, int idx) 13451e5a2931SJiri Olsa { 13466f6b6594SJiri Olsa return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx); 13471e5a2931SJiri Olsa } 13481e5a2931SJiri Olsa 13492760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *config, 1350f854839bSJiri Olsa struct perf_cpu_map *map, int idx) 1351db5742b6SKan Liang { 1352db5742b6SKan Liang return perf_stat__get_aggr(config, perf_stat__get_die, map, idx); 1353db5742b6SKan Liang } 1354db5742b6SKan Liang 13552760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_core_cached(struct perf_stat_config *config, 1356f854839bSJiri Olsa struct perf_cpu_map *map, int idx) 13571e5a2931SJiri Olsa { 13586f6b6594SJiri Olsa return perf_stat__get_aggr(config, perf_stat__get_core, map, idx); 13591e5a2931SJiri Olsa } 13601e5a2931SJiri Olsa 13612760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_node_cached(struct perf_stat_config *config, 136286895b48SJiri Olsa struct perf_cpu_map *map, int idx) 136386895b48SJiri Olsa { 136486895b48SJiri Olsa return perf_stat__get_aggr(config, perf_stat__get_node, map, idx); 136586895b48SJiri Olsa } 136686895b48SJiri Olsa 13674fc4d8dfSJin Yao static bool term_percore_set(void) 13684fc4d8dfSJin Yao { 136932dcd021SJiri Olsa struct evsel *counter; 13704fc4d8dfSJin Yao 13714fc4d8dfSJin Yao evlist__for_each_entry(evsel_list, counter) { 13724fc4d8dfSJin Yao if (counter->percore) 13734fc4d8dfSJin Yao return true; 13744fc4d8dfSJin Yao } 13754fc4d8dfSJin Yao 13764fc4d8dfSJin Yao return false; 13774fc4d8dfSJin Yao } 13784fc4d8dfSJin Yao 137986ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void) 138086ee6e18SStephane Eranian { 13811e5a2931SJiri Olsa int nr; 13821e5a2931SJiri Olsa 1383421a50f3SJiri Olsa switch (stat_config.aggr_mode) { 138486ee6e18SStephane Eranian case AGGR_SOCKET: 1385f72f901dSJiri Olsa if (cpu_map__build_socket_map(evsel_list->core.cpus, &stat_config.aggr_map)) { 138686ee6e18SStephane Eranian perror("cannot build socket map"); 138786ee6e18SStephane Eranian return -1; 138886ee6e18SStephane Eranian } 13896f6b6594SJiri Olsa stat_config.aggr_get_id = perf_stat__get_socket_cached; 139086ee6e18SStephane Eranian break; 1391db5742b6SKan Liang case AGGR_DIE: 1392f72f901dSJiri Olsa if (cpu_map__build_die_map(evsel_list->core.cpus, &stat_config.aggr_map)) { 1393db5742b6SKan Liang perror("cannot build die map"); 1394db5742b6SKan Liang return -1; 1395db5742b6SKan Liang } 1396db5742b6SKan Liang stat_config.aggr_get_id = perf_stat__get_die_cached; 1397db5742b6SKan Liang break; 139812c08a9fSStephane Eranian case AGGR_CORE: 1399f72f901dSJiri Olsa if (cpu_map__build_core_map(evsel_list->core.cpus, &stat_config.aggr_map)) { 140012c08a9fSStephane Eranian perror("cannot build core map"); 140112c08a9fSStephane Eranian return -1; 140212c08a9fSStephane Eranian } 14036f6b6594SJiri Olsa stat_config.aggr_get_id = perf_stat__get_core_cached; 140412c08a9fSStephane Eranian break; 140586895b48SJiri Olsa case AGGR_NODE: 140686895b48SJiri Olsa if (cpu_map__build_node_map(evsel_list->core.cpus, &stat_config.aggr_map)) { 140786895b48SJiri Olsa perror("cannot build core map"); 140886895b48SJiri Olsa return -1; 140986895b48SJiri Olsa } 141086895b48SJiri Olsa stat_config.aggr_get_id = perf_stat__get_node_cached; 141186895b48SJiri Olsa break; 141286ee6e18SStephane Eranian case AGGR_NONE: 14134fc4d8dfSJin Yao if (term_percore_set()) { 1414f72f901dSJiri Olsa if (cpu_map__build_core_map(evsel_list->core.cpus, 14154fc4d8dfSJin Yao &stat_config.aggr_map)) { 14164fc4d8dfSJin Yao perror("cannot build core map"); 14174fc4d8dfSJin Yao return -1; 14184fc4d8dfSJin Yao } 14194fc4d8dfSJin Yao stat_config.aggr_get_id = perf_stat__get_core_cached; 14204fc4d8dfSJin Yao } 14214fc4d8dfSJin Yao break; 142286ee6e18SStephane Eranian case AGGR_GLOBAL: 142332b8af82SJiri Olsa case AGGR_THREAD: 1424208df99eSJiri Olsa case AGGR_UNSET: 142586ee6e18SStephane Eranian default: 142686ee6e18SStephane Eranian break; 142786ee6e18SStephane Eranian } 14281e5a2931SJiri Olsa 14291e5a2931SJiri Olsa /* 14301e5a2931SJiri Olsa * The evsel_list->cpus is the base we operate on, 14311e5a2931SJiri Olsa * taking the highest cpu number to be the size of 14321e5a2931SJiri Olsa * the aggregation translate cpumap. 14331e5a2931SJiri Olsa */ 14344256d434SJiri Olsa nr = perf_cpu_map__max(evsel_list->core.cpus); 1435d526e1a0SJames Clark stat_config.cpus_aggr_map = cpu_aggr_map__empty_new(nr + 1); 14366f6b6594SJiri Olsa return stat_config.cpus_aggr_map ? 0 : -ENOMEM; 143786ee6e18SStephane Eranian } 143886ee6e18SStephane Eranian 1439d526e1a0SJames Clark static void cpu_aggr_map__delete(struct cpu_aggr_map *map) 1440d526e1a0SJames Clark { 1441d526e1a0SJames Clark if (map) { 1442d526e1a0SJames Clark WARN_ONCE(refcount_read(&map->refcnt) != 0, 1443d526e1a0SJames Clark "cpu_aggr_map refcnt unbalanced\n"); 1444d526e1a0SJames Clark free(map); 1445d526e1a0SJames Clark } 1446d526e1a0SJames Clark } 1447d526e1a0SJames Clark 1448d526e1a0SJames Clark static void cpu_aggr_map__put(struct cpu_aggr_map *map) 1449d526e1a0SJames Clark { 1450d526e1a0SJames Clark if (map && refcount_dec_and_test(&map->refcnt)) 1451d526e1a0SJames Clark cpu_aggr_map__delete(map); 1452d526e1a0SJames Clark } 1453d526e1a0SJames Clark 1454544c2ae7SMasami Hiramatsu static void perf_stat__exit_aggr_mode(void) 1455544c2ae7SMasami Hiramatsu { 1456d526e1a0SJames Clark cpu_aggr_map__put(stat_config.aggr_map); 1457d526e1a0SJames Clark cpu_aggr_map__put(stat_config.cpus_aggr_map); 14586f6b6594SJiri Olsa stat_config.aggr_map = NULL; 14596f6b6594SJiri Olsa stat_config.cpus_aggr_map = NULL; 1460544c2ae7SMasami Hiramatsu } 1461544c2ae7SMasami Hiramatsu 1462f854839bSJiri Olsa static inline int perf_env__get_cpu(struct perf_env *env, struct perf_cpu_map *map, int idx) 146368d702f7SJiri Olsa { 146468d702f7SJiri Olsa int cpu; 146568d702f7SJiri Olsa 146668d702f7SJiri Olsa if (idx > map->nr) 146768d702f7SJiri Olsa return -1; 146868d702f7SJiri Olsa 146968d702f7SJiri Olsa cpu = map->map[idx]; 147068d702f7SJiri Olsa 1471da8a58b5SJan Stancek if (cpu >= env->nr_cpus_avail) 147268d702f7SJiri Olsa return -1; 147368d702f7SJiri Olsa 147468d702f7SJiri Olsa return cpu; 147568d702f7SJiri Olsa } 147668d702f7SJiri Olsa 14772760f5a1SJames Clark static struct aggr_cpu_id perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data) 147868d702f7SJiri Olsa { 147968d702f7SJiri Olsa struct perf_env *env = data; 148068d702f7SJiri Olsa int cpu = perf_env__get_cpu(env, map, idx); 14812760f5a1SJames Clark struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id(); 148268d702f7SJiri Olsa 14832760f5a1SJames Clark if (cpu != -1) 14841a270cb6SJames Clark id.socket = env->cpu[cpu].socket_id; 14852760f5a1SJames Clark 14862760f5a1SJames Clark return id; 148768d702f7SJiri Olsa } 148868d702f7SJiri Olsa 14892760f5a1SJames Clark static struct aggr_cpu_id perf_env__get_die(struct perf_cpu_map *map, int idx, void *data) 1490db5742b6SKan Liang { 1491db5742b6SKan Liang struct perf_env *env = data; 14922760f5a1SJames Clark struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id(); 14932760f5a1SJames Clark int cpu = perf_env__get_cpu(env, map, idx); 1494db5742b6SKan Liang 1495db5742b6SKan Liang if (cpu != -1) { 1496db5742b6SKan Liang /* 14971a270cb6SJames Clark * die_id is relative to socket, so start 14981a270cb6SJames Clark * with the socket ID and then add die to 14991a270cb6SJames Clark * make a unique ID. 1500db5742b6SKan Liang */ 15011a270cb6SJames Clark id.socket = env->cpu[cpu].socket_id; 1502ba2ee166SJames Clark id.die = env->cpu[cpu].die_id; 1503db5742b6SKan Liang } 1504db5742b6SKan Liang 15052760f5a1SJames Clark return id; 1506db5742b6SKan Liang } 1507db5742b6SKan Liang 15082760f5a1SJames Clark static struct aggr_cpu_id perf_env__get_core(struct perf_cpu_map *map, int idx, void *data) 150968d702f7SJiri Olsa { 151068d702f7SJiri Olsa struct perf_env *env = data; 15112760f5a1SJames Clark struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id(); 15122760f5a1SJames Clark int cpu = perf_env__get_cpu(env, map, idx); 151368d702f7SJiri Olsa 151468d702f7SJiri Olsa if (cpu != -1) { 151568d702f7SJiri Olsa /* 1516db5742b6SKan Liang * core_id is relative to socket and die, 1517b9933817SJames Clark * we need a global id. So we set 1518b9933817SJames Clark * socket, die id and core id 151968d702f7SJiri Olsa */ 15201a270cb6SJames Clark id.socket = env->cpu[cpu].socket_id; 1521ba2ee166SJames Clark id.die = env->cpu[cpu].die_id; 1522b9933817SJames Clark id.core = env->cpu[cpu].core_id; 152368d702f7SJiri Olsa } 152468d702f7SJiri Olsa 15252760f5a1SJames Clark return id; 152668d702f7SJiri Olsa } 152768d702f7SJiri Olsa 15282760f5a1SJames Clark static struct aggr_cpu_id perf_env__get_node(struct perf_cpu_map *map, int idx, void *data) 152986895b48SJiri Olsa { 153086895b48SJiri Olsa int cpu = perf_env__get_cpu(data, map, idx); 15312760f5a1SJames Clark struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id(); 153286895b48SJiri Olsa 1533fcd83a35SJames Clark id.node = perf_env__numa_node(data, cpu); 15342760f5a1SJames Clark return id; 153586895b48SJiri Olsa } 153686895b48SJiri Olsa 1537f854839bSJiri Olsa static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus, 1538d526e1a0SJames Clark struct cpu_aggr_map **sockp) 153968d702f7SJiri Olsa { 154068d702f7SJiri Olsa return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env); 154168d702f7SJiri Olsa } 154268d702f7SJiri Olsa 1543f854839bSJiri Olsa static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus, 1544d526e1a0SJames Clark struct cpu_aggr_map **diep) 1545db5742b6SKan Liang { 1546db5742b6SKan Liang return cpu_map__build_map(cpus, diep, perf_env__get_die, env); 1547db5742b6SKan Liang } 1548db5742b6SKan Liang 1549f854839bSJiri Olsa static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus, 1550d526e1a0SJames Clark struct cpu_aggr_map **corep) 155168d702f7SJiri Olsa { 155268d702f7SJiri Olsa return cpu_map__build_map(cpus, corep, perf_env__get_core, env); 155368d702f7SJiri Olsa } 155468d702f7SJiri Olsa 155586895b48SJiri Olsa static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *cpus, 1556d526e1a0SJames Clark struct cpu_aggr_map **nodep) 155786895b48SJiri Olsa { 155886895b48SJiri Olsa return cpu_map__build_map(cpus, nodep, perf_env__get_node, env); 155986895b48SJiri Olsa } 156086895b48SJiri Olsa 15612760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused, 1562f854839bSJiri Olsa struct perf_cpu_map *map, int idx) 156368d702f7SJiri Olsa { 156468d702f7SJiri Olsa return perf_env__get_socket(map, idx, &perf_stat.session->header.env); 156568d702f7SJiri Olsa } 15662760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused, 1567f854839bSJiri Olsa struct perf_cpu_map *map, int idx) 1568db5742b6SKan Liang { 1569db5742b6SKan Liang return perf_env__get_die(map, idx, &perf_stat.session->header.env); 1570db5742b6SKan Liang } 157168d702f7SJiri Olsa 15722760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused, 1573f854839bSJiri Olsa struct perf_cpu_map *map, int idx) 157468d702f7SJiri Olsa { 157568d702f7SJiri Olsa return perf_env__get_core(map, idx, &perf_stat.session->header.env); 157668d702f7SJiri Olsa } 157768d702f7SJiri Olsa 15782760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_node_file(struct perf_stat_config *config __maybe_unused, 157986895b48SJiri Olsa struct perf_cpu_map *map, int idx) 158086895b48SJiri Olsa { 158186895b48SJiri Olsa return perf_env__get_node(map, idx, &perf_stat.session->header.env); 158286895b48SJiri Olsa } 158386895b48SJiri Olsa 158468d702f7SJiri Olsa static int perf_stat_init_aggr_mode_file(struct perf_stat *st) 158568d702f7SJiri Olsa { 158668d702f7SJiri Olsa struct perf_env *env = &st->session->header.env; 158768d702f7SJiri Olsa 158868d702f7SJiri Olsa switch (stat_config.aggr_mode) { 158968d702f7SJiri Olsa case AGGR_SOCKET: 1590f72f901dSJiri Olsa if (perf_env__build_socket_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) { 159168d702f7SJiri Olsa perror("cannot build socket map"); 159268d702f7SJiri Olsa return -1; 159368d702f7SJiri Olsa } 15946f6b6594SJiri Olsa stat_config.aggr_get_id = perf_stat__get_socket_file; 159568d702f7SJiri Olsa break; 1596db5742b6SKan Liang case AGGR_DIE: 1597f72f901dSJiri Olsa if (perf_env__build_die_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) { 1598db5742b6SKan Liang perror("cannot build die map"); 1599db5742b6SKan Liang return -1; 1600db5742b6SKan Liang } 1601db5742b6SKan Liang stat_config.aggr_get_id = perf_stat__get_die_file; 1602db5742b6SKan Liang break; 160368d702f7SJiri Olsa case AGGR_CORE: 1604f72f901dSJiri Olsa if (perf_env__build_core_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) { 160568d702f7SJiri Olsa perror("cannot build core map"); 160668d702f7SJiri Olsa return -1; 160768d702f7SJiri Olsa } 16086f6b6594SJiri Olsa stat_config.aggr_get_id = perf_stat__get_core_file; 160968d702f7SJiri Olsa break; 161086895b48SJiri Olsa case AGGR_NODE: 161186895b48SJiri Olsa if (perf_env__build_node_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) { 161286895b48SJiri Olsa perror("cannot build core map"); 161386895b48SJiri Olsa return -1; 161486895b48SJiri Olsa } 161586895b48SJiri Olsa stat_config.aggr_get_id = perf_stat__get_node_file; 161686895b48SJiri Olsa break; 161768d702f7SJiri Olsa case AGGR_NONE: 161868d702f7SJiri Olsa case AGGR_GLOBAL: 161968d702f7SJiri Olsa case AGGR_THREAD: 162068d702f7SJiri Olsa case AGGR_UNSET: 162168d702f7SJiri Olsa default: 162268d702f7SJiri Olsa break; 162368d702f7SJiri Olsa } 162468d702f7SJiri Olsa 162568d702f7SJiri Olsa return 0; 162668d702f7SJiri Olsa } 162768d702f7SJiri Olsa 16282cba3ffbSIngo Molnar /* 16292cba3ffbSIngo Molnar * Add default attributes, if there were no attributes specified or 16302cba3ffbSIngo Molnar * if -d/--detailed, -d -d or -d -d -d is used: 16312cba3ffbSIngo Molnar */ 16322cba3ffbSIngo Molnar static int add_default_attributes(void) 16332cba3ffbSIngo Molnar { 163444b1e60aSAndi Kleen int err; 16359dec4473SAndi Kleen struct perf_event_attr default_attrs0[] = { 1636b070a547SArnaldo Carvalho de Melo 1637b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 1638b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 1639b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 1640b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 1641b070a547SArnaldo Carvalho de Melo 1642b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 16439dec4473SAndi Kleen }; 16449dec4473SAndi Kleen struct perf_event_attr frontend_attrs[] = { 1645b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 16469dec4473SAndi Kleen }; 16479dec4473SAndi Kleen struct perf_event_attr backend_attrs[] = { 1648b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 16499dec4473SAndi Kleen }; 16509dec4473SAndi Kleen struct perf_event_attr default_attrs1[] = { 1651b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 1652b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 1653b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 1654b070a547SArnaldo Carvalho de Melo 1655b070a547SArnaldo Carvalho de Melo }; 1656ac2dc29eSJin Yao struct perf_event_attr default_sw_attrs[] = { 1657ac2dc29eSJin Yao { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 1658ac2dc29eSJin Yao { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 1659ac2dc29eSJin Yao { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 1660ac2dc29eSJin Yao { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 1661ac2dc29eSJin Yao }; 1662b070a547SArnaldo Carvalho de Melo 1663b070a547SArnaldo Carvalho de Melo /* 1664b070a547SArnaldo Carvalho de Melo * Detailed stats (-d), covering the L1 and last level data caches: 1665b070a547SArnaldo Carvalho de Melo */ 1666b070a547SArnaldo Carvalho de Melo struct perf_event_attr detailed_attrs[] = { 1667b070a547SArnaldo Carvalho de Melo 1668b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1669b070a547SArnaldo Carvalho de Melo .config = 1670b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1671b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1672b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1673b070a547SArnaldo Carvalho de Melo 1674b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1675b070a547SArnaldo Carvalho de Melo .config = 1676b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1677b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1678b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1679b070a547SArnaldo Carvalho de Melo 1680b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1681b070a547SArnaldo Carvalho de Melo .config = 1682b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1683b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1684b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1685b070a547SArnaldo Carvalho de Melo 1686b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1687b070a547SArnaldo Carvalho de Melo .config = 1688b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1689b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1690b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1691b070a547SArnaldo Carvalho de Melo }; 1692b070a547SArnaldo Carvalho de Melo 1693b070a547SArnaldo Carvalho de Melo /* 1694b070a547SArnaldo Carvalho de Melo * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: 1695b070a547SArnaldo Carvalho de Melo */ 1696b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_detailed_attrs[] = { 1697b070a547SArnaldo Carvalho de Melo 1698b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1699b070a547SArnaldo Carvalho de Melo .config = 1700b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1701b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1702b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1703b070a547SArnaldo Carvalho de Melo 1704b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1705b070a547SArnaldo Carvalho de Melo .config = 1706b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1707b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1708b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1709b070a547SArnaldo Carvalho de Melo 1710b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1711b070a547SArnaldo Carvalho de Melo .config = 1712b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1713b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1714b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1715b070a547SArnaldo Carvalho de Melo 1716b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1717b070a547SArnaldo Carvalho de Melo .config = 1718b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1719b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1720b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1721b070a547SArnaldo Carvalho de Melo 1722b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1723b070a547SArnaldo Carvalho de Melo .config = 1724b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1725b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1726b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1727b070a547SArnaldo Carvalho de Melo 1728b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1729b070a547SArnaldo Carvalho de Melo .config = 1730b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1731b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1732b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1733b070a547SArnaldo Carvalho de Melo 1734b070a547SArnaldo Carvalho de Melo }; 1735b070a547SArnaldo Carvalho de Melo 1736b070a547SArnaldo Carvalho de Melo /* 1737b070a547SArnaldo Carvalho de Melo * Very, very detailed stats (-d -d -d), adding prefetch events: 1738b070a547SArnaldo Carvalho de Melo */ 1739b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_very_detailed_attrs[] = { 1740b070a547SArnaldo Carvalho de Melo 1741b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1742b070a547SArnaldo Carvalho de Melo .config = 1743b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1744b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1745b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1746b070a547SArnaldo Carvalho de Melo 1747b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1748b070a547SArnaldo Carvalho de Melo .config = 1749b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1750b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1751b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1752b070a547SArnaldo Carvalho de Melo }; 1753a5cfa621SJiri Olsa struct parse_events_error errinfo; 1754b070a547SArnaldo Carvalho de Melo 17552cba3ffbSIngo Molnar /* Set attrs if no event is selected and !null_run: */ 1756aea0dca1SJiri Olsa if (stat_config.null_run) 17572cba3ffbSIngo Molnar return 0; 17582cba3ffbSIngo Molnar 1759a910e466SIan Rogers bzero(&errinfo, sizeof(errinfo)); 17604cabc3d1SAndi Kleen if (transaction_run) { 1761742d92ffSThomas Richter /* Handle -T as -M transaction. Once platform specific metrics 17624d39c89fSIngo Molnar * support has been added to the json files, all architectures 1763742d92ffSThomas Richter * will use this approach. To determine transaction support 1764742d92ffSThomas Richter * on an architecture test for such a metric name. 1765742d92ffSThomas Richter */ 1766742d92ffSThomas Richter if (metricgroup__has_metric("transaction")) { 1767742d92ffSThomas Richter struct option opt = { .value = &evsel_list }; 1768742d92ffSThomas Richter 1769742d92ffSThomas Richter return metricgroup__parse_groups(&opt, "transaction", 177005530a79SIan Rogers stat_config.metric_no_group, 177105530a79SIan Rogers stat_config.metric_no_merge, 1772d0192fdbSJiri Olsa &stat_config.metric_events); 1773742d92ffSThomas Richter } 1774742d92ffSThomas Richter 17754cabc3d1SAndi Kleen if (pmu_have_event("cpu", "cycles-ct") && 17764cabc3d1SAndi Kleen pmu_have_event("cpu", "el-start")) 1777fca32340SThomas Richter err = parse_events(evsel_list, transaction_attrs, 1778fca32340SThomas Richter &errinfo); 17794cabc3d1SAndi Kleen else 1780fca32340SThomas Richter err = parse_events(evsel_list, 1781fca32340SThomas Richter transaction_limited_attrs, 1782fca32340SThomas Richter &errinfo); 1783a454742cSJiri Olsa if (err) { 17844cabc3d1SAndi Kleen fprintf(stderr, "Cannot set up transaction events\n"); 1785a5cfa621SJiri Olsa parse_events_print_error(&errinfo, transaction_attrs); 17864cabc3d1SAndi Kleen return -1; 17874cabc3d1SAndi Kleen } 17884cabc3d1SAndi Kleen return 0; 17894cabc3d1SAndi Kleen } 17904cabc3d1SAndi Kleen 1791daefd0bcSKan Liang if (smi_cost) { 1792daefd0bcSKan Liang int smi; 1793daefd0bcSKan Liang 1794daefd0bcSKan Liang if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) { 1795daefd0bcSKan Liang fprintf(stderr, "freeze_on_smi is not supported.\n"); 1796daefd0bcSKan Liang return -1; 1797daefd0bcSKan Liang } 1798daefd0bcSKan Liang 1799daefd0bcSKan Liang if (!smi) { 1800daefd0bcSKan Liang if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) { 1801daefd0bcSKan Liang fprintf(stderr, "Failed to set freeze_on_smi.\n"); 1802daefd0bcSKan Liang return -1; 1803daefd0bcSKan Liang } 1804daefd0bcSKan Liang smi_reset = true; 1805daefd0bcSKan Liang } 1806daefd0bcSKan Liang 1807daefd0bcSKan Liang if (pmu_have_event("msr", "aperf") && 1808daefd0bcSKan Liang pmu_have_event("msr", "smi")) { 1809daefd0bcSKan Liang if (!force_metric_only) 18100ce5aa02SJiri Olsa stat_config.metric_only = true; 1811a5cfa621SJiri Olsa err = parse_events(evsel_list, smi_cost_attrs, &errinfo); 1812daefd0bcSKan Liang } else { 1813daefd0bcSKan Liang fprintf(stderr, "To measure SMI cost, it needs " 1814daefd0bcSKan Liang "msr/aperf/, msr/smi/ and cpu/cycles/ support\n"); 1815a5cfa621SJiri Olsa parse_events_print_error(&errinfo, smi_cost_attrs); 1816daefd0bcSKan Liang return -1; 1817daefd0bcSKan Liang } 1818daefd0bcSKan Liang if (err) { 1819a910e466SIan Rogers parse_events_print_error(&errinfo, smi_cost_attrs); 1820daefd0bcSKan Liang fprintf(stderr, "Cannot set up SMI cost events\n"); 1821daefd0bcSKan Liang return -1; 1822daefd0bcSKan Liang } 1823daefd0bcSKan Liang return 0; 1824daefd0bcSKan Liang } 1825daefd0bcSKan Liang 182644b1e60aSAndi Kleen if (topdown_run) { 182763e39aa6SKan Liang const char **metric_attrs = topdown_metric_attrs; 182863e39aa6SKan Liang unsigned int max_level = 1; 182944b1e60aSAndi Kleen char *str = NULL; 183044b1e60aSAndi Kleen bool warn = false; 183144b1e60aSAndi Kleen 183255c36a9fSAndi Kleen if (!force_metric_only) 183355c36a9fSAndi Kleen stat_config.metric_only = true; 183455c36a9fSAndi Kleen 183563e39aa6SKan Liang if (pmu_have_event("cpu", topdown_metric_L2_attrs[5])) { 183663e39aa6SKan Liang metric_attrs = topdown_metric_L2_attrs; 183763e39aa6SKan Liang max_level = 2; 183863e39aa6SKan Liang } 183963e39aa6SKan Liang 184063e39aa6SKan Liang if (stat_config.topdown_level > max_level) { 184163e39aa6SKan Liang pr_err("Invalid top-down metrics level. The max level is %u.\n", max_level); 184263e39aa6SKan Liang return -1; 184363e39aa6SKan Liang } else if (!stat_config.topdown_level) 184463e39aa6SKan Liang stat_config.topdown_level = max_level; 184563e39aa6SKan Liang 184663e39aa6SKan Liang if (topdown_filter_events(metric_attrs, &str, 1) < 0) { 184755c36a9fSAndi Kleen pr_err("Out of memory\n"); 184855c36a9fSAndi Kleen return -1; 184955c36a9fSAndi Kleen } 185063e39aa6SKan Liang if (metric_attrs[0] && str) { 185155c36a9fSAndi Kleen if (!stat_config.interval && !stat_config.metric_only) { 185255c36a9fSAndi Kleen fprintf(stat_config.output, 185355c36a9fSAndi Kleen "Topdown accuracy may decrease when measuring long periods.\n" 185455c36a9fSAndi Kleen "Please print the result regularly, e.g. -I1000\n"); 185555c36a9fSAndi Kleen } 185655c36a9fSAndi Kleen goto setup_metrics; 185755c36a9fSAndi Kleen } 185855c36a9fSAndi Kleen 185955c36a9fSAndi Kleen zfree(&str); 186055c36a9fSAndi Kleen 186144b1e60aSAndi Kleen if (stat_config.aggr_mode != AGGR_GLOBAL && 186244b1e60aSAndi Kleen stat_config.aggr_mode != AGGR_CORE) { 186344b1e60aSAndi Kleen pr_err("top down event configuration requires --per-core mode\n"); 186444b1e60aSAndi Kleen return -1; 186544b1e60aSAndi Kleen } 186644b1e60aSAndi Kleen stat_config.aggr_mode = AGGR_CORE; 186744b1e60aSAndi Kleen if (nr_cgroups || !target__has_cpu(&target)) { 186844b1e60aSAndi Kleen pr_err("top down event configuration requires system-wide mode (-a)\n"); 186944b1e60aSAndi Kleen return -1; 187044b1e60aSAndi Kleen } 187144b1e60aSAndi Kleen 187244b1e60aSAndi Kleen if (topdown_filter_events(topdown_attrs, &str, 187344b1e60aSAndi Kleen arch_topdown_check_group(&warn)) < 0) { 187444b1e60aSAndi Kleen pr_err("Out of memory\n"); 187544b1e60aSAndi Kleen return -1; 187644b1e60aSAndi Kleen } 187744b1e60aSAndi Kleen if (topdown_attrs[0] && str) { 187844b1e60aSAndi Kleen if (warn) 187944b1e60aSAndi Kleen arch_topdown_group_warn(); 188055c36a9fSAndi Kleen setup_metrics: 1881a5cfa621SJiri Olsa err = parse_events(evsel_list, str, &errinfo); 188244b1e60aSAndi Kleen if (err) { 188344b1e60aSAndi Kleen fprintf(stderr, 188444b1e60aSAndi Kleen "Cannot set up top down events %s: %d\n", 188544b1e60aSAndi Kleen str, err); 1886a5cfa621SJiri Olsa parse_events_print_error(&errinfo, str); 1887c74b0503SLeo Yan free(str); 188844b1e60aSAndi Kleen return -1; 188944b1e60aSAndi Kleen } 189044b1e60aSAndi Kleen } else { 189144b1e60aSAndi Kleen fprintf(stderr, "System does not support topdown\n"); 189244b1e60aSAndi Kleen return -1; 189344b1e60aSAndi Kleen } 189444b1e60aSAndi Kleen free(str); 189544b1e60aSAndi Kleen } 189644b1e60aSAndi Kleen 18976484d2f9SJiri Olsa if (!evsel_list->core.nr_entries) { 1898ac2dc29eSJin Yao if (perf_pmu__has_hybrid()) { 1899ac2dc29eSJin Yao const char *hybrid_str = "cycles,instructions,branches,branch-misses"; 1900ac2dc29eSJin Yao 1901ac2dc29eSJin Yao if (target__has_cpu(&target)) 1902ac2dc29eSJin Yao default_sw_attrs[0].config = PERF_COUNT_SW_CPU_CLOCK; 1903ac2dc29eSJin Yao 1904ac2dc29eSJin Yao if (evlist__add_default_attrs(evsel_list, 1905ac2dc29eSJin Yao default_sw_attrs) < 0) { 1906ac2dc29eSJin Yao return -1; 1907ac2dc29eSJin Yao } 1908ac2dc29eSJin Yao 1909ac2dc29eSJin Yao err = parse_events(evsel_list, hybrid_str, &errinfo); 1910ac2dc29eSJin Yao if (err) { 1911ac2dc29eSJin Yao fprintf(stderr, 1912ac2dc29eSJin Yao "Cannot set up hybrid events %s: %d\n", 1913ac2dc29eSJin Yao hybrid_str, err); 1914ac2dc29eSJin Yao parse_events_print_error(&errinfo, hybrid_str); 1915ac2dc29eSJin Yao return -1; 1916ac2dc29eSJin Yao } 1917ac2dc29eSJin Yao return err; 1918ac2dc29eSJin Yao } 1919ac2dc29eSJin Yao 1920a1f3d567SNamhyung Kim if (target__has_cpu(&target)) 1921a1f3d567SNamhyung Kim default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK; 1922a1f3d567SNamhyung Kim 1923e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, default_attrs0) < 0) 19249dec4473SAndi Kleen return -1; 19259dec4473SAndi Kleen if (pmu_have_event("cpu", "stalled-cycles-frontend")) { 1926e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, frontend_attrs) < 0) 19279dec4473SAndi Kleen return -1; 19289dec4473SAndi Kleen } 19299dec4473SAndi Kleen if (pmu_have_event("cpu", "stalled-cycles-backend")) { 1930e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, backend_attrs) < 0) 19319dec4473SAndi Kleen return -1; 19329dec4473SAndi Kleen } 1933e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, default_attrs1) < 0) 19342cba3ffbSIngo Molnar return -1; 193542641d6fSKan Liang 19365f148e7cSKan Liang stat_config.topdown_level = TOPDOWN_MAX_LEVEL; 193742641d6fSKan Liang if (arch_evlist__add_default_attrs(evsel_list) < 0) 193842641d6fSKan Liang return -1; 19392cba3ffbSIngo Molnar } 19402cba3ffbSIngo Molnar 19412cba3ffbSIngo Molnar /* Detailed events get appended to the event list: */ 19422cba3ffbSIngo Molnar 19432cba3ffbSIngo Molnar if (detailed_run < 1) 19442cba3ffbSIngo Molnar return 0; 19452cba3ffbSIngo Molnar 19462cba3ffbSIngo Molnar /* Append detailed run extra attributes: */ 1947e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) 19482cba3ffbSIngo Molnar return -1; 19492cba3ffbSIngo Molnar 19502cba3ffbSIngo Molnar if (detailed_run < 2) 19512cba3ffbSIngo Molnar return 0; 19522cba3ffbSIngo Molnar 19532cba3ffbSIngo Molnar /* Append very detailed run extra attributes: */ 1954e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) 19552cba3ffbSIngo Molnar return -1; 19562cba3ffbSIngo Molnar 19572cba3ffbSIngo Molnar if (detailed_run < 3) 19582cba3ffbSIngo Molnar return 0; 19592cba3ffbSIngo Molnar 19602cba3ffbSIngo Molnar /* Append very, very detailed run extra attributes: */ 1961e251abeeSArnaldo Carvalho de Melo return evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); 19622cba3ffbSIngo Molnar } 19632cba3ffbSIngo Molnar 19648a59f3ccSJiri Olsa static const char * const stat_record_usage[] = { 19654979d0c7SJiri Olsa "perf stat record [<options>]", 19664979d0c7SJiri Olsa NULL, 19674979d0c7SJiri Olsa }; 19684979d0c7SJiri Olsa 19693ba78bd0SJiri Olsa static void init_features(struct perf_session *session) 19703ba78bd0SJiri Olsa { 19713ba78bd0SJiri Olsa int feat; 19723ba78bd0SJiri Olsa 19733ba78bd0SJiri Olsa for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) 19743ba78bd0SJiri Olsa perf_header__set_feat(&session->header, feat); 19753ba78bd0SJiri Olsa 19768002a63fSJiri Olsa perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT); 19773ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_BUILD_ID); 19783ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); 19793ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 19803ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_AUXTRACE); 19813ba78bd0SJiri Olsa } 19823ba78bd0SJiri Olsa 19834979d0c7SJiri Olsa static int __cmd_record(int argc, const char **argv) 19844979d0c7SJiri Olsa { 19854979d0c7SJiri Olsa struct perf_session *session; 19868ceb41d7SJiri Olsa struct perf_data *data = &perf_stat.data; 19874979d0c7SJiri Olsa 19888a59f3ccSJiri Olsa argc = parse_options(argc, argv, stat_options, stat_record_usage, 19894979d0c7SJiri Olsa PARSE_OPT_STOP_AT_NON_OPTION); 19904979d0c7SJiri Olsa 19914979d0c7SJiri Olsa if (output_name) 19922d4f2799SJiri Olsa data->path = output_name; 19934979d0c7SJiri Olsa 1994d97ae04bSJiri Olsa if (stat_config.run_count != 1 || forever) { 1995e9d6db8eSJiri Olsa pr_err("Cannot use -r option with perf stat record.\n"); 1996e9d6db8eSJiri Olsa return -1; 1997e9d6db8eSJiri Olsa } 1998e9d6db8eSJiri Olsa 19992681bd85SNamhyung Kim session = perf_session__new(data, NULL); 20006ef81c55SMamatha Inamdar if (IS_ERR(session)) { 20016ef81c55SMamatha Inamdar pr_err("Perf session creation failed\n"); 20026ef81c55SMamatha Inamdar return PTR_ERR(session); 20034979d0c7SJiri Olsa } 20044979d0c7SJiri Olsa 20053ba78bd0SJiri Olsa init_features(session); 20063ba78bd0SJiri Olsa 20074979d0c7SJiri Olsa session->evlist = evsel_list; 20084979d0c7SJiri Olsa perf_stat.session = session; 20094979d0c7SJiri Olsa perf_stat.record = true; 20104979d0c7SJiri Olsa return argc; 20114979d0c7SJiri Olsa } 20124979d0c7SJiri Olsa 201389f1688aSJiri Olsa static int process_stat_round_event(struct perf_session *session, 201489f1688aSJiri Olsa union perf_event *event) 2015a56f9390SJiri Olsa { 201672932371SJiri Olsa struct perf_record_stat_round *stat_round = &event->stat_round; 201732dcd021SJiri Olsa struct evsel *counter; 2018a56f9390SJiri Olsa struct timespec tsh, *ts = NULL; 2019a56f9390SJiri Olsa const char **argv = session->header.env.cmdline_argv; 2020a56f9390SJiri Olsa int argc = session->header.env.nr_cmdline; 2021a56f9390SJiri Olsa 2022e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evsel_list, counter) 2023a56f9390SJiri Olsa perf_stat_process_counter(&stat_config, counter); 2024a56f9390SJiri Olsa 2025e3b03b6cSAndi Kleen if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL) 2026e3b03b6cSAndi Kleen update_stats(&walltime_nsecs_stats, stat_round->time); 2027a56f9390SJiri Olsa 2028e3b03b6cSAndi Kleen if (stat_config.interval && stat_round->time) { 2029bd48c63eSArnaldo Carvalho de Melo tsh.tv_sec = stat_round->time / NSEC_PER_SEC; 2030bd48c63eSArnaldo Carvalho de Melo tsh.tv_nsec = stat_round->time % NSEC_PER_SEC; 2031a56f9390SJiri Olsa ts = &tsh; 2032a56f9390SJiri Olsa } 2033a56f9390SJiri Olsa 2034a56f9390SJiri Olsa print_counters(ts, argc, argv); 2035a56f9390SJiri Olsa return 0; 2036a56f9390SJiri Olsa } 2037a56f9390SJiri Olsa 203862ba18baSJiri Olsa static 203989f1688aSJiri Olsa int process_stat_config_event(struct perf_session *session, 204089f1688aSJiri Olsa union perf_event *event) 204162ba18baSJiri Olsa { 204289f1688aSJiri Olsa struct perf_tool *tool = session->tool; 204368d702f7SJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 204468d702f7SJiri Olsa 204562ba18baSJiri Olsa perf_event__read_stat_config(&stat_config, &event->stat_config); 204668d702f7SJiri Olsa 2047315c0a1fSJiri Olsa if (perf_cpu_map__empty(st->cpus)) { 204889af4e05SJiri Olsa if (st->aggr_mode != AGGR_UNSET) 204989af4e05SJiri Olsa pr_warning("warning: processing task data, aggregation mode not set\n"); 205089af4e05SJiri Olsa return 0; 205189af4e05SJiri Olsa } 205289af4e05SJiri Olsa 205389af4e05SJiri Olsa if (st->aggr_mode != AGGR_UNSET) 205489af4e05SJiri Olsa stat_config.aggr_mode = st->aggr_mode; 205589af4e05SJiri Olsa 20568ceb41d7SJiri Olsa if (perf_stat.data.is_pipe) 205768d702f7SJiri Olsa perf_stat_init_aggr_mode(); 205868d702f7SJiri Olsa else 205968d702f7SJiri Olsa perf_stat_init_aggr_mode_file(st); 206068d702f7SJiri Olsa 206162ba18baSJiri Olsa return 0; 206262ba18baSJiri Olsa } 206362ba18baSJiri Olsa 20641975d36eSJiri Olsa static int set_maps(struct perf_stat *st) 20651975d36eSJiri Olsa { 20661975d36eSJiri Olsa if (!st->cpus || !st->threads) 20671975d36eSJiri Olsa return 0; 20681975d36eSJiri Olsa 20691975d36eSJiri Olsa if (WARN_ONCE(st->maps_allocated, "stats double allocation\n")) 20701975d36eSJiri Olsa return -EINVAL; 20711975d36eSJiri Olsa 2072453fa030SJiri Olsa perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads); 20731975d36eSJiri Olsa 207453f5e908SArnaldo Carvalho de Melo if (evlist__alloc_stats(evsel_list, true)) 20751975d36eSJiri Olsa return -ENOMEM; 20761975d36eSJiri Olsa 20771975d36eSJiri Olsa st->maps_allocated = true; 20781975d36eSJiri Olsa return 0; 20791975d36eSJiri Olsa } 20801975d36eSJiri Olsa 20811975d36eSJiri Olsa static 208289f1688aSJiri Olsa int process_thread_map_event(struct perf_session *session, 208389f1688aSJiri Olsa union perf_event *event) 20841975d36eSJiri Olsa { 208589f1688aSJiri Olsa struct perf_tool *tool = session->tool; 20861975d36eSJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 20871975d36eSJiri Olsa 20881975d36eSJiri Olsa if (st->threads) { 20891975d36eSJiri Olsa pr_warning("Extra thread map event, ignoring.\n"); 20901975d36eSJiri Olsa return 0; 20911975d36eSJiri Olsa } 20921975d36eSJiri Olsa 20931975d36eSJiri Olsa st->threads = thread_map__new_event(&event->thread_map); 20941975d36eSJiri Olsa if (!st->threads) 20951975d36eSJiri Olsa return -ENOMEM; 20961975d36eSJiri Olsa 20971975d36eSJiri Olsa return set_maps(st); 20981975d36eSJiri Olsa } 20991975d36eSJiri Olsa 21001975d36eSJiri Olsa static 210189f1688aSJiri Olsa int process_cpu_map_event(struct perf_session *session, 210289f1688aSJiri Olsa union perf_event *event) 21031975d36eSJiri Olsa { 210489f1688aSJiri Olsa struct perf_tool *tool = session->tool; 21051975d36eSJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 2106f854839bSJiri Olsa struct perf_cpu_map *cpus; 21071975d36eSJiri Olsa 21081975d36eSJiri Olsa if (st->cpus) { 21091975d36eSJiri Olsa pr_warning("Extra cpu map event, ignoring.\n"); 21101975d36eSJiri Olsa return 0; 21111975d36eSJiri Olsa } 21121975d36eSJiri Olsa 21131975d36eSJiri Olsa cpus = cpu_map__new_data(&event->cpu_map.data); 21141975d36eSJiri Olsa if (!cpus) 21151975d36eSJiri Olsa return -ENOMEM; 21161975d36eSJiri Olsa 21171975d36eSJiri Olsa st->cpus = cpus; 21181975d36eSJiri Olsa return set_maps(st); 21191975d36eSJiri Olsa } 21201975d36eSJiri Olsa 21218a59f3ccSJiri Olsa static const char * const stat_report_usage[] = { 2122ba6039b6SJiri Olsa "perf stat report [<options>]", 2123ba6039b6SJiri Olsa NULL, 2124ba6039b6SJiri Olsa }; 2125ba6039b6SJiri Olsa 2126ba6039b6SJiri Olsa static struct perf_stat perf_stat = { 2127ba6039b6SJiri Olsa .tool = { 2128ba6039b6SJiri Olsa .attr = perf_event__process_attr, 2129fa6ea781SJiri Olsa .event_update = perf_event__process_event_update, 21301975d36eSJiri Olsa .thread_map = process_thread_map_event, 21311975d36eSJiri Olsa .cpu_map = process_cpu_map_event, 213262ba18baSJiri Olsa .stat_config = process_stat_config_event, 2133a56f9390SJiri Olsa .stat = perf_event__process_stat_event, 2134a56f9390SJiri Olsa .stat_round = process_stat_round_event, 2135ba6039b6SJiri Olsa }, 213689af4e05SJiri Olsa .aggr_mode = AGGR_UNSET, 2137ba6039b6SJiri Olsa }; 2138ba6039b6SJiri Olsa 2139ba6039b6SJiri Olsa static int __cmd_report(int argc, const char **argv) 2140ba6039b6SJiri Olsa { 2141ba6039b6SJiri Olsa struct perf_session *session; 2142ba6039b6SJiri Olsa const struct option options[] = { 2143ba6039b6SJiri Olsa OPT_STRING('i', "input", &input_name, "file", "input file name"), 214489af4e05SJiri Olsa OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode, 214589af4e05SJiri Olsa "aggregate counts per processor socket", AGGR_SOCKET), 2146db5742b6SKan Liang OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode, 2147db5742b6SKan Liang "aggregate counts per processor die", AGGR_DIE), 214889af4e05SJiri Olsa OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode, 214989af4e05SJiri Olsa "aggregate counts per physical processor core", AGGR_CORE), 215086895b48SJiri Olsa OPT_SET_UINT(0, "per-node", &perf_stat.aggr_mode, 215186895b48SJiri Olsa "aggregate counts per numa node", AGGR_NODE), 215289af4e05SJiri Olsa OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode, 215389af4e05SJiri Olsa "disable CPU count aggregation", AGGR_NONE), 2154ba6039b6SJiri Olsa OPT_END() 2155ba6039b6SJiri Olsa }; 2156ba6039b6SJiri Olsa struct stat st; 2157ba6039b6SJiri Olsa int ret; 2158ba6039b6SJiri Olsa 21598a59f3ccSJiri Olsa argc = parse_options(argc, argv, options, stat_report_usage, 0); 2160ba6039b6SJiri Olsa 2161ba6039b6SJiri Olsa if (!input_name || !strlen(input_name)) { 2162ba6039b6SJiri Olsa if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) 2163ba6039b6SJiri Olsa input_name = "-"; 2164ba6039b6SJiri Olsa else 2165ba6039b6SJiri Olsa input_name = "perf.data"; 2166ba6039b6SJiri Olsa } 2167ba6039b6SJiri Olsa 21682d4f2799SJiri Olsa perf_stat.data.path = input_name; 21698ceb41d7SJiri Olsa perf_stat.data.mode = PERF_DATA_MODE_READ; 2170ba6039b6SJiri Olsa 21712681bd85SNamhyung Kim session = perf_session__new(&perf_stat.data, &perf_stat.tool); 21726ef81c55SMamatha Inamdar if (IS_ERR(session)) 21736ef81c55SMamatha Inamdar return PTR_ERR(session); 2174ba6039b6SJiri Olsa 2175ba6039b6SJiri Olsa perf_stat.session = session; 2176ba6039b6SJiri Olsa stat_config.output = stderr; 2177ba6039b6SJiri Olsa evsel_list = session->evlist; 2178ba6039b6SJiri Olsa 2179ba6039b6SJiri Olsa ret = perf_session__process_events(session); 2180ba6039b6SJiri Olsa if (ret) 2181ba6039b6SJiri Olsa return ret; 2182ba6039b6SJiri Olsa 2183ba6039b6SJiri Olsa perf_session__delete(session); 2184ba6039b6SJiri Olsa return 0; 2185ba6039b6SJiri Olsa } 2186ba6039b6SJiri Olsa 2187e3ba76deSJiri Olsa static void setup_system_wide(int forks) 2188e3ba76deSJiri Olsa { 2189e3ba76deSJiri Olsa /* 2190e3ba76deSJiri Olsa * Make system wide (-a) the default target if 2191e3ba76deSJiri Olsa * no target was specified and one of following 2192e3ba76deSJiri Olsa * conditions is met: 2193e3ba76deSJiri Olsa * 2194e3ba76deSJiri Olsa * - there's no workload specified 2195e3ba76deSJiri Olsa * - there is workload specified but all requested 2196e3ba76deSJiri Olsa * events are system wide events 2197e3ba76deSJiri Olsa */ 2198e3ba76deSJiri Olsa if (!target__none(&target)) 2199e3ba76deSJiri Olsa return; 2200e3ba76deSJiri Olsa 2201e3ba76deSJiri Olsa if (!forks) 2202e3ba76deSJiri Olsa target.system_wide = true; 2203e3ba76deSJiri Olsa else { 220432dcd021SJiri Olsa struct evsel *counter; 2205e3ba76deSJiri Olsa 2206e3ba76deSJiri Olsa evlist__for_each_entry(evsel_list, counter) { 2207002a3d69SJin Yao if (!counter->core.system_wide && 2208002a3d69SJin Yao strcmp(counter->name, "duration_time")) { 2209e3ba76deSJiri Olsa return; 2210e3ba76deSJiri Olsa } 2211002a3d69SJin Yao } 2212e3ba76deSJiri Olsa 22136484d2f9SJiri Olsa if (evsel_list->core.nr_entries) 2214e3ba76deSJiri Olsa target.system_wide = true; 2215e3ba76deSJiri Olsa } 2216e3ba76deSJiri Olsa } 2217e3ba76deSJiri Olsa 2218b0ad8ea6SArnaldo Carvalho de Melo int cmd_stat(int argc, const char **argv) 221986470930SIngo Molnar { 2220b070a547SArnaldo Carvalho de Melo const char * const stat_usage[] = { 2221b070a547SArnaldo Carvalho de Melo "perf stat [<options>] [<command>]", 2222b070a547SArnaldo Carvalho de Melo NULL 2223b070a547SArnaldo Carvalho de Melo }; 2224fa853c4bSSong Liu int status = -EINVAL, run_idx, err; 22254aa9015fSStephane Eranian const char *mode; 22265821522eSJiri Olsa FILE *output = stderr; 2227f1f8ad52Syuzhoujian unsigned int interval, timeout; 2228ba6039b6SJiri Olsa const char * const stat_subcommands[] = { "record", "report" }; 2229fa853c4bSSong Liu char errbuf[BUFSIZ]; 223042202dd5SIngo Molnar 22315af52b51SStephane Eranian setlocale(LC_ALL, ""); 22325af52b51SStephane Eranian 22330f98b11cSJiri Olsa evsel_list = evlist__new(); 2234361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 2235361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 2236361c99a6SArnaldo Carvalho de Melo 22371669e509SWang Nan parse_events__shrink_config_terms(); 223851433eadSMichael Petlan 223951433eadSMichael Petlan /* String-parsing callback-based options would segfault when negated */ 224051433eadSMichael Petlan set_option_flag(stat_options, 'e', "event", PARSE_OPT_NONEG); 224151433eadSMichael Petlan set_option_flag(stat_options, 'M', "metrics", PARSE_OPT_NONEG); 224251433eadSMichael Petlan set_option_flag(stat_options, 'G', "cgroup", PARSE_OPT_NONEG); 224351433eadSMichael Petlan 22444979d0c7SJiri Olsa argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands, 22454979d0c7SJiri Olsa (const char **) stat_usage, 2246a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 224737932c18SAndi Kleen perf_stat__collect_metric_expr(evsel_list); 2248fb4605baSAndi Kleen perf_stat__init_shadow_stats(); 2249d7470b6aSStephane Eranian 2250fa7070a3SJiri Olsa if (stat_config.csv_sep) { 2251fa7070a3SJiri Olsa stat_config.csv_output = true; 2252fa7070a3SJiri Olsa if (!strcmp(stat_config.csv_sep, "\\t")) 2253fa7070a3SJiri Olsa stat_config.csv_sep = "\t"; 22546edb78a2SJiri Olsa } else 2255fa7070a3SJiri Olsa stat_config.csv_sep = DEFAULT_SEPARATOR; 22566edb78a2SJiri Olsa 22574979d0c7SJiri Olsa if (argc && !strncmp(argv[0], "rec", 3)) { 22584979d0c7SJiri Olsa argc = __cmd_record(argc, argv); 22594979d0c7SJiri Olsa if (argc < 0) 22604979d0c7SJiri Olsa return -1; 2261ba6039b6SJiri Olsa } else if (argc && !strncmp(argv[0], "rep", 3)) 2262ba6039b6SJiri Olsa return __cmd_report(argc, argv); 22634979d0c7SJiri Olsa 2264ec0d3d1fSJiri Olsa interval = stat_config.interval; 2265f1f8ad52Syuzhoujian timeout = stat_config.timeout; 2266ec0d3d1fSJiri Olsa 22674979d0c7SJiri Olsa /* 22684979d0c7SJiri Olsa * For record command the -o is already taken care of. 22694979d0c7SJiri Olsa */ 22704979d0c7SJiri Olsa if (!STAT_RECORD && output_name && strcmp(output_name, "-")) 22714aa9015fSStephane Eranian output = NULL; 22724aa9015fSStephane Eranian 227356f3bae7SJim Cromie if (output_name && output_fd) { 227456f3bae7SJim Cromie fprintf(stderr, "cannot use both --output and --log-fd\n"); 2275e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "o", 1); 2276e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "log-fd", 0); 2277cc03c542SNamhyung Kim goto out; 227856f3bae7SJim Cromie } 2279fc3e4d07SStephane Eranian 22800ce5aa02SJiri Olsa if (stat_config.metric_only && stat_config.aggr_mode == AGGR_THREAD) { 228154b50916SAndi Kleen fprintf(stderr, "--metric-only is not supported with --per-thread\n"); 228254b50916SAndi Kleen goto out; 228354b50916SAndi Kleen } 228454b50916SAndi Kleen 2285d97ae04bSJiri Olsa if (stat_config.metric_only && stat_config.run_count > 1) { 228654b50916SAndi Kleen fprintf(stderr, "--metric-only is not supported with -r\n"); 228754b50916SAndi Kleen goto out; 228854b50916SAndi Kleen } 228954b50916SAndi Kleen 229054ac0b1bSJiri Olsa if (stat_config.walltime_run_table && stat_config.run_count <= 1) { 2291e55c14afSJiri Olsa fprintf(stderr, "--table is only supported with -r\n"); 2292e55c14afSJiri Olsa parse_options_usage(stat_usage, stat_options, "r", 1); 2293e55c14afSJiri Olsa parse_options_usage(NULL, stat_options, "table", 0); 2294e55c14afSJiri Olsa goto out; 2295e55c14afSJiri Olsa } 2296e55c14afSJiri Olsa 2297fc3e4d07SStephane Eranian if (output_fd < 0) { 2298fc3e4d07SStephane Eranian fprintf(stderr, "argument to --log-fd must be a > 0\n"); 2299e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "log-fd", 0); 2300cc03c542SNamhyung Kim goto out; 2301fc3e4d07SStephane Eranian } 2302fc3e4d07SStephane Eranian 230355a4de94SAndi Kleen if (!output && !stat_config.quiet) { 23044aa9015fSStephane Eranian struct timespec tm; 23054aa9015fSStephane Eranian mode = append_file ? "a" : "w"; 23064aa9015fSStephane Eranian 23074aa9015fSStephane Eranian output = fopen(output_name, mode); 23084aa9015fSStephane Eranian if (!output) { 23094aa9015fSStephane Eranian perror("failed to create output file"); 2310fceda7feSDavid Ahern return -1; 23114aa9015fSStephane Eranian } 23124aa9015fSStephane Eranian clock_gettime(CLOCK_REALTIME, &tm); 23134aa9015fSStephane Eranian fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 2314fc3e4d07SStephane Eranian } else if (output_fd > 0) { 231556f3bae7SJim Cromie mode = append_file ? "a" : "w"; 231656f3bae7SJim Cromie output = fdopen(output_fd, mode); 231756f3bae7SJim Cromie if (!output) { 231856f3bae7SJim Cromie perror("Failed opening logfd"); 231956f3bae7SJim Cromie return -errno; 232056f3bae7SJim Cromie } 23214aa9015fSStephane Eranian } 23224aa9015fSStephane Eranian 23235821522eSJiri Olsa stat_config.output = output; 23245821522eSJiri Olsa 2325d7470b6aSStephane Eranian /* 2326d7470b6aSStephane Eranian * let the spreadsheet do the pretty-printing 2327d7470b6aSStephane Eranian */ 2328fa7070a3SJiri Olsa if (stat_config.csv_output) { 232961a9f324SJim Cromie /* User explicitly passed -B? */ 2330d7470b6aSStephane Eranian if (big_num_opt == 1) { 2331d7470b6aSStephane Eranian fprintf(stderr, "-B option not supported with -x\n"); 2332e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "B", 1); 2333e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "x", 1); 2334cc03c542SNamhyung Kim goto out; 2335d7470b6aSStephane Eranian } else /* Nope, so disable big number formatting */ 233634ff0866SJiri Olsa stat_config.big_num = false; 2337d7470b6aSStephane Eranian } else if (big_num_opt == 0) /* User passed --no-big-num */ 233834ff0866SJiri Olsa stat_config.big_num = false; 2339d7470b6aSStephane Eranian 2340fa853c4bSSong Liu err = target__validate(&target); 2341fa853c4bSSong Liu if (err) { 2342fa853c4bSSong Liu target__strerror(&target, err, errbuf, BUFSIZ); 2343fa853c4bSSong Liu pr_warning("%s\n", errbuf); 2344fa853c4bSSong Liu } 2345fa853c4bSSong Liu 2346e3ba76deSJiri Olsa setup_system_wide(argc); 2347ac3063bdSDavid Ahern 23480ce2da14SJiri Olsa /* 23490ce2da14SJiri Olsa * Display user/system times only for single 23500ce2da14SJiri Olsa * run and when there's specified tracee. 23510ce2da14SJiri Olsa */ 2352d97ae04bSJiri Olsa if ((stat_config.run_count == 1) && target__none(&target)) 23538897a891SJiri Olsa stat_config.ru_display = true; 23540ce2da14SJiri Olsa 2355d97ae04bSJiri Olsa if (stat_config.run_count < 0) { 2356cc03c542SNamhyung Kim pr_err("Run count must be a positive number\n"); 2357e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "r", 1); 2358cc03c542SNamhyung Kim goto out; 2359d97ae04bSJiri Olsa } else if (stat_config.run_count == 0) { 2360a7e191c3SFrederik Deweerdt forever = true; 2361d97ae04bSJiri Olsa stat_config.run_count = 1; 2362a7e191c3SFrederik Deweerdt } 236386470930SIngo Molnar 236454ac0b1bSJiri Olsa if (stat_config.walltime_run_table) { 236554ac0b1bSJiri Olsa stat_config.walltime_run = zalloc(stat_config.run_count * sizeof(stat_config.walltime_run[0])); 236654ac0b1bSJiri Olsa if (!stat_config.walltime_run) { 2367e55c14afSJiri Olsa pr_err("failed to setup -r option"); 2368e55c14afSJiri Olsa goto out; 2369e55c14afSJiri Olsa } 2370e55c14afSJiri Olsa } 2371e55c14afSJiri Olsa 23721d9f8d1bSJin Yao if ((stat_config.aggr_mode == AGGR_THREAD) && 23731d9f8d1bSJin Yao !target__has_task(&target)) { 23741d9f8d1bSJin Yao if (!target.system_wide || target.cpu_list) { 23751d9f8d1bSJin Yao fprintf(stderr, "The --per-thread option is only " 23761d9f8d1bSJin Yao "available when monitoring via -p -t -a " 23771d9f8d1bSJin Yao "options or only --per-thread.\n"); 2378e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "p", 1); 2379e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "t", 1); 238032b8af82SJiri Olsa goto out; 238132b8af82SJiri Olsa } 23821d9f8d1bSJin Yao } 238332b8af82SJiri Olsa 238432b8af82SJiri Olsa /* 238532b8af82SJiri Olsa * no_aggr, cgroup are for system-wide only 238632b8af82SJiri Olsa * --per-thread is aggregated per thread, we dont mix it with cpu mode 238732b8af82SJiri Olsa */ 2388421a50f3SJiri Olsa if (((stat_config.aggr_mode != AGGR_GLOBAL && 2389*1c02f6c9SNamhyung Kim stat_config.aggr_mode != AGGR_THREAD) || 2390*1c02f6c9SNamhyung Kim (nr_cgroups || stat_config.cgroup_list)) && 2391602ad878SArnaldo Carvalho de Melo !target__has_cpu(&target)) { 2392023695d9SStephane Eranian fprintf(stderr, "both cgroup and no-aggregation " 2393023695d9SStephane Eranian "modes only available in system-wide mode\n"); 2394023695d9SStephane Eranian 2395e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "G", 1); 2396e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "A", 1); 2397e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "a", 1); 2398*1c02f6c9SNamhyung Kim parse_options_usage(NULL, stat_options, "for-each-cgroup", 0); 2399cc03c542SNamhyung Kim goto out; 2400d7e7a451SStephane Eranian } 2401d7e7a451SStephane Eranian 2402f07952b1SAlexander Antonov if (stat_config.iostat_run) { 2403f07952b1SAlexander Antonov status = iostat_prepare(evsel_list, &stat_config); 2404f07952b1SAlexander Antonov if (status) 2405f07952b1SAlexander Antonov goto out; 2406f07952b1SAlexander Antonov if (iostat_mode == IOSTAT_LIST) { 2407f07952b1SAlexander Antonov iostat_list(evsel_list, &stat_config); 2408f07952b1SAlexander Antonov goto out; 2409f07952b1SAlexander Antonov } else if (verbose) 2410f07952b1SAlexander Antonov iostat_list(evsel_list, &stat_config); 2411f07952b1SAlexander Antonov } 2412f07952b1SAlexander Antonov 24132cba3ffbSIngo Molnar if (add_default_attributes()) 2414c6264defSIngo Molnar goto out; 241586470930SIngo Molnar 2416d1c5a0e8SNamhyung Kim if (stat_config.cgroup_list) { 2417d1c5a0e8SNamhyung Kim if (nr_cgroups > 0) { 2418d1c5a0e8SNamhyung Kim pr_err("--cgroup and --for-each-cgroup cannot be used together\n"); 2419d1c5a0e8SNamhyung Kim parse_options_usage(stat_usage, stat_options, "G", 1); 2420d1c5a0e8SNamhyung Kim parse_options_usage(NULL, stat_options, "for-each-cgroup", 0); 2421d1c5a0e8SNamhyung Kim goto out; 2422d1c5a0e8SNamhyung Kim } 2423d1c5a0e8SNamhyung Kim 2424b214ba8cSNamhyung Kim if (evlist__expand_cgroup(evsel_list, stat_config.cgroup_list, 2425bb1c15b6SNamhyung Kim &stat_config.metric_events, true) < 0) { 2426bb1c15b6SNamhyung Kim parse_options_usage(stat_usage, stat_options, 2427bb1c15b6SNamhyung Kim "for-each-cgroup", 0); 2428d1c5a0e8SNamhyung Kim goto out; 2429d1c5a0e8SNamhyung Kim } 2430bb1c15b6SNamhyung Kim } 2431d1c5a0e8SNamhyung Kim 24321d9f8d1bSJin Yao if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide)) 24331d9f8d1bSJin Yao target.per_thread = true; 24341d9f8d1bSJin Yao 24351d3351e6SJin Yao if (evlist__fix_hybrid_cpus(evsel_list, target.cpu_list)) { 24361d3351e6SJin Yao pr_err("failed to use cpu list %s\n", target.cpu_list); 24371d3351e6SJin Yao goto out; 24381d3351e6SJin Yao } 24391d3351e6SJin Yao 24401d3351e6SJin Yao target.hybrid = perf_pmu__has_hybrid(); 24417748bb71SArnaldo Carvalho de Melo if (evlist__create_maps(evsel_list, &target) < 0) { 2442602ad878SArnaldo Carvalho de Melo if (target__has_task(&target)) { 24435c98d466SArnaldo Carvalho de Melo pr_err("Problems finding threads of monitor\n"); 2444e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "p", 1); 2445e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "t", 1); 2446602ad878SArnaldo Carvalho de Melo } else if (target__has_cpu(&target)) { 244760d567e2SArnaldo Carvalho de Melo perror("failed to parse CPUs map"); 2448e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "C", 1); 2449e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "a", 1); 2450cc03c542SNamhyung Kim } 2451cc03c542SNamhyung Kim goto out; 245260d567e2SArnaldo Carvalho de Melo } 245332b8af82SJiri Olsa 2454a9a17902SJiri Olsa evlist__check_cpu_maps(evsel_list); 2455a9a17902SJiri Olsa 245632b8af82SJiri Olsa /* 245732b8af82SJiri Olsa * Initialize thread_map with comm names, 245832b8af82SJiri Olsa * so we could print it out on output. 245932b8af82SJiri Olsa */ 246056739444SJin Yao if (stat_config.aggr_mode == AGGR_THREAD) { 246103617c22SJiri Olsa thread_map__read_comms(evsel_list->core.threads); 246256739444SJin Yao if (target.system_wide) { 246356739444SJin Yao if (runtime_stat_new(&stat_config, 2464a2f354e3SJiri Olsa perf_thread_map__nr(evsel_list->core.threads))) { 246556739444SJin Yao goto out; 246656739444SJin Yao } 246756739444SJin Yao } 246856739444SJin Yao } 246932b8af82SJiri Olsa 247086895b48SJiri Olsa if (stat_config.aggr_mode == AGGR_NODE) 247186895b48SJiri Olsa cpu__setup_cpunode_map(); 247286895b48SJiri Olsa 2473db06a269Syuzhoujian if (stat_config.times && interval) 2474db06a269Syuzhoujian interval_count = true; 2475db06a269Syuzhoujian else if (stat_config.times && !interval) { 2476db06a269Syuzhoujian pr_err("interval-count option should be used together with " 2477db06a269Syuzhoujian "interval-print.\n"); 2478db06a269Syuzhoujian parse_options_usage(stat_usage, stat_options, "interval-count", 0); 2479db06a269Syuzhoujian parse_options_usage(stat_usage, stat_options, "I", 1); 2480db06a269Syuzhoujian goto out; 2481db06a269Syuzhoujian } 2482c45c6ea2SStephane Eranian 2483f1f8ad52Syuzhoujian if (timeout && timeout < 100) { 2484f1f8ad52Syuzhoujian if (timeout < 10) { 2485f1f8ad52Syuzhoujian pr_err("timeout must be >= 10ms.\n"); 2486f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "timeout", 0); 2487f1f8ad52Syuzhoujian goto out; 2488f1f8ad52Syuzhoujian } else 2489f1f8ad52Syuzhoujian pr_warning("timeout < 100ms. " 2490f1f8ad52Syuzhoujian "The overhead percentage could be high in some cases. " 2491f1f8ad52Syuzhoujian "Please proceed with caution.\n"); 2492f1f8ad52Syuzhoujian } 2493f1f8ad52Syuzhoujian if (timeout && interval) { 2494f1f8ad52Syuzhoujian pr_err("timeout option is not supported with interval-print.\n"); 2495f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "timeout", 0); 2496f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "I", 1); 2497f1f8ad52Syuzhoujian goto out; 2498f1f8ad52Syuzhoujian } 2499f1f8ad52Syuzhoujian 250053f5e908SArnaldo Carvalho de Melo if (evlist__alloc_stats(evsel_list, interval)) 250103ad9747SArnaldo Carvalho de Melo goto out; 2502d6d901c2SZhang, Yanmin 250386ee6e18SStephane Eranian if (perf_stat_init_aggr_mode()) 250403ad9747SArnaldo Carvalho de Melo goto out; 250586ee6e18SStephane Eranian 250686470930SIngo Molnar /* 25077d9ad16aSJiri Olsa * Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless 25087d9ad16aSJiri Olsa * while avoiding that older tools show confusing messages. 25097d9ad16aSJiri Olsa * 25107d9ad16aSJiri Olsa * However for pipe sessions we need to keep it zero, 25117d9ad16aSJiri Olsa * because script's perf_evsel__check_attr is triggered 25127d9ad16aSJiri Olsa * by attr->sample_type != 0, and we can't run it on 25137d9ad16aSJiri Olsa * stat sessions. 25147d9ad16aSJiri Olsa */ 25157d9ad16aSJiri Olsa stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe); 25167d9ad16aSJiri Olsa 25177d9ad16aSJiri Olsa /* 251886470930SIngo Molnar * We dont want to block the signals - that would cause 251986470930SIngo Molnar * child tasks to inherit that and Ctrl-C would not work. 252086470930SIngo Molnar * What we want is for Ctrl-C to work in the exec()-ed 252186470930SIngo Molnar * task, but being ignored by perf stat itself: 252286470930SIngo Molnar */ 2523f7b7c26eSPeter Zijlstra atexit(sig_atexit); 2524a7e191c3SFrederik Deweerdt if (!forever) 252586470930SIngo Molnar signal(SIGINT, skip_signal); 252613370a9bSStephane Eranian signal(SIGCHLD, skip_signal); 252786470930SIngo Molnar signal(SIGALRM, skip_signal); 252886470930SIngo Molnar signal(SIGABRT, skip_signal); 252986470930SIngo Molnar 253027e9769aSAlexey Budankov if (evlist__initialize_ctlfd(evsel_list, stat_config.ctl_fd, stat_config.ctl_fd_ack)) 253127e9769aSAlexey Budankov goto out; 253227e9769aSAlexey Budankov 253342202dd5SIngo Molnar status = 0; 2534d97ae04bSJiri Olsa for (run_idx = 0; forever || run_idx < stat_config.run_count; run_idx++) { 2535d97ae04bSJiri Olsa if (stat_config.run_count != 1 && verbose > 0) 25364aa9015fSStephane Eranian fprintf(output, "[ perf stat: executing run #%d ... ]\n", 25374aa9015fSStephane Eranian run_idx + 1); 2538f9cef0a9SIngo Molnar 2539b63fd11cSSrikar Dronamraju if (run_idx != 0) 254053f5e908SArnaldo Carvalho de Melo evlist__reset_prev_raw_counts(evsel_list); 2541b63fd11cSSrikar Dronamraju 2542e55c14afSJiri Olsa status = run_perf_stat(argc, argv, run_idx); 2543443f2d5bSSrikar Dronamraju if (forever && status != -1 && !interval) { 2544d4f63a47SJiri Olsa print_counters(NULL, argc, argv); 2545254ecbc7SJiri Olsa perf_stat__reset_stats(); 2546a7e191c3SFrederik Deweerdt } 254742202dd5SIngo Molnar } 254842202dd5SIngo Molnar 2549c7e5b328SJin Yao if (!forever && status != -1 && (!interval || stat_config.summary)) 2550d4f63a47SJiri Olsa print_counters(NULL, argc, argv); 2551d134ffb9SArnaldo Carvalho de Melo 255227e9769aSAlexey Budankov evlist__finalize_ctlfd(evsel_list); 255327e9769aSAlexey Budankov 25544979d0c7SJiri Olsa if (STAT_RECORD) { 25554979d0c7SJiri Olsa /* 25564979d0c7SJiri Olsa * We synthesize the kernel mmap record just so that older tools 25574979d0c7SJiri Olsa * don't emit warnings about not being able to resolve symbols 25584d39c89fSIngo Molnar * due to /proc/sys/kernel/kptr_restrict settings and instead provide 25594979d0c7SJiri Olsa * a saner message about no samples being in the perf.data file. 25604979d0c7SJiri Olsa * 25614979d0c7SJiri Olsa * This also serves to suppress a warning about f_header.data.size == 0 25628b99b1a4SJiri Olsa * in header.c at the moment 'perf stat record' gets introduced, which 25638b99b1a4SJiri Olsa * is not really needed once we start adding the stat specific PERF_RECORD_ 25648b99b1a4SJiri Olsa * records, but the need to suppress the kptr_restrict messages in older 25658b99b1a4SJiri Olsa * tools remain -acme 25664979d0c7SJiri Olsa */ 25678ceb41d7SJiri Olsa int fd = perf_data__fd(&perf_stat.data); 2568fa853c4bSSong Liu 2569fa853c4bSSong Liu err = perf_event__synthesize_kernel_mmap((void *)&perf_stat, 25704979d0c7SJiri Olsa process_synthesized_event, 25714979d0c7SJiri Olsa &perf_stat.session->machines.host); 25724979d0c7SJiri Olsa if (err) { 25734979d0c7SJiri Olsa pr_warning("Couldn't synthesize the kernel mmap record, harmless, " 25744979d0c7SJiri Olsa "older tools may produce warnings about this file\n."); 25754979d0c7SJiri Olsa } 25764979d0c7SJiri Olsa 25777aad0c32SJiri Olsa if (!interval) { 25787aad0c32SJiri Olsa if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL)) 25797aad0c32SJiri Olsa pr_err("failed to write stat round event\n"); 25807aad0c32SJiri Olsa } 25817aad0c32SJiri Olsa 25828ceb41d7SJiri Olsa if (!perf_stat.data.is_pipe) { 25834979d0c7SJiri Olsa perf_stat.session->header.data_size += perf_stat.bytes_written; 25844979d0c7SJiri Olsa perf_session__write_header(perf_stat.session, evsel_list, fd, true); 2585664c98d4SJiri Olsa } 25864979d0c7SJiri Olsa 2587750b4edeSJiri Olsa evlist__close(evsel_list); 25884979d0c7SJiri Olsa perf_session__delete(perf_stat.session); 25894979d0c7SJiri Olsa } 25904979d0c7SJiri Olsa 2591544c2ae7SMasami Hiramatsu perf_stat__exit_aggr_mode(); 259253f5e908SArnaldo Carvalho de Melo evlist__free_stats(evsel_list); 25930015e2e1SArnaldo Carvalho de Melo out: 2594f07952b1SAlexander Antonov if (stat_config.iostat_run) 2595f07952b1SAlexander Antonov iostat_release(evsel_list); 2596f07952b1SAlexander Antonov 2597d8f9da24SArnaldo Carvalho de Melo zfree(&stat_config.walltime_run); 2598e55c14afSJiri Olsa 2599daefd0bcSKan Liang if (smi_cost && smi_reset) 2600daefd0bcSKan Liang sysfs__write_int(FREEZE_ON_SMI_PATH, 0); 2601daefd0bcSKan Liang 2602c12995a5SJiri Olsa evlist__delete(evsel_list); 260356739444SJin Yao 26049afe5658SJiri Olsa metricgroup__rblist_exit(&stat_config.metric_events); 260556739444SJin Yao runtime_stat_delete(&stat_config); 2606ee7fe31eSAdrian Hunter evlist__close_control(stat_config.ctl_fd, stat_config.ctl_fd_ack, &stat_config.ctl_fd_close); 260756739444SJin Yao 260842202dd5SIngo Molnar return status; 260986470930SIngo Molnar } 2610