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; 194*a4b8cfcaSIan Rogers static char *metrics; 1955af52b51SStephane Eranian 1964979d0c7SJiri Olsa struct perf_stat { 1974979d0c7SJiri Olsa bool record; 1988ceb41d7SJiri Olsa struct perf_data data; 1994979d0c7SJiri Olsa struct perf_session *session; 2004979d0c7SJiri Olsa u64 bytes_written; 201ba6039b6SJiri Olsa struct perf_tool tool; 2021975d36eSJiri Olsa bool maps_allocated; 203f854839bSJiri Olsa struct perf_cpu_map *cpus; 2049749b90eSJiri Olsa struct perf_thread_map *threads; 20589af4e05SJiri Olsa enum aggr_mode aggr_mode; 2064979d0c7SJiri Olsa }; 2074979d0c7SJiri Olsa 2084979d0c7SJiri Olsa static struct perf_stat perf_stat; 2094979d0c7SJiri Olsa #define STAT_RECORD perf_stat.record 2104979d0c7SJiri Olsa 21160666c63SLiming Wang static volatile int done = 0; 21260666c63SLiming Wang 213421a50f3SJiri Olsa static struct perf_stat_config stat_config = { 214421a50f3SJiri Olsa .aggr_mode = AGGR_GLOBAL, 215711a572eSJiri Olsa .scale = true, 216df4f7b4dSJiri Olsa .unit_width = 4, /* strlen("unit") */ 217d97ae04bSJiri Olsa .run_count = 1, 218ee1760e2SJiri Olsa .metric_only_len = METRIC_ONLY_LEN, 21926893a60SJiri Olsa .walltime_nsecs_stats = &walltime_nsecs_stats, 220c735b0a5SFlorian Fischer .ru_stats = &ru_stats, 22134ff0866SJiri Olsa .big_num = true, 22227e9769aSAlexey Budankov .ctl_fd = -1, 223f07952b1SAlexander Antonov .ctl_fd_ack = -1, 224f07952b1SAlexander Antonov .iostat_run = false, 225421a50f3SJiri Olsa }; 226421a50f3SJiri Olsa 227a9a17902SJiri Olsa static bool cpus_map_matched(struct evsel *a, struct evsel *b) 228a9a17902SJiri Olsa { 229a9a17902SJiri Olsa if (!a->core.cpus && !b->core.cpus) 230a9a17902SJiri Olsa return true; 231a9a17902SJiri Olsa 232a9a17902SJiri Olsa if (!a->core.cpus || !b->core.cpus) 233a9a17902SJiri Olsa return false; 234a9a17902SJiri Olsa 23544028699SIan Rogers if (perf_cpu_map__nr(a->core.cpus) != perf_cpu_map__nr(b->core.cpus)) 236a9a17902SJiri Olsa return false; 237a9a17902SJiri Olsa 23844028699SIan Rogers for (int i = 0; i < perf_cpu_map__nr(a->core.cpus); i++) { 23944028699SIan Rogers if (perf_cpu_map__cpu(a->core.cpus, i).cpu != 24044028699SIan Rogers perf_cpu_map__cpu(b->core.cpus, i).cpu) 241a9a17902SJiri Olsa return false; 242a9a17902SJiri Olsa } 243a9a17902SJiri Olsa 244a9a17902SJiri Olsa return true; 245a9a17902SJiri Olsa } 246a9a17902SJiri Olsa 247a9a17902SJiri Olsa static void evlist__check_cpu_maps(struct evlist *evlist) 248a9a17902SJiri Olsa { 249a9a17902SJiri Olsa struct evsel *evsel, *pos, *leader; 250a9a17902SJiri Olsa char buf[1024]; 251a9a17902SJiri Olsa 252660e533eSJin Yao if (evlist__has_hybrid(evlist)) 253660e533eSJin Yao evlist__warn_hybrid_group(evlist); 254660e533eSJin Yao 255a9a17902SJiri Olsa evlist__for_each_entry(evlist, evsel) { 256fba7c866SJiri Olsa leader = evsel__leader(evsel); 257a9a17902SJiri Olsa 258a9a17902SJiri Olsa /* Check that leader matches cpus with each member. */ 259a9a17902SJiri Olsa if (leader == evsel) 260a9a17902SJiri Olsa continue; 261a9a17902SJiri Olsa if (cpus_map_matched(leader, evsel)) 262a9a17902SJiri Olsa continue; 263a9a17902SJiri Olsa 264a9a17902SJiri Olsa /* If there's mismatch disable the group and warn user. */ 265a9a17902SJiri Olsa WARN_ONCE(1, "WARNING: grouped events cpus do not match, disabling group:\n"); 266a9a17902SJiri Olsa evsel__group_desc(leader, buf, sizeof(buf)); 267a9a17902SJiri Olsa pr_warning(" %s\n", buf); 268a9a17902SJiri Olsa 269a9a17902SJiri Olsa if (verbose) { 270a9a17902SJiri Olsa cpu_map__snprint(leader->core.cpus, buf, sizeof(buf)); 271a9a17902SJiri Olsa pr_warning(" %s: %s\n", leader->name, buf); 272a9a17902SJiri Olsa cpu_map__snprint(evsel->core.cpus, buf, sizeof(buf)); 273a9a17902SJiri Olsa pr_warning(" %s: %s\n", evsel->name, buf); 274a9a17902SJiri Olsa } 275a9a17902SJiri Olsa 276e8f4f794SKan Liang for_each_group_evsel(pos, leader) 277e8f4f794SKan Liang evsel__remove_from_group(pos, leader); 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 3307ac0089dSIan Rogers static int evsel__write_stat_event(struct evsel *counter, int cpu_map_idx, u32 thread, 3315a6ea81bSJiri Olsa struct perf_counts_values *count) 3325a6ea81bSJiri Olsa { 3337ac0089dSIan Rogers struct perf_sample_id *sid = SID(counter, cpu_map_idx, thread); 3346d18804bSIan Rogers struct perf_cpu cpu = perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx); 3355a6ea81bSJiri Olsa 3365a6ea81bSJiri Olsa return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count, 3375a6ea81bSJiri Olsa process_synthesized_event, NULL); 3385a6ea81bSJiri Olsa } 3395a6ea81bSJiri Olsa 340da8c94c0SIan Rogers static int read_single_counter(struct evsel *counter, int cpu_map_idx, 341f0fbb114SAndi Kleen int thread, struct timespec *rs) 342f0fbb114SAndi Kleen { 343b03b89b3SFlorian Fischer switch(counter->tool_event) { 344b03b89b3SFlorian Fischer case PERF_TOOL_DURATION_TIME: { 345f0fbb114SAndi Kleen u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL; 346f0fbb114SAndi Kleen struct perf_counts_values *count = 347da8c94c0SIan Rogers perf_counts(counter->counts, cpu_map_idx, thread); 348f0fbb114SAndi Kleen count->ena = count->run = val; 349f0fbb114SAndi Kleen count->val = val; 350f0fbb114SAndi Kleen return 0; 351f0fbb114SAndi Kleen } 352b03b89b3SFlorian Fischer case PERF_TOOL_USER_TIME: 353b03b89b3SFlorian Fischer case PERF_TOOL_SYSTEM_TIME: { 354b03b89b3SFlorian Fischer u64 val; 355b03b89b3SFlorian Fischer struct perf_counts_values *count = 356b03b89b3SFlorian Fischer perf_counts(counter->counts, cpu_map_idx, thread); 357b03b89b3SFlorian Fischer if (counter->tool_event == PERF_TOOL_USER_TIME) 358b03b89b3SFlorian Fischer val = ru_stats.ru_utime_usec_stat.mean; 359b03b89b3SFlorian Fischer else 360b03b89b3SFlorian Fischer val = ru_stats.ru_stime_usec_stat.mean; 361b03b89b3SFlorian Fischer count->ena = count->run = val; 362b03b89b3SFlorian Fischer count->val = val; 363b03b89b3SFlorian Fischer return 0; 364b03b89b3SFlorian Fischer } 365b03b89b3SFlorian Fischer default: 366b03b89b3SFlorian Fischer case PERF_TOOL_NONE: 367da8c94c0SIan Rogers return evsel__read_counter(counter, cpu_map_idx, thread); 368b03b89b3SFlorian Fischer case PERF_TOOL_MAX: 369b03b89b3SFlorian Fischer /* This should never be reached */ 370b03b89b3SFlorian Fischer return 0; 371b03b89b3SFlorian Fischer } 372f0fbb114SAndi Kleen } 373f0fbb114SAndi Kleen 374f5b4a9c3SStephane Eranian /* 375f5b4a9c3SStephane Eranian * Read out the results of a single counter: 376f5b4a9c3SStephane Eranian * do not aggregate counts across CPUs in system-wide mode 377f5b4a9c3SStephane Eranian */ 378da8c94c0SIan Rogers static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu_map_idx) 379f5b4a9c3SStephane Eranian { 380a2f354e3SJiri Olsa int nthreads = perf_thread_map__nr(evsel_list->core.threads); 3814b49ab70SAndi Kleen int thread; 382f5b4a9c3SStephane Eranian 3833b4331d9SSuzuki K. Poulose if (!counter->supported) 3843b4331d9SSuzuki K. Poulose return -ENOENT; 3853b4331d9SSuzuki K. Poulose 3869bf1a529SJiri Olsa for (thread = 0; thread < nthreads; thread++) { 3873b3eb044SJiri Olsa struct perf_counts_values *count; 3883b3eb044SJiri Olsa 389da8c94c0SIan Rogers count = perf_counts(counter->counts, cpu_map_idx, thread); 39082bf311eSJiri Olsa 39182bf311eSJiri Olsa /* 39282bf311eSJiri Olsa * The leader's group read loads data into its group members 393ea089692SArnaldo Carvalho de Melo * (via evsel__read_counter()) and sets their count->loaded. 39482bf311eSJiri Olsa */ 395da8c94c0SIan Rogers if (!perf_counts__is_loaded(counter->counts, cpu_map_idx, thread) && 396da8c94c0SIan Rogers read_single_counter(counter, cpu_map_idx, thread, rs)) { 397db49a717SStephane Eranian counter->counts->scaled = -1; 398da8c94c0SIan Rogers perf_counts(counter->counts, cpu_map_idx, thread)->ena = 0; 399da8c94c0SIan Rogers perf_counts(counter->counts, cpu_map_idx, thread)->run = 0; 400c52b12edSArnaldo Carvalho de Melo return -1; 401db49a717SStephane Eranian } 4025a6ea81bSJiri Olsa 403da8c94c0SIan Rogers perf_counts__set_loaded(counter->counts, cpu_map_idx, thread, false); 40482bf311eSJiri Olsa 4055a6ea81bSJiri Olsa if (STAT_RECORD) { 406da8c94c0SIan Rogers if (evsel__write_stat_event(counter, cpu_map_idx, thread, count)) { 4075a6ea81bSJiri Olsa pr_err("failed to write stat event\n"); 4085a6ea81bSJiri Olsa return -1; 4095a6ea81bSJiri Olsa } 4105a6ea81bSJiri Olsa } 4110b1abbf4SAndi Kleen 4120b1abbf4SAndi Kleen if (verbose > 1) { 4130b1abbf4SAndi Kleen fprintf(stat_config.output, 4140b1abbf4SAndi Kleen "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 4158ab2e96dSArnaldo Carvalho de Melo evsel__name(counter), 4166d18804bSIan Rogers perf_cpu_map__cpu(evsel__cpus(counter), 4176d18804bSIan Rogers cpu_map_idx).cpu, 4180b1abbf4SAndi Kleen count->val, count->ena, count->run); 4190b1abbf4SAndi Kleen } 420f5b4a9c3SStephane Eranian } 421c52b12edSArnaldo Carvalho de Melo 422c52b12edSArnaldo Carvalho de Melo return 0; 42386470930SIngo Molnar } 42486470930SIngo Molnar 425c7e5b328SJin Yao static int read_affinity_counters(struct timespec *rs) 426106a94a0SJiri Olsa { 427472832d2SIan Rogers struct evlist_cpu_iterator evlist_cpu_itr; 428472832d2SIan Rogers struct affinity saved_affinity, *affinity; 4294b49ab70SAndi Kleen 430112cb561SSong Liu if (all_counters_use_bpf) 431112cb561SSong Liu return 0; 432112cb561SSong Liu 4334b49ab70SAndi Kleen if (!target__has_cpu(&target) || target__has_per_thread(&target)) 434472832d2SIan Rogers affinity = NULL; 435472832d2SIan Rogers else if (affinity__setup(&saved_affinity) < 0) 436472832d2SIan Rogers return -1; 437472832d2SIan Rogers else 438472832d2SIan Rogers affinity = &saved_affinity; 439106a94a0SJiri Olsa 440472832d2SIan Rogers evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { 441472832d2SIan Rogers struct evsel *counter = evlist_cpu_itr.evsel; 442472832d2SIan Rogers 443112cb561SSong Liu if (evsel__is_bpf(counter)) 444112cb561SSong Liu continue; 445472832d2SIan Rogers 4464b49ab70SAndi Kleen if (!counter->err) { 4474b49ab70SAndi Kleen counter->err = read_counter_cpu(counter, rs, 448472832d2SIan Rogers evlist_cpu_itr.cpu_map_idx); 4494b49ab70SAndi Kleen } 4504b49ab70SAndi Kleen } 451472832d2SIan Rogers if (affinity) 452472832d2SIan Rogers affinity__cleanup(&saved_affinity); 453472832d2SIan Rogers 454c7e5b328SJin Yao return 0; 455c7e5b328SJin Yao } 456c7e5b328SJin Yao 457fa853c4bSSong Liu static int read_bpf_map_counters(void) 458fa853c4bSSong Liu { 459fa853c4bSSong Liu struct evsel *counter; 460fa853c4bSSong Liu int err; 461fa853c4bSSong Liu 462fa853c4bSSong Liu evlist__for_each_entry(evsel_list, counter) { 463112cb561SSong Liu if (!evsel__is_bpf(counter)) 464112cb561SSong Liu continue; 465112cb561SSong Liu 466fa853c4bSSong Liu err = bpf_counter__read(counter); 467fa853c4bSSong Liu if (err) 468fa853c4bSSong Liu return err; 469fa853c4bSSong Liu } 470fa853c4bSSong Liu return 0; 471fa853c4bSSong Liu } 472fa853c4bSSong Liu 473c7e5b328SJin Yao static void read_counters(struct timespec *rs) 474c7e5b328SJin Yao { 475c7e5b328SJin Yao struct evsel *counter; 476c7e5b328SJin Yao 477fa853c4bSSong Liu if (!stat_config.stop_read_counter) { 478112cb561SSong Liu if (read_bpf_map_counters() || 479112cb561SSong Liu read_affinity_counters(rs)) 480c7e5b328SJin Yao return; 481fa853c4bSSong Liu } 4823b3eb044SJiri Olsa 4834b49ab70SAndi Kleen evlist__for_each_entry(evsel_list, counter) { 4844b49ab70SAndi Kleen if (counter->err) 4854b49ab70SAndi Kleen pr_debug("failed to read counter %s\n", counter->name); 4864b49ab70SAndi Kleen if (counter->err == 0 && perf_stat_process_counter(&stat_config, counter)) 4873b3eb044SJiri Olsa pr_warning("failed to process counter %s\n", counter->name); 4884b49ab70SAndi Kleen counter->err = 0; 489106a94a0SJiri Olsa } 490106a94a0SJiri Olsa } 491106a94a0SJiri Olsa 49272f02a94SJin Yao static int runtime_stat_new(struct perf_stat_config *config, int nthreads) 49372f02a94SJin Yao { 49472f02a94SJin Yao int i; 49572f02a94SJin Yao 49672f02a94SJin Yao config->stats = calloc(nthreads, sizeof(struct runtime_stat)); 49772f02a94SJin Yao if (!config->stats) 49872f02a94SJin Yao return -1; 49972f02a94SJin Yao 50072f02a94SJin Yao config->stats_num = nthreads; 50172f02a94SJin Yao 50272f02a94SJin Yao for (i = 0; i < nthreads; i++) 50372f02a94SJin Yao runtime_stat__init(&config->stats[i]); 50472f02a94SJin Yao 50572f02a94SJin Yao return 0; 50672f02a94SJin Yao } 50772f02a94SJin Yao 50872f02a94SJin Yao static void runtime_stat_delete(struct perf_stat_config *config) 50972f02a94SJin Yao { 51072f02a94SJin Yao int i; 51172f02a94SJin Yao 51272f02a94SJin Yao if (!config->stats) 51372f02a94SJin Yao return; 51472f02a94SJin Yao 51572f02a94SJin Yao for (i = 0; i < config->stats_num; i++) 51672f02a94SJin Yao runtime_stat__exit(&config->stats[i]); 51772f02a94SJin Yao 51872f02a94SJin Yao zfree(&config->stats); 51972f02a94SJin Yao } 52072f02a94SJin Yao 52172f02a94SJin Yao static void runtime_stat_reset(struct perf_stat_config *config) 52272f02a94SJin Yao { 52372f02a94SJin Yao int i; 52472f02a94SJin Yao 52572f02a94SJin Yao if (!config->stats) 52672f02a94SJin Yao return; 52772f02a94SJin Yao 52872f02a94SJin Yao for (i = 0; i < config->stats_num; i++) 52972f02a94SJin Yao perf_stat__reset_shadow_per_stat(&config->stats[i]); 53072f02a94SJin Yao } 53172f02a94SJin Yao 532ba411a95SJiri Olsa static void process_interval(void) 53313370a9bSStephane Eranian { 53413370a9bSStephane Eranian struct timespec ts, rs; 53513370a9bSStephane Eranian 53613370a9bSStephane Eranian clock_gettime(CLOCK_MONOTONIC, &ts); 53713370a9bSStephane Eranian diff_timespec(&rs, &ts, &ref_time); 53813370a9bSStephane Eranian 539197ba86fSJin Yao perf_stat__reset_shadow_per_stat(&rt_stat); 54072f02a94SJin Yao runtime_stat_reset(&stat_config); 541f0fbb114SAndi Kleen read_counters(&rs); 542f0fbb114SAndi Kleen 5437aad0c32SJiri Olsa if (STAT_RECORD) { 544bd48c63eSArnaldo Carvalho de Melo if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL)) 5457aad0c32SJiri Olsa pr_err("failed to write stat round event\n"); 5467aad0c32SJiri Olsa } 5477aad0c32SJiri Olsa 548b90f1333SAndi Kleen init_stats(&walltime_nsecs_stats); 549ea9eb1f4SJiri Olsa update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000ULL); 550d4f63a47SJiri Olsa print_counters(&rs, 0, NULL); 55113370a9bSStephane Eranian } 55213370a9bSStephane Eranian 553dece3a4dSAlexey Budankov static bool handle_interval(unsigned int interval, int *times) 554dece3a4dSAlexey Budankov { 555dece3a4dSAlexey Budankov if (interval) { 556dece3a4dSAlexey Budankov process_interval(); 557dece3a4dSAlexey Budankov if (interval_count && !(--(*times))) 558dece3a4dSAlexey Budankov return true; 559dece3a4dSAlexey Budankov } 560dece3a4dSAlexey Budankov return false; 561dece3a4dSAlexey Budankov } 562dece3a4dSAlexey Budankov 563fa853c4bSSong Liu static int enable_counters(void) 56441191688SAndi Kleen { 565fa853c4bSSong Liu struct evsel *evsel; 566fa853c4bSSong Liu int err; 567fa853c4bSSong Liu 568fa853c4bSSong Liu evlist__for_each_entry(evsel_list, evsel) { 569112cb561SSong Liu if (!evsel__is_bpf(evsel)) 570112cb561SSong Liu continue; 571112cb561SSong Liu 572fa853c4bSSong Liu err = bpf_counter__enable(evsel); 573fa853c4bSSong Liu if (err) 574fa853c4bSSong Liu return err; 575fa853c4bSSong Liu } 576fa853c4bSSong Liu 5772162b9c6SAlexey Budankov if (stat_config.initial_delay < 0) { 5782162b9c6SAlexey Budankov pr_info(EVLIST_DISABLED_MSG); 579fa853c4bSSong Liu return 0; 5802162b9c6SAlexey Budankov } 5812162b9c6SAlexey Budankov 5822162b9c6SAlexey Budankov if (stat_config.initial_delay > 0) { 5832162b9c6SAlexey Budankov pr_info(EVLIST_DISABLED_MSG); 584728c0ee0SJiri Olsa usleep(stat_config.initial_delay * USEC_PER_MSEC); 5852162b9c6SAlexey Budankov } 58667ccdecdSJiri Olsa 58767ccdecdSJiri Olsa /* 58867ccdecdSJiri Olsa * We need to enable counters only if: 58967ccdecdSJiri Olsa * - we don't have tracee (attaching to task or cpu) 59067ccdecdSJiri Olsa * - we have initial delay configured 59167ccdecdSJiri Olsa */ 5922162b9c6SAlexey Budankov if (!target__none(&target) || stat_config.initial_delay) { 593f8b61bd2SSong Liu if (!all_counters_use_bpf) 5941c87f165SJiri Olsa evlist__enable(evsel_list); 5952162b9c6SAlexey Budankov if (stat_config.initial_delay > 0) 5962162b9c6SAlexey Budankov pr_info(EVLIST_ENABLED_MSG); 5972162b9c6SAlexey Budankov } 598fa853c4bSSong Liu return 0; 59941191688SAndi Kleen } 60041191688SAndi Kleen 6013df33effSMark Rutland static void disable_counters(void) 6023df33effSMark Rutland { 603f8b61bd2SSong Liu struct evsel *counter; 604f8b61bd2SSong Liu 6053df33effSMark Rutland /* 6063df33effSMark Rutland * If we don't have tracee (attaching to task or cpu), counters may 6073df33effSMark Rutland * still be running. To get accurate group ratios, we must stop groups 6083df33effSMark Rutland * from counting before reading their constituent counters. 6093df33effSMark Rutland */ 610f8b61bd2SSong Liu if (!target__none(&target)) { 611f8b61bd2SSong Liu evlist__for_each_entry(evsel_list, counter) 612f8b61bd2SSong Liu bpf_counter__disable(counter); 613f8b61bd2SSong Liu if (!all_counters_use_bpf) 614e74676deSJiri Olsa evlist__disable(evsel_list); 6153df33effSMark Rutland } 616f8b61bd2SSong Liu } 6173df33effSMark Rutland 618f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno; 6196af206fdSArnaldo Carvalho de Melo 6206af206fdSArnaldo Carvalho de Melo /* 6217b392ef0SArnaldo Carvalho de Melo * evlist__prepare_workload will send a SIGUSR1 6226af206fdSArnaldo Carvalho de Melo * if the fork fails, since we asked by setting its 6236af206fdSArnaldo Carvalho de Melo * want_signal to true. 6246af206fdSArnaldo Carvalho de Melo */ 625f33cbe72SArnaldo Carvalho de Melo static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info, 626f33cbe72SArnaldo Carvalho de Melo void *ucontext __maybe_unused) 6276af206fdSArnaldo Carvalho de Melo { 628f33cbe72SArnaldo Carvalho de Melo workload_exec_errno = info->si_value.sival_int; 6296af206fdSArnaldo Carvalho de Melo } 6306af206fdSArnaldo Carvalho de Melo 631ddc6999eSArnaldo Carvalho de Melo static bool evsel__should_store_id(struct evsel *counter) 63282bf311eSJiri Olsa { 6331fc632ceSJiri Olsa return STAT_RECORD || counter->core.attr.read_format & PERF_FORMAT_ID; 63482bf311eSJiri Olsa } 63582bf311eSJiri Olsa 636cbb5df7eSJiri Olsa static bool is_target_alive(struct target *_target, 6379749b90eSJiri Olsa struct perf_thread_map *threads) 638cbb5df7eSJiri Olsa { 639cbb5df7eSJiri Olsa struct stat st; 640cbb5df7eSJiri Olsa int i; 641cbb5df7eSJiri Olsa 642cbb5df7eSJiri Olsa if (!target__has_task(_target)) 643cbb5df7eSJiri Olsa return true; 644cbb5df7eSJiri Olsa 645cbb5df7eSJiri Olsa for (i = 0; i < threads->nr; i++) { 646cbb5df7eSJiri Olsa char path[PATH_MAX]; 647cbb5df7eSJiri Olsa 648cbb5df7eSJiri Olsa scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(), 649cbb5df7eSJiri Olsa threads->map[i].pid); 650cbb5df7eSJiri Olsa 651cbb5df7eSJiri Olsa if (!stat(path, &st)) 652cbb5df7eSJiri Olsa return true; 653cbb5df7eSJiri Olsa } 654cbb5df7eSJiri Olsa 655cbb5df7eSJiri Olsa return false; 656cbb5df7eSJiri Olsa } 657cbb5df7eSJiri Olsa 658bee328cbSAlexey Budankov static void process_evlist(struct evlist *evlist, unsigned int interval) 659bee328cbSAlexey Budankov { 660bee328cbSAlexey Budankov enum evlist_ctl_cmd cmd = EVLIST_CTL_CMD_UNSUPPORTED; 661bee328cbSAlexey Budankov 662bee328cbSAlexey Budankov if (evlist__ctlfd_process(evlist, &cmd) > 0) { 663bee328cbSAlexey Budankov switch (cmd) { 664bee328cbSAlexey Budankov case EVLIST_CTL_CMD_ENABLE: 665bee328cbSAlexey Budankov if (interval) 666bee328cbSAlexey Budankov process_interval(); 667bee328cbSAlexey Budankov break; 668bee328cbSAlexey Budankov case EVLIST_CTL_CMD_DISABLE: 669bee328cbSAlexey Budankov if (interval) 670bee328cbSAlexey Budankov process_interval(); 671bee328cbSAlexey Budankov break; 672d20aff15SAdrian Hunter case EVLIST_CTL_CMD_SNAPSHOT: 673bee328cbSAlexey Budankov case EVLIST_CTL_CMD_ACK: 674bee328cbSAlexey Budankov case EVLIST_CTL_CMD_UNSUPPORTED: 675142544a9SJiri Olsa case EVLIST_CTL_CMD_EVLIST: 676f186cd61SJiri Olsa case EVLIST_CTL_CMD_STOP: 67747fddcb4SJiri Olsa case EVLIST_CTL_CMD_PING: 678bee328cbSAlexey Budankov default: 679bee328cbSAlexey Budankov break; 680bee328cbSAlexey Budankov } 681bee328cbSAlexey Budankov } 682bee328cbSAlexey Budankov } 683bee328cbSAlexey Budankov 684bee328cbSAlexey Budankov static void compute_tts(struct timespec *time_start, struct timespec *time_stop, 685bee328cbSAlexey Budankov int *time_to_sleep) 686bee328cbSAlexey Budankov { 687bee328cbSAlexey Budankov int tts = *time_to_sleep; 688bee328cbSAlexey Budankov struct timespec time_diff; 689bee328cbSAlexey Budankov 690bee328cbSAlexey Budankov diff_timespec(&time_diff, time_stop, time_start); 691bee328cbSAlexey Budankov 692bee328cbSAlexey Budankov tts -= time_diff.tv_sec * MSEC_PER_SEC + 693bee328cbSAlexey Budankov time_diff.tv_nsec / NSEC_PER_MSEC; 694bee328cbSAlexey Budankov 695bee328cbSAlexey Budankov if (tts < 0) 696bee328cbSAlexey Budankov tts = 0; 697bee328cbSAlexey Budankov 698bee328cbSAlexey Budankov *time_to_sleep = tts; 699bee328cbSAlexey Budankov } 700bee328cbSAlexey Budankov 701bee328cbSAlexey Budankov static int dispatch_events(bool forks, int timeout, int interval, int *times) 702987b8238SAlexey Budankov { 703987b8238SAlexey Budankov int child_exited = 0, status = 0; 704bee328cbSAlexey Budankov int time_to_sleep, sleep_time; 705bee328cbSAlexey Budankov struct timespec time_start, time_stop; 706bee328cbSAlexey Budankov 707bee328cbSAlexey Budankov if (interval) 708bee328cbSAlexey Budankov sleep_time = interval; 709bee328cbSAlexey Budankov else if (timeout) 710bee328cbSAlexey Budankov sleep_time = timeout; 711bee328cbSAlexey Budankov else 712bee328cbSAlexey Budankov sleep_time = 1000; 713bee328cbSAlexey Budankov 714bee328cbSAlexey Budankov time_to_sleep = sleep_time; 715987b8238SAlexey Budankov 716987b8238SAlexey Budankov while (!done) { 717987b8238SAlexey Budankov if (forks) 718987b8238SAlexey Budankov child_exited = waitpid(child_pid, &status, WNOHANG); 719987b8238SAlexey Budankov else 720987b8238SAlexey Budankov child_exited = !is_target_alive(&target, evsel_list->core.threads) ? 1 : 0; 721987b8238SAlexey Budankov 722987b8238SAlexey Budankov if (child_exited) 723987b8238SAlexey Budankov break; 724987b8238SAlexey Budankov 725bee328cbSAlexey Budankov clock_gettime(CLOCK_MONOTONIC, &time_start); 726bee328cbSAlexey Budankov if (!(evlist__poll(evsel_list, time_to_sleep) > 0)) { /* poll timeout or EINTR */ 727987b8238SAlexey Budankov if (timeout || handle_interval(interval, times)) 728987b8238SAlexey Budankov break; 729bee328cbSAlexey Budankov time_to_sleep = sleep_time; 730bee328cbSAlexey Budankov } else { /* fd revent */ 731bee328cbSAlexey Budankov process_evlist(evsel_list, interval); 732bee328cbSAlexey Budankov clock_gettime(CLOCK_MONOTONIC, &time_stop); 733bee328cbSAlexey Budankov compute_tts(&time_start, &time_stop, &time_to_sleep); 734bee328cbSAlexey Budankov } 735987b8238SAlexey Budankov } 736987b8238SAlexey Budankov 737987b8238SAlexey Budankov return status; 738987b8238SAlexey Budankov } 739987b8238SAlexey Budankov 740e0e6a6caSAndi Kleen enum counter_recovery { 741e0e6a6caSAndi Kleen COUNTER_SKIP, 742e0e6a6caSAndi Kleen COUNTER_RETRY, 743e0e6a6caSAndi Kleen COUNTER_FATAL, 744e0e6a6caSAndi Kleen }; 745e0e6a6caSAndi Kleen 746e0e6a6caSAndi Kleen static enum counter_recovery stat_handle_error(struct evsel *counter) 747e0e6a6caSAndi Kleen { 748e0e6a6caSAndi Kleen char msg[BUFSIZ]; 749e0e6a6caSAndi Kleen /* 750e0e6a6caSAndi Kleen * PPC returns ENXIO for HW counters until 2.6.37 751e0e6a6caSAndi Kleen * (behavior changed with commit b0a873e). 752e0e6a6caSAndi Kleen */ 753e0e6a6caSAndi Kleen if (errno == EINVAL || errno == ENOSYS || 754e0e6a6caSAndi Kleen errno == ENOENT || errno == EOPNOTSUPP || 755e0e6a6caSAndi Kleen errno == ENXIO) { 756e0e6a6caSAndi Kleen if (verbose > 0) 757e0e6a6caSAndi Kleen ui__warning("%s event is not supported by the kernel.\n", 7588ab2e96dSArnaldo Carvalho de Melo evsel__name(counter)); 759e0e6a6caSAndi Kleen counter->supported = false; 7604804e011SAndi Kleen /* 7614804e011SAndi Kleen * errored is a sticky flag that means one of the counter's 7624804e011SAndi Kleen * cpu event had a problem and needs to be reexamined. 7634804e011SAndi Kleen */ 7644804e011SAndi Kleen counter->errored = true; 765e0e6a6caSAndi Kleen 766fba7c866SJiri Olsa if ((evsel__leader(counter) != counter) || 767fba7c866SJiri Olsa !(counter->core.leader->nr_members > 1)) 768e0e6a6caSAndi Kleen return COUNTER_SKIP; 769ae430892SArnaldo Carvalho de Melo } else if (evsel__fallback(counter, errno, msg, sizeof(msg))) { 770e0e6a6caSAndi Kleen if (verbose > 0) 771e0e6a6caSAndi Kleen ui__warning("%s\n", msg); 772e0e6a6caSAndi Kleen return COUNTER_RETRY; 773e0e6a6caSAndi Kleen } else if (target__has_per_thread(&target) && 774e0e6a6caSAndi Kleen evsel_list->core.threads && 775e0e6a6caSAndi Kleen evsel_list->core.threads->err_thread != -1) { 776e0e6a6caSAndi Kleen /* 777e0e6a6caSAndi Kleen * For global --per-thread case, skip current 778e0e6a6caSAndi Kleen * error thread. 779e0e6a6caSAndi Kleen */ 780e0e6a6caSAndi Kleen if (!thread_map__remove(evsel_list->core.threads, 781e0e6a6caSAndi Kleen evsel_list->core.threads->err_thread)) { 782e0e6a6caSAndi Kleen evsel_list->core.threads->err_thread = -1; 783e0e6a6caSAndi Kleen return COUNTER_RETRY; 784e0e6a6caSAndi Kleen } 785e0e6a6caSAndi Kleen } 786e0e6a6caSAndi Kleen 7872bb72dbbSArnaldo Carvalho de Melo evsel__open_strerror(counter, &target, errno, msg, sizeof(msg)); 788e0e6a6caSAndi Kleen ui__error("%s\n", msg); 789e0e6a6caSAndi Kleen 790e0e6a6caSAndi Kleen if (child_pid != -1) 791e0e6a6caSAndi Kleen kill(child_pid, SIGTERM); 792e0e6a6caSAndi Kleen return COUNTER_FATAL; 793e0e6a6caSAndi Kleen } 794e0e6a6caSAndi Kleen 795e55c14afSJiri Olsa static int __run_perf_stat(int argc, const char **argv, int run_idx) 79686470930SIngo Molnar { 797ec0d3d1fSJiri Olsa int interval = stat_config.interval; 798db06a269Syuzhoujian int times = stat_config.times; 799f1f8ad52Syuzhoujian int timeout = stat_config.timeout; 800d6195a6aSArnaldo Carvalho de Melo char msg[BUFSIZ]; 80186470930SIngo Molnar unsigned long long t0, t1; 80232dcd021SJiri Olsa struct evsel *counter; 803410136f5SStephane Eranian size_t l; 80442202dd5SIngo Molnar int status = 0; 8056be2850eSZhang, Yanmin const bool forks = (argc > 0); 8068ceb41d7SJiri Olsa bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false; 807472832d2SIan Rogers struct evlist_cpu_iterator evlist_cpu_itr; 80849de1795SArnaldo Carvalho de Melo struct affinity saved_affinity, *affinity = NULL; 809472832d2SIan Rogers int err; 8104804e011SAndi Kleen bool second_pass = false; 81186470930SIngo Molnar 812acf28922SNamhyung Kim if (forks) { 8137b392ef0SArnaldo Carvalho de Melo if (evlist__prepare_workload(evsel_list, &target, argv, is_pipe, workload_exec_failed_signal) < 0) { 814acf28922SNamhyung Kim perror("failed to prepare workload"); 815fceda7feSDavid Ahern return -1; 816051ae7f7SPaul Mackerras } 817d20a47e7SNamhyung Kim child_pid = evsel_list->workload.pid; 81860666c63SLiming Wang } 819051ae7f7SPaul Mackerras 8206a4bb04cSJiri Olsa if (group) 821a622eafaSArnaldo Carvalho de Melo evlist__set_leader(evsel_list); 8226a4bb04cSJiri Olsa 8230df6ade7SIan Rogers if (!cpu_map__is_dummy(evsel_list->core.user_requested_cpus)) { 82449de1795SArnaldo Carvalho de Melo if (affinity__setup(&saved_affinity) < 0) 8254804e011SAndi Kleen return -1; 82649de1795SArnaldo Carvalho de Melo affinity = &saved_affinity; 82749de1795SArnaldo Carvalho de Melo } 8285a5dfe4bSAndi Kleen 829fa853c4bSSong Liu evlist__for_each_entry(evsel_list, counter) { 830bf515f02SIan Rogers counter->reset_group = false; 831fa853c4bSSong Liu if (bpf_counter__load(counter, &target)) 832fa853c4bSSong Liu return -1; 833112cb561SSong Liu if (!evsel__is_bpf(counter)) 834112cb561SSong Liu all_counters_use_bpf = false; 835fa853c4bSSong Liu } 836fa853c4bSSong Liu 83749de1795SArnaldo Carvalho de Melo evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { 838472832d2SIan Rogers counter = evlist_cpu_itr.evsel; 839472832d2SIan Rogers 8407fac83aaSSong Liu /* 8417fac83aaSSong Liu * bperf calls evsel__open_per_cpu() in bperf__load(), so 8427fac83aaSSong Liu * no need to call it again here. 8437fac83aaSSong Liu */ 8447fac83aaSSong Liu if (target.use_bpf) 8457fac83aaSSong Liu break; 8464804e011SAndi Kleen 8474804e011SAndi Kleen if (counter->reset_group || counter->errored) 8484804e011SAndi Kleen continue; 849112cb561SSong Liu if (evsel__is_bpf(counter)) 850112cb561SSong Liu continue; 8514804e011SAndi Kleen try_again: 8524804e011SAndi Kleen if (create_perf_stat_counter(counter, &stat_config, &target, 853472832d2SIan Rogers evlist_cpu_itr.cpu_map_idx) < 0) { 8544804e011SAndi Kleen 8554804e011SAndi Kleen /* 8564804e011SAndi Kleen * Weak group failed. We cannot just undo this here 8574804e011SAndi Kleen * because earlier CPUs might be in group mode, and the kernel 8584804e011SAndi Kleen * doesn't support mixing group and non group reads. Defer 8594804e011SAndi Kleen * it to later. 8604804e011SAndi Kleen * Don't close here because we're in the wrong affinity. 8614804e011SAndi Kleen */ 86235c1980eSAndi Kleen if ((errno == EINVAL || errno == EBADF) && 863fba7c866SJiri Olsa evsel__leader(counter) != counter && 8645a5dfe4bSAndi Kleen counter->weak_group) { 86564b4778bSArnaldo Carvalho de Melo evlist__reset_weak_group(evsel_list, counter, false); 8664804e011SAndi Kleen assert(counter->reset_group); 8674804e011SAndi Kleen second_pass = true; 8684804e011SAndi Kleen continue; 8695a5dfe4bSAndi Kleen } 8705a5dfe4bSAndi Kleen 871e0e6a6caSAndi Kleen switch (stat_handle_error(counter)) { 872e0e6a6caSAndi Kleen case COUNTER_FATAL: 873084ab9f8SArnaldo Carvalho de Melo return -1; 874e0e6a6caSAndi Kleen case COUNTER_RETRY: 875e0e6a6caSAndi Kleen goto try_again; 876e0e6a6caSAndi Kleen case COUNTER_SKIP: 877e0e6a6caSAndi Kleen continue; 878e0e6a6caSAndi Kleen default: 879e0e6a6caSAndi Kleen break; 880e0e6a6caSAndi Kleen } 8814804e011SAndi Kleen 882084ab9f8SArnaldo Carvalho de Melo } 8832cee77c4SDavid Ahern counter->supported = true; 8844804e011SAndi Kleen } 8854804e011SAndi Kleen 8864804e011SAndi Kleen if (second_pass) { 8874804e011SAndi Kleen /* 8884804e011SAndi Kleen * Now redo all the weak group after closing them, 8894804e011SAndi Kleen * and also close errored counters. 8904804e011SAndi Kleen */ 8914804e011SAndi Kleen 8924804e011SAndi Kleen /* First close errored or weak retry */ 89349de1795SArnaldo Carvalho de Melo evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { 894472832d2SIan Rogers counter = evlist_cpu_itr.evsel; 895472832d2SIan Rogers 8964804e011SAndi Kleen if (!counter->reset_group && !counter->errored) 8974804e011SAndi Kleen continue; 898472832d2SIan Rogers 899472832d2SIan Rogers perf_evsel__close_cpu(&counter->core, evlist_cpu_itr.cpu_map_idx); 9004804e011SAndi Kleen } 9014804e011SAndi Kleen /* Now reopen weak */ 90249de1795SArnaldo Carvalho de Melo evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { 903472832d2SIan Rogers counter = evlist_cpu_itr.evsel; 904472832d2SIan Rogers 9054804e011SAndi Kleen if (!counter->reset_group && !counter->errored) 9064804e011SAndi Kleen continue; 9074804e011SAndi Kleen if (!counter->reset_group) 9084804e011SAndi Kleen continue; 9094804e011SAndi Kleen try_again_reset: 9108ab2e96dSArnaldo Carvalho de Melo pr_debug2("reopening weak %s\n", evsel__name(counter)); 9114804e011SAndi Kleen if (create_perf_stat_counter(counter, &stat_config, &target, 912472832d2SIan Rogers evlist_cpu_itr.cpu_map_idx) < 0) { 9134804e011SAndi Kleen 9144804e011SAndi Kleen switch (stat_handle_error(counter)) { 9154804e011SAndi Kleen case COUNTER_FATAL: 9164804e011SAndi Kleen return -1; 9174804e011SAndi Kleen case COUNTER_RETRY: 9184804e011SAndi Kleen goto try_again_reset; 9194804e011SAndi Kleen case COUNTER_SKIP: 9204804e011SAndi Kleen continue; 9214804e011SAndi Kleen default: 9224804e011SAndi Kleen break; 9234804e011SAndi Kleen } 9244804e011SAndi Kleen } 9254804e011SAndi Kleen counter->supported = true; 9264804e011SAndi Kleen } 9274804e011SAndi Kleen } 92849de1795SArnaldo Carvalho de Melo affinity__cleanup(affinity); 9294804e011SAndi Kleen 9304804e011SAndi Kleen evlist__for_each_entry(evsel_list, counter) { 9314804e011SAndi Kleen if (!counter->supported) { 9324804e011SAndi Kleen perf_evsel__free_fd(&counter->core); 9334804e011SAndi Kleen continue; 9344804e011SAndi Kleen } 935410136f5SStephane Eranian 936410136f5SStephane Eranian l = strlen(counter->unit); 937df4f7b4dSJiri Olsa if (l > stat_config.unit_width) 938df4f7b4dSJiri Olsa stat_config.unit_width = l; 9392af4646dSJiri Olsa 940ddc6999eSArnaldo Carvalho de Melo if (evsel__should_store_id(counter) && 94134397753SArnaldo Carvalho de Melo evsel__store_ids(counter, evsel_list)) 9422af4646dSJiri Olsa return -1; 94348290609SArnaldo Carvalho de Melo } 94486470930SIngo Molnar 94524bf91a7SArnaldo Carvalho de Melo if (evlist__apply_filters(evsel_list, &counter)) { 94662d94b00SArnaldo Carvalho de Melo pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", 9478ab2e96dSArnaldo Carvalho de Melo counter->filter, evsel__name(counter), errno, 948c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, msg, sizeof(msg))); 949cfd748aeSFrederic Weisbecker return -1; 950cfd748aeSFrederic Weisbecker } 951cfd748aeSFrederic Weisbecker 9524979d0c7SJiri Olsa if (STAT_RECORD) { 953fa853c4bSSong Liu int fd = perf_data__fd(&perf_stat.data); 9544979d0c7SJiri Olsa 955664c98d4SJiri Olsa if (is_pipe) { 9568ceb41d7SJiri Olsa err = perf_header__write_pipe(perf_data__fd(&perf_stat.data)); 957664c98d4SJiri Olsa } else { 9584979d0c7SJiri Olsa err = perf_session__write_header(perf_stat.session, evsel_list, 9594979d0c7SJiri Olsa fd, false); 960664c98d4SJiri Olsa } 961664c98d4SJiri Olsa 9624979d0c7SJiri Olsa if (err < 0) 9634979d0c7SJiri Olsa return err; 9648b99b1a4SJiri Olsa 965b251892dSArnaldo Carvalho de Melo err = perf_event__synthesize_stat_events(&stat_config, NULL, evsel_list, 966c2c247f2SJiri Olsa process_synthesized_event, is_pipe); 9678b99b1a4SJiri Olsa if (err < 0) 9688b99b1a4SJiri Olsa return err; 9694979d0c7SJiri Olsa } 9704979d0c7SJiri Olsa 971fa853c4bSSong Liu err = enable_counters(); 972fa853c4bSSong Liu if (err) 973fa853c4bSSong Liu return -1; 974bb8bc52eSAdrián Herrera Arcila 975bb8bc52eSAdrián Herrera Arcila /* Exec the command, if any */ 976bb8bc52eSAdrián Herrera Arcila if (forks) 977d0a0a511SThomas Richter evlist__start_workload(evsel_list); 978acf28922SNamhyung Kim 979435b46efSSong Liu t0 = rdclock(); 980435b46efSSong Liu clock_gettime(CLOCK_MONOTONIC, &ref_time); 981435b46efSSong Liu 982bb8bc52eSAdrián Herrera Arcila if (forks) { 98327e9769aSAlexey Budankov if (interval || timeout || evlist__ctlfd_initialized(evsel_list)) 984bee328cbSAlexey Budankov status = dispatch_events(forks, timeout, interval, ×); 985cfbd41b7SArnaldo Carvalho de Melo if (child_pid != -1) { 986cfbd41b7SArnaldo Carvalho de Melo if (timeout) 987cfbd41b7SArnaldo Carvalho de Melo kill(child_pid, SIGTERM); 9888897a891SJiri Olsa wait4(child_pid, &status, 0, &stat_config.ru_data); 989cfbd41b7SArnaldo Carvalho de Melo } 9906af206fdSArnaldo Carvalho de Melo 991f33cbe72SArnaldo Carvalho de Melo if (workload_exec_errno) { 992c8b5f2c9SArnaldo Carvalho de Melo const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); 993f33cbe72SArnaldo Carvalho de Melo pr_err("Workload failed: %s\n", emsg); 9946af206fdSArnaldo Carvalho de Melo return -1; 995f33cbe72SArnaldo Carvalho de Melo } 9966af206fdSArnaldo Carvalho de Melo 99733e49ea7SAndi Kleen if (WIFSIGNALED(status)) 99833e49ea7SAndi Kleen psignal(WTERMSIG(status), argv[0]); 99960666c63SLiming Wang } else { 1000bee328cbSAlexey Budankov status = dispatch_events(forks, timeout, interval, ×); 100160666c63SLiming Wang } 100286470930SIngo Molnar 10033df33effSMark Rutland disable_counters(); 10043df33effSMark Rutland 100586470930SIngo Molnar t1 = rdclock(); 100686470930SIngo Molnar 100754ac0b1bSJiri Olsa if (stat_config.walltime_run_table) 100854ac0b1bSJiri Olsa stat_config.walltime_run[run_idx] = t1 - t0; 1009e55c14afSJiri Olsa 1010ee6a9614SJin Yao if (interval && stat_config.summary) { 1011c7e5b328SJin Yao stat_config.interval = 0; 1012ee6a9614SJin Yao stat_config.stop_read_counter = true; 1013c7e5b328SJin Yao init_stats(&walltime_nsecs_stats); 1014c7e5b328SJin Yao update_stats(&walltime_nsecs_stats, t1 - t0); 1015c7e5b328SJin Yao 1016c7e5b328SJin Yao if (stat_config.aggr_mode == AGGR_GLOBAL) 101753f5e908SArnaldo Carvalho de Melo evlist__save_aggr_prev_raw_counts(evsel_list); 1018c7e5b328SJin Yao 101953f5e908SArnaldo Carvalho de Melo evlist__copy_prev_raw_counts(evsel_list); 102053f5e908SArnaldo Carvalho de Melo evlist__reset_prev_raw_counts(evsel_list); 1021c7e5b328SJin Yao runtime_stat_reset(&stat_config); 1022c7e5b328SJin Yao perf_stat__reset_shadow_per_stat(&rt_stat); 1023c735b0a5SFlorian Fischer } else { 10249e9772c4SPeter Zijlstra update_stats(&walltime_nsecs_stats, t1 - t0); 1025c735b0a5SFlorian Fischer update_rusage_stats(&ru_stats, &stat_config.ru_data); 1026c735b0a5SFlorian Fischer } 102742202dd5SIngo Molnar 10283df33effSMark Rutland /* 10293df33effSMark Rutland * Closing a group leader splits the group, and as we only disable 10303df33effSMark Rutland * group leaders, results in remaining events becoming enabled. To 10313df33effSMark Rutland * avoid arbitrary skew, we must read all counters before closing any 10323df33effSMark Rutland * group leaders. 10333df33effSMark Rutland */ 1034f0fbb114SAndi Kleen read_counters(&(struct timespec) { .tv_nsec = t1-t0 }); 103508ef3af1SJiri Olsa 103608ef3af1SJiri Olsa /* 103708ef3af1SJiri Olsa * We need to keep evsel_list alive, because it's processed 103808ef3af1SJiri Olsa * later the evsel_list will be closed after. 103908ef3af1SJiri Olsa */ 104008ef3af1SJiri Olsa if (!STAT_RECORD) 1041750b4edeSJiri Olsa evlist__close(evsel_list); 1042c52b12edSArnaldo Carvalho de Melo 104342202dd5SIngo Molnar return WEXITSTATUS(status); 104442202dd5SIngo Molnar } 104542202dd5SIngo Molnar 1046e55c14afSJiri Olsa static int run_perf_stat(int argc, const char **argv, int run_idx) 10471f16c575SPeter Zijlstra { 10481f16c575SPeter Zijlstra int ret; 10491f16c575SPeter Zijlstra 10501f16c575SPeter Zijlstra if (pre_cmd) { 10511f16c575SPeter Zijlstra ret = system(pre_cmd); 10521f16c575SPeter Zijlstra if (ret) 10531f16c575SPeter Zijlstra return ret; 10541f16c575SPeter Zijlstra } 10551f16c575SPeter Zijlstra 10561f16c575SPeter Zijlstra if (sync_run) 10571f16c575SPeter Zijlstra sync(); 10581f16c575SPeter Zijlstra 1059e55c14afSJiri Olsa ret = __run_perf_stat(argc, argv, run_idx); 10601f16c575SPeter Zijlstra if (ret) 10611f16c575SPeter Zijlstra return ret; 10621f16c575SPeter Zijlstra 10631f16c575SPeter Zijlstra if (post_cmd) { 10641f16c575SPeter Zijlstra ret = system(post_cmd); 10651f16c575SPeter Zijlstra if (ret) 10661f16c575SPeter Zijlstra return ret; 10671f16c575SPeter Zijlstra } 10681f16c575SPeter Zijlstra 10691f16c575SPeter Zijlstra return ret; 10701f16c575SPeter Zijlstra } 10711f16c575SPeter Zijlstra 1072a5a9eac1SJiri Olsa static void print_counters(struct timespec *ts, int argc, const char **argv) 1073a5a9eac1SJiri Olsa { 10740174820aSJiri Olsa /* Do not print anything if we record to the pipe. */ 10750174820aSJiri Olsa if (STAT_RECORD && perf_stat.data.is_pipe) 10760174820aSJiri Olsa return; 107755a4de94SAndi Kleen if (stat_config.quiet) 107855a4de94SAndi Kleen return; 10790174820aSJiri Olsa 108071273724SArnaldo Carvalho de Melo evlist__print_counters(evsel_list, &stat_config, &target, ts, argc, argv); 1081a5a9eac1SJiri Olsa } 1082a5a9eac1SJiri Olsa 1083f7b7c26eSPeter Zijlstra static volatile int signr = -1; 1084f7b7c26eSPeter Zijlstra 108586470930SIngo Molnar static void skip_signal(int signo) 108686470930SIngo Molnar { 1087ec0d3d1fSJiri Olsa if ((child_pid == -1) || stat_config.interval) 108860666c63SLiming Wang done = 1; 108960666c63SLiming Wang 1090f7b7c26eSPeter Zijlstra signr = signo; 1091d07f0b12SStephane Eranian /* 1092d07f0b12SStephane Eranian * render child_pid harmless 1093d07f0b12SStephane Eranian * won't send SIGTERM to a random 1094d07f0b12SStephane Eranian * process in case of race condition 1095d07f0b12SStephane Eranian * and fast PID recycling 1096d07f0b12SStephane Eranian */ 1097d07f0b12SStephane Eranian child_pid = -1; 1098f7b7c26eSPeter Zijlstra } 1099f7b7c26eSPeter Zijlstra 1100f7b7c26eSPeter Zijlstra static void sig_atexit(void) 1101f7b7c26eSPeter Zijlstra { 1102d07f0b12SStephane Eranian sigset_t set, oset; 1103d07f0b12SStephane Eranian 1104d07f0b12SStephane Eranian /* 1105d07f0b12SStephane Eranian * avoid race condition with SIGCHLD handler 1106d07f0b12SStephane Eranian * in skip_signal() which is modifying child_pid 1107d07f0b12SStephane Eranian * goal is to avoid send SIGTERM to a random 1108d07f0b12SStephane Eranian * process 1109d07f0b12SStephane Eranian */ 1110d07f0b12SStephane Eranian sigemptyset(&set); 1111d07f0b12SStephane Eranian sigaddset(&set, SIGCHLD); 1112d07f0b12SStephane Eranian sigprocmask(SIG_BLOCK, &set, &oset); 1113d07f0b12SStephane Eranian 1114933da83aSChris Wilson if (child_pid != -1) 1115933da83aSChris Wilson kill(child_pid, SIGTERM); 1116933da83aSChris Wilson 1117d07f0b12SStephane Eranian sigprocmask(SIG_SETMASK, &oset, NULL); 1118d07f0b12SStephane Eranian 1119f7b7c26eSPeter Zijlstra if (signr == -1) 1120f7b7c26eSPeter Zijlstra return; 1121f7b7c26eSPeter Zijlstra 1122f7b7c26eSPeter Zijlstra signal(signr, SIG_DFL); 1123f7b7c26eSPeter Zijlstra kill(getpid(), signr); 112486470930SIngo Molnar } 112586470930SIngo Molnar 1126d778a778SPaul A. Clarke void perf_stat__set_big_num(int set) 1127d778a778SPaul A. Clarke { 1128d778a778SPaul A. Clarke stat_config.big_num = (set != 0); 1129d778a778SPaul A. Clarke } 1130d778a778SPaul A. Clarke 11310bdad978SJin Yao void perf_stat__set_no_csv_summary(int set) 11320bdad978SJin Yao { 11330bdad978SJin Yao stat_config.no_csv_summary = (set != 0); 11340bdad978SJin Yao } 11350bdad978SJin Yao 11361d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused, 11371d037ca1SIrina Tirdea const char *s __maybe_unused, int unset) 1138d7470b6aSStephane Eranian { 1139d7470b6aSStephane Eranian big_num_opt = unset ? 0 : 1; 1140d778a778SPaul A. Clarke perf_stat__set_big_num(!unset); 1141d7470b6aSStephane Eranian return 0; 1142d7470b6aSStephane Eranian } 1143d7470b6aSStephane Eranian 114444b1e60aSAndi Kleen static int enable_metric_only(const struct option *opt __maybe_unused, 114544b1e60aSAndi Kleen const char *s __maybe_unused, int unset) 114644b1e60aSAndi Kleen { 114744b1e60aSAndi Kleen force_metric_only = true; 11480ce5aa02SJiri Olsa stat_config.metric_only = !unset; 114944b1e60aSAndi Kleen return 0; 115044b1e60aSAndi Kleen } 115144b1e60aSAndi Kleen 1152*a4b8cfcaSIan Rogers static int append_metric_groups(const struct option *opt __maybe_unused, 1153b18f3e36SAndi Kleen const char *str, 1154b18f3e36SAndi Kleen int unset __maybe_unused) 1155b18f3e36SAndi Kleen { 1156*a4b8cfcaSIan Rogers if (metrics) { 1157*a4b8cfcaSIan Rogers char *tmp; 1158*a4b8cfcaSIan Rogers 1159*a4b8cfcaSIan Rogers if (asprintf(&tmp, "%s,%s", metrics, str) < 0) 1160*a4b8cfcaSIan Rogers return -ENOMEM; 1161*a4b8cfcaSIan Rogers free(metrics); 1162*a4b8cfcaSIan Rogers metrics = tmp; 1163*a4b8cfcaSIan Rogers } else { 1164*a4b8cfcaSIan Rogers metrics = strdup(str); 1165*a4b8cfcaSIan Rogers if (!metrics) 1166*a4b8cfcaSIan Rogers return -ENOMEM; 1167*a4b8cfcaSIan Rogers } 1168*a4b8cfcaSIan Rogers return 0; 1169b18f3e36SAndi Kleen } 1170b18f3e36SAndi Kleen 117127e9769aSAlexey Budankov static int parse_control_option(const struct option *opt, 117227e9769aSAlexey Budankov const char *str, 117327e9769aSAlexey Budankov int unset __maybe_unused) 117427e9769aSAlexey Budankov { 11759864a66dSAdrian Hunter struct perf_stat_config *config = opt->value; 117627e9769aSAlexey Budankov 1177a8fcbd26SAdrian Hunter return evlist__parse_control(str, &config->ctl_fd, &config->ctl_fd_ack, &config->ctl_fd_close); 1178a8fcbd26SAdrian Hunter } 1179a8fcbd26SAdrian Hunter 1180d1c5a0e8SNamhyung Kim static int parse_stat_cgroups(const struct option *opt, 1181d1c5a0e8SNamhyung Kim const char *str, int unset) 1182d1c5a0e8SNamhyung Kim { 1183d1c5a0e8SNamhyung Kim if (stat_config.cgroup_list) { 1184d1c5a0e8SNamhyung Kim pr_err("--cgroup and --for-each-cgroup cannot be used together\n"); 1185d1c5a0e8SNamhyung Kim return -1; 1186d1c5a0e8SNamhyung Kim } 1187d1c5a0e8SNamhyung Kim 1188d1c5a0e8SNamhyung Kim return parse_cgroups(opt, str, unset); 1189d1c5a0e8SNamhyung Kim } 1190d1c5a0e8SNamhyung Kim 1191e69dc842SJin Yao static int parse_hybrid_type(const struct option *opt, 1192e69dc842SJin Yao const char *str, 1193e69dc842SJin Yao int unset __maybe_unused) 1194e69dc842SJin Yao { 1195e69dc842SJin Yao struct evlist *evlist = *(struct evlist **)opt->value; 1196e69dc842SJin Yao 1197e69dc842SJin Yao if (!list_empty(&evlist->core.entries)) { 1198e69dc842SJin Yao fprintf(stderr, "Must define cputype before events/metrics\n"); 1199e69dc842SJin Yao return -1; 1200e69dc842SJin Yao } 1201e69dc842SJin Yao 1202e69dc842SJin Yao evlist->hybrid_pmu_name = perf_pmu__hybrid_type_to_pmu(str); 1203e69dc842SJin Yao if (!evlist->hybrid_pmu_name) { 1204e69dc842SJin Yao fprintf(stderr, "--cputype %s is not supported!\n", str); 1205e69dc842SJin Yao return -1; 1206e69dc842SJin Yao } 1207e69dc842SJin Yao 1208e69dc842SJin Yao return 0; 1209e69dc842SJin Yao } 1210e69dc842SJin Yao 121151433eadSMichael Petlan static struct option stat_options[] = { 1212e0547311SJiri Olsa OPT_BOOLEAN('T', "transaction", &transaction_run, 1213e0547311SJiri Olsa "hardware transaction statistics"), 1214e0547311SJiri Olsa OPT_CALLBACK('e', "event", &evsel_list, "event", 1215e0547311SJiri Olsa "event selector. use 'perf list' to list available events", 1216e0547311SJiri Olsa parse_events_option), 1217e0547311SJiri Olsa OPT_CALLBACK(0, "filter", &evsel_list, "filter", 1218e0547311SJiri Olsa "event filter", parse_filter), 12195698f26bSJiri Olsa OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit, 1220e0547311SJiri Olsa "child tasks do not inherit counters"), 1221e0547311SJiri Olsa OPT_STRING('p', "pid", &target.pid, "pid", 1222e0547311SJiri Olsa "stat events on existing process id"), 1223e0547311SJiri Olsa OPT_STRING('t', "tid", &target.tid, "tid", 1224e0547311SJiri Olsa "stat events on existing thread id"), 1225fa853c4bSSong Liu #ifdef HAVE_BPF_SKEL 1226fa853c4bSSong Liu OPT_STRING('b', "bpf-prog", &target.bpf_str, "bpf-prog-id", 1227fa853c4bSSong Liu "stat events on existing bpf program id"), 12287fac83aaSSong Liu OPT_BOOLEAN(0, "bpf-counters", &target.use_bpf, 12297fac83aaSSong Liu "use bpf program to count events"), 12307fac83aaSSong Liu OPT_STRING(0, "bpf-attr-map", &target.attr_map, "attr-map-path", 12317fac83aaSSong Liu "path to perf_event_attr map"), 1232fa853c4bSSong Liu #endif 1233e0547311SJiri Olsa OPT_BOOLEAN('a', "all-cpus", &target.system_wide, 1234e0547311SJiri Olsa "system-wide collection from all CPUs"), 1235e0547311SJiri Olsa OPT_BOOLEAN('g', "group", &group, 1236e0547311SJiri Olsa "put the counters into a counter group"), 123775998bb2SAndi Kleen OPT_BOOLEAN(0, "scale", &stat_config.scale, 123875998bb2SAndi Kleen "Use --no-scale to disable counter scaling for multiplexing"), 1239e0547311SJiri Olsa OPT_INCR('v', "verbose", &verbose, 1240e0547311SJiri Olsa "be more verbose (show counter open errors, etc)"), 1241d97ae04bSJiri Olsa OPT_INTEGER('r', "repeat", &stat_config.run_count, 1242e0547311SJiri Olsa "repeat command and print average + stddev (max: 100, forever: 0)"), 124354ac0b1bSJiri Olsa OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table, 1244e55c14afSJiri Olsa "display details about each run (only with -r option)"), 1245aea0dca1SJiri Olsa OPT_BOOLEAN('n', "null", &stat_config.null_run, 1246e0547311SJiri Olsa "null run - dont start any counters"), 1247e0547311SJiri Olsa OPT_INCR('d', "detailed", &detailed_run, 1248e0547311SJiri Olsa "detailed run - start a lot of events"), 1249e0547311SJiri Olsa OPT_BOOLEAN('S', "sync", &sync_run, 1250e0547311SJiri Olsa "call sync() before starting a run"), 1251e0547311SJiri Olsa OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 1252e0547311SJiri Olsa "print large numbers with thousands\' separators", 1253e0547311SJiri Olsa stat__set_big_num), 1254e0547311SJiri Olsa OPT_STRING('C', "cpu", &target.cpu_list, "cpu", 1255e0547311SJiri Olsa "list of cpus to monitor in system-wide"), 1256e0547311SJiri Olsa OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode, 1257e0547311SJiri Olsa "disable CPU count aggregation", AGGR_NONE), 1258fdee335bSJiri Olsa OPT_BOOLEAN(0, "no-merge", &stat_config.no_merge, "Do not merge identical named events"), 12592c8e6451SZhengjun Xing OPT_BOOLEAN(0, "hybrid-merge", &stat_config.hybrid_merge, 12602c8e6451SZhengjun Xing "Merge identical named hybrid events"), 1261fa7070a3SJiri Olsa OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator", 1262e0547311SJiri Olsa "print counts with custom separator"), 1263df936cadSClaire Jensen OPT_BOOLEAN('j', "json-output", &stat_config.json_output, 1264df936cadSClaire Jensen "print counts in JSON format"), 1265e0547311SJiri Olsa OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1266d1c5a0e8SNamhyung Kim "monitor event in cgroup name only", parse_stat_cgroups), 1267d1c5a0e8SNamhyung Kim OPT_STRING(0, "for-each-cgroup", &stat_config.cgroup_list, "name", 1268d1c5a0e8SNamhyung Kim "expand events for each cgroup"), 1269e0547311SJiri Olsa OPT_STRING('o', "output", &output_name, "file", "output file name"), 1270e0547311SJiri Olsa OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), 1271e0547311SJiri Olsa OPT_INTEGER(0, "log-fd", &output_fd, 1272e0547311SJiri Olsa "log output to fd, instead of stderr"), 1273e0547311SJiri Olsa OPT_STRING(0, "pre", &pre_cmd, "command", 1274e0547311SJiri Olsa "command to run prior to the measured command"), 1275e0547311SJiri Olsa OPT_STRING(0, "post", &post_cmd, "command", 1276e0547311SJiri Olsa "command to run after to the measured command"), 1277e0547311SJiri Olsa OPT_UINTEGER('I', "interval-print", &stat_config.interval, 12789dc9a95fSAlexey Budankov "print counts at regular interval in ms " 12799dc9a95fSAlexey Budankov "(overhead is possible for values <= 100ms)"), 1280db06a269Syuzhoujian OPT_INTEGER(0, "interval-count", &stat_config.times, 1281db06a269Syuzhoujian "print counts for fixed number of times"), 1282132c6ba3SJiri Olsa OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear, 12839660e08eSJiri Olsa "clear screen in between new interval"), 1284f1f8ad52Syuzhoujian OPT_UINTEGER(0, "timeout", &stat_config.timeout, 1285f1f8ad52Syuzhoujian "stop workload and print counts after a timeout period in ms (>= 10ms)"), 1286e0547311SJiri Olsa OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode, 1287e0547311SJiri Olsa "aggregate counts per processor socket", AGGR_SOCKET), 1288db5742b6SKan Liang OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode, 1289db5742b6SKan Liang "aggregate counts per processor die", AGGR_DIE), 1290e0547311SJiri Olsa OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode, 1291e0547311SJiri Olsa "aggregate counts per physical processor core", AGGR_CORE), 1292e0547311SJiri Olsa OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode, 1293e0547311SJiri Olsa "aggregate counts per thread", AGGR_THREAD), 129486895b48SJiri Olsa OPT_SET_UINT(0, "per-node", &stat_config.aggr_mode, 129586895b48SJiri Olsa "aggregate counts per numa node", AGGR_NODE), 12962162b9c6SAlexey Budankov OPT_INTEGER('D', "delay", &stat_config.initial_delay, 12972162b9c6SAlexey Budankov "ms to wait before starting measurement after program start (-1: start with events disabled)"), 12980ce5aa02SJiri Olsa OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL, 129944b1e60aSAndi Kleen "Only print computed metrics. No raw values", enable_metric_only), 130005530a79SIan Rogers OPT_BOOLEAN(0, "metric-no-group", &stat_config.metric_no_group, 130105530a79SIan Rogers "don't group metric events, impacts multiplexing"), 130205530a79SIan Rogers OPT_BOOLEAN(0, "metric-no-merge", &stat_config.metric_no_merge, 130305530a79SIan Rogers "don't try to share events between metrics in a group"), 130444b1e60aSAndi Kleen OPT_BOOLEAN(0, "topdown", &topdown_run, 130563e39aa6SKan Liang "measure top-down statistics"), 130663e39aa6SKan Liang OPT_UINTEGER(0, "td-level", &stat_config.topdown_level, 130763e39aa6SKan Liang "Set the metrics level for the top-down statistics (0: max level)"), 1308daefd0bcSKan Liang OPT_BOOLEAN(0, "smi-cost", &smi_cost, 1309daefd0bcSKan Liang "measure SMI cost"), 1310b18f3e36SAndi Kleen OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list", 1311b18f3e36SAndi Kleen "monitor specified metrics or metric groups (separated by ,)", 1312*a4b8cfcaSIan Rogers append_metric_groups), 1313dd071024SJin Yao OPT_BOOLEAN_FLAG(0, "all-kernel", &stat_config.all_kernel, 1314dd071024SJin Yao "Configure all used events to run in kernel space.", 1315dd071024SJin Yao PARSE_OPT_EXCLUSIVE), 1316dd071024SJin Yao OPT_BOOLEAN_FLAG(0, "all-user", &stat_config.all_user, 1317dd071024SJin Yao "Configure all used events to run in user space.", 1318dd071024SJin Yao PARSE_OPT_EXCLUSIVE), 13191af62ce6SJin Yao OPT_BOOLEAN(0, "percore-show-thread", &stat_config.percore_show_thread, 13201af62ce6SJin Yao "Use with 'percore' event qualifier to show the event " 13211af62ce6SJin Yao "counts of one hardware thread by sum up total hardware " 13221af62ce6SJin Yao "threads of same physical core"), 1323ee6a9614SJin Yao OPT_BOOLEAN(0, "summary", &stat_config.summary, 1324ee6a9614SJin Yao "print summary for interval mode"), 13250bdad978SJin Yao OPT_BOOLEAN(0, "no-csv-summary", &stat_config.no_csv_summary, 13260bdad978SJin Yao "don't print 'summary' for CSV summary output"), 132755a4de94SAndi Kleen OPT_BOOLEAN(0, "quiet", &stat_config.quiet, 132855a4de94SAndi Kleen "don't print output (useful with record)"), 1329e69dc842SJin Yao OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type", 1330e69dc842SJin Yao "Only enable events on applying cpu with this type " 1331e69dc842SJin Yao "for hybrid platform (e.g. core or atom)", 1332e69dc842SJin Yao parse_hybrid_type), 133370943490SStephane Eranian #ifdef HAVE_LIBPFM 133470943490SStephane Eranian OPT_CALLBACK(0, "pfm-events", &evsel_list, "event", 133570943490SStephane Eranian "libpfm4 event selector. use 'perf list' to list available events", 133670943490SStephane Eranian parse_libpfm_events_option), 133770943490SStephane Eranian #endif 1338a8fcbd26SAdrian Hunter OPT_CALLBACK(0, "control", &stat_config, "fd:ctl-fd[,ack-fd] or fifo:ctl-fifo[,ack-fifo]", 133927e9769aSAlexey Budankov "Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events).\n" 1340a8fcbd26SAdrian Hunter "\t\t\t Optionally send control command completion ('ack\\n') to ack-fd descriptor.\n" 1341a8fcbd26SAdrian Hunter "\t\t\t Alternatively, ctl-fifo / ack-fifo will be opened and used as ctl-fd / ack-fd.", 134227e9769aSAlexey Budankov parse_control_option), 1343f07952b1SAlexander Antonov OPT_CALLBACK_OPTARG(0, "iostat", &evsel_list, &stat_config, "default", 1344f07952b1SAlexander Antonov "measure I/O performance metrics provided by arch/platform", 1345f07952b1SAlexander Antonov iostat_parse), 1346e0547311SJiri Olsa OPT_END() 1347e0547311SJiri Olsa }; 1348e0547311SJiri Olsa 13495f50e15cSIan Rogers static const char *const aggr_mode__string[] = { 13505f50e15cSIan Rogers [AGGR_CORE] = "core", 13515f50e15cSIan Rogers [AGGR_DIE] = "die", 13525f50e15cSIan Rogers [AGGR_GLOBAL] = "global", 13535f50e15cSIan Rogers [AGGR_NODE] = "node", 13545f50e15cSIan Rogers [AGGR_NONE] = "none", 13555f50e15cSIan Rogers [AGGR_SOCKET] = "socket", 13565f50e15cSIan Rogers [AGGR_THREAD] = "thread", 13575f50e15cSIan Rogers [AGGR_UNSET] = "unset", 13585f50e15cSIan Rogers }; 13595f50e15cSIan Rogers 13602760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_socket(struct perf_stat_config *config __maybe_unused, 13616d18804bSIan Rogers struct perf_cpu cpu) 13621fe7a300SJiri Olsa { 1363973aeb3cSIan Rogers return aggr_cpu_id__socket(cpu, /*data=*/NULL); 13641fe7a300SJiri Olsa } 13651fe7a300SJiri Olsa 13662760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_die(struct perf_stat_config *config __maybe_unused, 13676d18804bSIan Rogers struct perf_cpu cpu) 1368db5742b6SKan Liang { 1369973aeb3cSIan Rogers return aggr_cpu_id__die(cpu, /*data=*/NULL); 1370db5742b6SKan Liang } 1371db5742b6SKan Liang 13722760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused, 13736d18804bSIan Rogers struct perf_cpu cpu) 13741fe7a300SJiri Olsa { 1375973aeb3cSIan Rogers return aggr_cpu_id__core(cpu, /*data=*/NULL); 13761fe7a300SJiri Olsa } 13771fe7a300SJiri Olsa 13782760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_node(struct perf_stat_config *config __maybe_unused, 13796d18804bSIan Rogers struct perf_cpu cpu) 138086895b48SJiri Olsa { 1381973aeb3cSIan Rogers return aggr_cpu_id__node(cpu, /*data=*/NULL); 138286895b48SJiri Olsa } 138386895b48SJiri Olsa 13842760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config, 13856d18804bSIan Rogers aggr_get_id_t get_id, struct perf_cpu cpu) 13861e5a2931SJiri Olsa { 138751b826faSIan Rogers struct aggr_cpu_id id = aggr_cpu_id__empty(); 13881e5a2931SJiri Olsa 13896d18804bSIan Rogers if (aggr_cpu_id__is_empty(&config->cpus_aggr_map->map[cpu.cpu])) 13906d18804bSIan Rogers config->cpus_aggr_map->map[cpu.cpu] = get_id(config, cpu); 13911e5a2931SJiri Olsa 13926d18804bSIan Rogers id = config->cpus_aggr_map->map[cpu.cpu]; 13932760f5a1SJames Clark return id; 13941e5a2931SJiri Olsa } 13951e5a2931SJiri Olsa 13962760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_socket_cached(struct perf_stat_config *config, 13976d18804bSIan Rogers struct perf_cpu cpu) 13981e5a2931SJiri Olsa { 139988031a0dSIan Rogers return perf_stat__get_aggr(config, perf_stat__get_socket, cpu); 14001e5a2931SJiri Olsa } 14011e5a2931SJiri Olsa 14022760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *config, 14036d18804bSIan Rogers struct perf_cpu cpu) 1404db5742b6SKan Liang { 140588031a0dSIan Rogers return perf_stat__get_aggr(config, perf_stat__get_die, cpu); 1406db5742b6SKan Liang } 1407db5742b6SKan Liang 14082760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_core_cached(struct perf_stat_config *config, 14096d18804bSIan Rogers struct perf_cpu cpu) 14101e5a2931SJiri Olsa { 141188031a0dSIan Rogers return perf_stat__get_aggr(config, perf_stat__get_core, cpu); 14121e5a2931SJiri Olsa } 14131e5a2931SJiri Olsa 14142760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_node_cached(struct perf_stat_config *config, 14156d18804bSIan Rogers struct perf_cpu cpu) 141686895b48SJiri Olsa { 141788031a0dSIan Rogers return perf_stat__get_aggr(config, perf_stat__get_node, cpu); 141886895b48SJiri Olsa } 141986895b48SJiri Olsa 14204fc4d8dfSJin Yao static bool term_percore_set(void) 14214fc4d8dfSJin Yao { 142232dcd021SJiri Olsa struct evsel *counter; 14234fc4d8dfSJin Yao 14244fc4d8dfSJin Yao evlist__for_each_entry(evsel_list, counter) { 14254fc4d8dfSJin Yao if (counter->percore) 14264fc4d8dfSJin Yao return true; 14274fc4d8dfSJin Yao } 14284fc4d8dfSJin Yao 14294fc4d8dfSJin Yao return false; 14304fc4d8dfSJin Yao } 14314fc4d8dfSJin Yao 14325f50e15cSIan Rogers static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode) 143386ee6e18SStephane Eranian { 14345f50e15cSIan Rogers switch (aggr_mode) { 143586ee6e18SStephane Eranian case AGGR_SOCKET: 1436973aeb3cSIan Rogers return aggr_cpu_id__socket; 1437db5742b6SKan Liang case AGGR_DIE: 1438973aeb3cSIan Rogers return aggr_cpu_id__die; 143912c08a9fSStephane Eranian case AGGR_CORE: 1440973aeb3cSIan Rogers return aggr_cpu_id__core; 144186895b48SJiri Olsa case AGGR_NODE: 1442973aeb3cSIan Rogers return aggr_cpu_id__node; 144386ee6e18SStephane Eranian case AGGR_NONE: 14445f50e15cSIan Rogers if (term_percore_set()) 1445973aeb3cSIan Rogers return aggr_cpu_id__core; 14465f50e15cSIan Rogers 14475f50e15cSIan Rogers return NULL; 144886ee6e18SStephane Eranian case AGGR_GLOBAL: 144932b8af82SJiri Olsa case AGGR_THREAD: 1450208df99eSJiri Olsa case AGGR_UNSET: 1451df936cadSClaire Jensen case AGGR_MAX: 145286ee6e18SStephane Eranian default: 14535f50e15cSIan Rogers return NULL; 14545f50e15cSIan Rogers } 14555f50e15cSIan Rogers } 14565f50e15cSIan Rogers 14575f50e15cSIan Rogers static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode) 14585f50e15cSIan Rogers { 14595f50e15cSIan Rogers switch (aggr_mode) { 14605f50e15cSIan Rogers case AGGR_SOCKET: 14615f50e15cSIan Rogers return perf_stat__get_socket_cached; 14625f50e15cSIan Rogers case AGGR_DIE: 14635f50e15cSIan Rogers return perf_stat__get_die_cached; 14645f50e15cSIan Rogers case AGGR_CORE: 14655f50e15cSIan Rogers return perf_stat__get_core_cached; 14665f50e15cSIan Rogers case AGGR_NODE: 14675f50e15cSIan Rogers return perf_stat__get_node_cached; 14685f50e15cSIan Rogers case AGGR_NONE: 14695f50e15cSIan Rogers if (term_percore_set()) { 14705f50e15cSIan Rogers return perf_stat__get_core_cached; 14715f50e15cSIan Rogers } 14725f50e15cSIan Rogers return NULL; 14735f50e15cSIan Rogers case AGGR_GLOBAL: 14745f50e15cSIan Rogers case AGGR_THREAD: 14755f50e15cSIan Rogers case AGGR_UNSET: 1476df936cadSClaire Jensen case AGGR_MAX: 14775f50e15cSIan Rogers default: 14785f50e15cSIan Rogers return NULL; 14795f50e15cSIan Rogers } 14805f50e15cSIan Rogers } 14815f50e15cSIan Rogers 14825f50e15cSIan Rogers static int perf_stat_init_aggr_mode(void) 14835f50e15cSIan Rogers { 14845f50e15cSIan Rogers int nr; 14855f50e15cSIan Rogers aggr_cpu_id_get_t get_id = aggr_mode__get_aggr(stat_config.aggr_mode); 14865f50e15cSIan Rogers 14875f50e15cSIan Rogers if (get_id) { 14880df6ade7SIan Rogers stat_config.aggr_map = cpu_aggr_map__new(evsel_list->core.user_requested_cpus, 14895f50e15cSIan Rogers get_id, /*data=*/NULL); 14905f50e15cSIan Rogers if (!stat_config.aggr_map) { 14915f50e15cSIan Rogers pr_err("cannot build %s map", aggr_mode__string[stat_config.aggr_mode]); 14925f50e15cSIan Rogers return -1; 14935f50e15cSIan Rogers } 14945f50e15cSIan Rogers stat_config.aggr_get_id = aggr_mode__get_id(stat_config.aggr_mode); 149586ee6e18SStephane Eranian } 14961e5a2931SJiri Olsa 14971e5a2931SJiri Olsa /* 14981e5a2931SJiri Olsa * The evsel_list->cpus is the base we operate on, 14991e5a2931SJiri Olsa * taking the highest cpu number to be the size of 15001e5a2931SJiri Olsa * the aggregation translate cpumap. 15011e5a2931SJiri Olsa */ 15020df6ade7SIan Rogers if (evsel_list->core.user_requested_cpus) 15030df6ade7SIan Rogers nr = perf_cpu_map__max(evsel_list->core.user_requested_cpus).cpu; 15048a96f454SIan Rogers else 15058a96f454SIan Rogers nr = 0; 1506d526e1a0SJames Clark stat_config.cpus_aggr_map = cpu_aggr_map__empty_new(nr + 1); 15076f6b6594SJiri Olsa return stat_config.cpus_aggr_map ? 0 : -ENOMEM; 150886ee6e18SStephane Eranian } 150986ee6e18SStephane Eranian 1510d526e1a0SJames Clark static void cpu_aggr_map__delete(struct cpu_aggr_map *map) 1511d526e1a0SJames Clark { 1512d526e1a0SJames Clark if (map) { 1513d526e1a0SJames Clark WARN_ONCE(refcount_read(&map->refcnt) != 0, 1514d526e1a0SJames Clark "cpu_aggr_map refcnt unbalanced\n"); 1515d526e1a0SJames Clark free(map); 1516d526e1a0SJames Clark } 1517d526e1a0SJames Clark } 1518d526e1a0SJames Clark 1519d526e1a0SJames Clark static void cpu_aggr_map__put(struct cpu_aggr_map *map) 1520d526e1a0SJames Clark { 1521d526e1a0SJames Clark if (map && refcount_dec_and_test(&map->refcnt)) 1522d526e1a0SJames Clark cpu_aggr_map__delete(map); 1523d526e1a0SJames Clark } 1524d526e1a0SJames Clark 1525544c2ae7SMasami Hiramatsu static void perf_stat__exit_aggr_mode(void) 1526544c2ae7SMasami Hiramatsu { 1527d526e1a0SJames Clark cpu_aggr_map__put(stat_config.aggr_map); 1528d526e1a0SJames Clark cpu_aggr_map__put(stat_config.cpus_aggr_map); 15296f6b6594SJiri Olsa stat_config.aggr_map = NULL; 15306f6b6594SJiri Olsa stat_config.cpus_aggr_map = NULL; 1531544c2ae7SMasami Hiramatsu } 1532544c2ae7SMasami Hiramatsu 15336d18804bSIan Rogers static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(struct perf_cpu cpu, void *data) 153468d702f7SJiri Olsa { 153568d702f7SJiri Olsa struct perf_env *env = data; 153651b826faSIan Rogers struct aggr_cpu_id id = aggr_cpu_id__empty(); 153768d702f7SJiri Olsa 15386d18804bSIan Rogers if (cpu.cpu != -1) 15396d18804bSIan Rogers id.socket = env->cpu[cpu.cpu].socket_id; 15402760f5a1SJames Clark 15412760f5a1SJames Clark return id; 154268d702f7SJiri Olsa } 154368d702f7SJiri Olsa 15446d18804bSIan Rogers static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(struct perf_cpu cpu, void *data) 1545db5742b6SKan Liang { 1546db5742b6SKan Liang struct perf_env *env = data; 154751b826faSIan Rogers struct aggr_cpu_id id = aggr_cpu_id__empty(); 1548db5742b6SKan Liang 15496d18804bSIan Rogers if (cpu.cpu != -1) { 1550db5742b6SKan Liang /* 15511a270cb6SJames Clark * die_id is relative to socket, so start 15521a270cb6SJames Clark * with the socket ID and then add die to 15531a270cb6SJames Clark * make a unique ID. 1554db5742b6SKan Liang */ 15556d18804bSIan Rogers id.socket = env->cpu[cpu.cpu].socket_id; 15566d18804bSIan Rogers id.die = env->cpu[cpu.cpu].die_id; 1557db5742b6SKan Liang } 1558db5742b6SKan Liang 15592760f5a1SJames Clark return id; 1560db5742b6SKan Liang } 1561db5742b6SKan Liang 15626d18804bSIan Rogers static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, void *data) 156368d702f7SJiri Olsa { 156468d702f7SJiri Olsa struct perf_env *env = data; 156551b826faSIan Rogers struct aggr_cpu_id id = aggr_cpu_id__empty(); 156668d702f7SJiri Olsa 15676d18804bSIan Rogers if (cpu.cpu != -1) { 156868d702f7SJiri Olsa /* 1569db5742b6SKan Liang * core_id is relative to socket and die, 1570b9933817SJames Clark * we need a global id. So we set 1571b9933817SJames Clark * socket, die id and core id 157268d702f7SJiri Olsa */ 15736d18804bSIan Rogers id.socket = env->cpu[cpu.cpu].socket_id; 15746d18804bSIan Rogers id.die = env->cpu[cpu.cpu].die_id; 15756d18804bSIan Rogers id.core = env->cpu[cpu.cpu].core_id; 157668d702f7SJiri Olsa } 157768d702f7SJiri Olsa 15782760f5a1SJames Clark return id; 157968d702f7SJiri Olsa } 158068d702f7SJiri Olsa 15816d18804bSIan Rogers static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(struct perf_cpu cpu, void *data) 158288031a0dSIan Rogers { 158351b826faSIan Rogers struct aggr_cpu_id id = aggr_cpu_id__empty(); 158486895b48SJiri Olsa 1585fcd83a35SJames Clark id.node = perf_env__numa_node(data, cpu); 15862760f5a1SJames Clark return id; 158786895b48SJiri Olsa } 158886895b48SJiri Olsa 15892760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused, 15906d18804bSIan Rogers struct perf_cpu cpu) 159168d702f7SJiri Olsa { 159288031a0dSIan Rogers return perf_env__get_socket_aggr_by_cpu(cpu, &perf_stat.session->header.env); 159368d702f7SJiri Olsa } 15942760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused, 15956d18804bSIan Rogers struct perf_cpu cpu) 1596db5742b6SKan Liang { 159788031a0dSIan Rogers return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env); 1598db5742b6SKan Liang } 159968d702f7SJiri Olsa 16002760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused, 16016d18804bSIan Rogers struct perf_cpu cpu) 160268d702f7SJiri Olsa { 160388031a0dSIan Rogers return perf_env__get_core_aggr_by_cpu(cpu, &perf_stat.session->header.env); 160468d702f7SJiri Olsa } 160568d702f7SJiri Olsa 16062760f5a1SJames Clark static struct aggr_cpu_id perf_stat__get_node_file(struct perf_stat_config *config __maybe_unused, 16076d18804bSIan Rogers struct perf_cpu cpu) 160886895b48SJiri Olsa { 160988031a0dSIan Rogers return perf_env__get_node_aggr_by_cpu(cpu, &perf_stat.session->header.env); 161086895b48SJiri Olsa } 161186895b48SJiri Olsa 16125f50e15cSIan Rogers static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode) 161368d702f7SJiri Olsa { 16145f50e15cSIan Rogers switch (aggr_mode) { 161568d702f7SJiri Olsa case AGGR_SOCKET: 16165f50e15cSIan Rogers return perf_env__get_socket_aggr_by_cpu; 1617db5742b6SKan Liang case AGGR_DIE: 16185f50e15cSIan Rogers return perf_env__get_die_aggr_by_cpu; 161968d702f7SJiri Olsa case AGGR_CORE: 16205f50e15cSIan Rogers return perf_env__get_core_aggr_by_cpu; 162186895b48SJiri Olsa case AGGR_NODE: 16225f50e15cSIan Rogers return perf_env__get_node_aggr_by_cpu; 162368d702f7SJiri Olsa case AGGR_NONE: 162468d702f7SJiri Olsa case AGGR_GLOBAL: 162568d702f7SJiri Olsa case AGGR_THREAD: 162668d702f7SJiri Olsa case AGGR_UNSET: 1627df936cadSClaire Jensen case AGGR_MAX: 162868d702f7SJiri Olsa default: 16295f50e15cSIan Rogers return NULL; 16305f50e15cSIan Rogers } 163168d702f7SJiri Olsa } 163268d702f7SJiri Olsa 16335f50e15cSIan Rogers static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode) 16345f50e15cSIan Rogers { 16355f50e15cSIan Rogers switch (aggr_mode) { 16365f50e15cSIan Rogers case AGGR_SOCKET: 16375f50e15cSIan Rogers return perf_stat__get_socket_file; 16385f50e15cSIan Rogers case AGGR_DIE: 16395f50e15cSIan Rogers return perf_stat__get_die_file; 16405f50e15cSIan Rogers case AGGR_CORE: 16415f50e15cSIan Rogers return perf_stat__get_core_file; 16425f50e15cSIan Rogers case AGGR_NODE: 16435f50e15cSIan Rogers return perf_stat__get_node_file; 16445f50e15cSIan Rogers case AGGR_NONE: 16455f50e15cSIan Rogers case AGGR_GLOBAL: 16465f50e15cSIan Rogers case AGGR_THREAD: 16475f50e15cSIan Rogers case AGGR_UNSET: 1648df936cadSClaire Jensen case AGGR_MAX: 16495f50e15cSIan Rogers default: 16505f50e15cSIan Rogers return NULL; 16515f50e15cSIan Rogers } 16525f50e15cSIan Rogers } 16535f50e15cSIan Rogers 16545f50e15cSIan Rogers static int perf_stat_init_aggr_mode_file(struct perf_stat *st) 16555f50e15cSIan Rogers { 16565f50e15cSIan Rogers struct perf_env *env = &st->session->header.env; 16575f50e15cSIan Rogers aggr_cpu_id_get_t get_id = aggr_mode__get_aggr_file(stat_config.aggr_mode); 16585f50e15cSIan Rogers 16595f50e15cSIan Rogers if (!get_id) 16605f50e15cSIan Rogers return 0; 16615f50e15cSIan Rogers 16620df6ade7SIan Rogers stat_config.aggr_map = cpu_aggr_map__new(evsel_list->core.user_requested_cpus, get_id, env); 16635f50e15cSIan Rogers if (!stat_config.aggr_map) { 16645f50e15cSIan Rogers pr_err("cannot build %s map", aggr_mode__string[stat_config.aggr_mode]); 16655f50e15cSIan Rogers return -1; 16665f50e15cSIan Rogers } 16675f50e15cSIan Rogers stat_config.aggr_get_id = aggr_mode__get_id_file(stat_config.aggr_mode); 166868d702f7SJiri Olsa return 0; 166968d702f7SJiri Olsa } 167068d702f7SJiri Olsa 16712cba3ffbSIngo Molnar /* 16722cba3ffbSIngo Molnar * Add default attributes, if there were no attributes specified or 16732cba3ffbSIngo Molnar * if -d/--detailed, -d -d or -d -d -d is used: 16742cba3ffbSIngo Molnar */ 16752cba3ffbSIngo Molnar static int add_default_attributes(void) 16762cba3ffbSIngo Molnar { 167744b1e60aSAndi Kleen int err; 16789dec4473SAndi Kleen struct perf_event_attr default_attrs0[] = { 1679b070a547SArnaldo Carvalho de Melo 1680b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 1681b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, 1682b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, 1683b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 1684b070a547SArnaldo Carvalho de Melo 1685b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 16869dec4473SAndi Kleen }; 16879dec4473SAndi Kleen struct perf_event_attr frontend_attrs[] = { 1688b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 16899dec4473SAndi Kleen }; 16909dec4473SAndi Kleen struct perf_event_attr backend_attrs[] = { 1691b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 16929dec4473SAndi Kleen }; 16939dec4473SAndi Kleen struct perf_event_attr default_attrs1[] = { 1694b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 1695b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 1696b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 1697b070a547SArnaldo Carvalho de Melo 1698b070a547SArnaldo Carvalho de Melo }; 1699b070a547SArnaldo Carvalho de Melo 1700b070a547SArnaldo Carvalho de Melo /* 1701b070a547SArnaldo Carvalho de Melo * Detailed stats (-d), covering the L1 and last level data caches: 1702b070a547SArnaldo Carvalho de Melo */ 1703b070a547SArnaldo Carvalho de Melo struct perf_event_attr detailed_attrs[] = { 1704b070a547SArnaldo Carvalho de Melo 1705b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1706b070a547SArnaldo Carvalho de Melo .config = 1707b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1708b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1709b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1710b070a547SArnaldo Carvalho de Melo 1711b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1712b070a547SArnaldo Carvalho de Melo .config = 1713b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1714b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1715b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1716b070a547SArnaldo Carvalho de Melo 1717b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1718b070a547SArnaldo Carvalho de Melo .config = 1719b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1720b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1721b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1722b070a547SArnaldo Carvalho de Melo 1723b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1724b070a547SArnaldo Carvalho de Melo .config = 1725b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_LL << 0 | 1726b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1727b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1728b070a547SArnaldo Carvalho de Melo }; 1729b070a547SArnaldo Carvalho de Melo 1730b070a547SArnaldo Carvalho de Melo /* 1731b070a547SArnaldo Carvalho de Melo * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: 1732b070a547SArnaldo Carvalho de Melo */ 1733b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_detailed_attrs[] = { 1734b070a547SArnaldo Carvalho de Melo 1735b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1736b070a547SArnaldo Carvalho de Melo .config = 1737b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1I << 0 | 1738b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1739b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 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_L1I << 0 | 1744b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1745b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 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_DTLB << 0 | 1750b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1751b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1752b070a547SArnaldo Carvalho de Melo 1753b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1754b070a547SArnaldo Carvalho de Melo .config = 1755b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_DTLB << 0 | 1756b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1757b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1758b070a547SArnaldo Carvalho de Melo 1759b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1760b070a547SArnaldo Carvalho de Melo .config = 1761b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1762b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1763b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1764b070a547SArnaldo Carvalho de Melo 1765b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1766b070a547SArnaldo Carvalho de Melo .config = 1767b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_ITLB << 0 | 1768b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_READ << 8) | 1769b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1770b070a547SArnaldo Carvalho de Melo 1771b070a547SArnaldo Carvalho de Melo }; 1772b070a547SArnaldo Carvalho de Melo 1773b070a547SArnaldo Carvalho de Melo /* 1774b070a547SArnaldo Carvalho de Melo * Very, very detailed stats (-d -d -d), adding prefetch events: 1775b070a547SArnaldo Carvalho de Melo */ 1776b070a547SArnaldo Carvalho de Melo struct perf_event_attr very_very_detailed_attrs[] = { 1777b070a547SArnaldo Carvalho de Melo 1778b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1779b070a547SArnaldo Carvalho de Melo .config = 1780b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1781b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1782b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, 1783b070a547SArnaldo Carvalho de Melo 1784b070a547SArnaldo Carvalho de Melo { .type = PERF_TYPE_HW_CACHE, 1785b070a547SArnaldo Carvalho de Melo .config = 1786b070a547SArnaldo Carvalho de Melo PERF_COUNT_HW_CACHE_L1D << 0 | 1787b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | 1788b070a547SArnaldo Carvalho de Melo (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, 1789b070a547SArnaldo Carvalho de Melo }; 1790a9c1ecdaSKan Liang 1791a9c1ecdaSKan Liang struct perf_event_attr default_null_attrs[] = {}; 1792a9c1ecdaSKan Liang 17932cba3ffbSIngo Molnar /* Set attrs if no event is selected and !null_run: */ 1794aea0dca1SJiri Olsa if (stat_config.null_run) 17952cba3ffbSIngo Molnar return 0; 17962cba3ffbSIngo Molnar 17974cabc3d1SAndi Kleen if (transaction_run) { 179807eafd4eSIan Rogers struct parse_events_error errinfo; 1799742d92ffSThomas Richter /* Handle -T as -M transaction. Once platform specific metrics 18004d39c89fSIngo Molnar * support has been added to the json files, all architectures 1801742d92ffSThomas Richter * will use this approach. To determine transaction support 1802742d92ffSThomas Richter * on an architecture test for such a metric name. 1803742d92ffSThomas Richter */ 1804742d92ffSThomas Richter if (metricgroup__has_metric("transaction")) { 1805*a4b8cfcaSIan Rogers return metricgroup__parse_groups(evsel_list, "transaction", 180605530a79SIan Rogers stat_config.metric_no_group, 180705530a79SIan Rogers stat_config.metric_no_merge, 1808d0192fdbSJiri Olsa &stat_config.metric_events); 1809742d92ffSThomas Richter } 1810742d92ffSThomas Richter 181107eafd4eSIan Rogers parse_events_error__init(&errinfo); 18124cabc3d1SAndi Kleen if (pmu_have_event("cpu", "cycles-ct") && 18134cabc3d1SAndi Kleen pmu_have_event("cpu", "el-start")) 1814fca32340SThomas Richter err = parse_events(evsel_list, transaction_attrs, 1815fca32340SThomas Richter &errinfo); 18164cabc3d1SAndi Kleen else 1817fca32340SThomas Richter err = parse_events(evsel_list, 1818fca32340SThomas Richter transaction_limited_attrs, 1819fca32340SThomas Richter &errinfo); 1820a454742cSJiri Olsa if (err) { 18214cabc3d1SAndi Kleen fprintf(stderr, "Cannot set up transaction events\n"); 18226c191289SIan Rogers parse_events_error__print(&errinfo, transaction_attrs); 18234cabc3d1SAndi Kleen } 182407eafd4eSIan Rogers parse_events_error__exit(&errinfo); 182507eafd4eSIan Rogers return err ? -1 : 0; 18264cabc3d1SAndi Kleen } 18274cabc3d1SAndi Kleen 1828daefd0bcSKan Liang if (smi_cost) { 182907eafd4eSIan Rogers struct parse_events_error errinfo; 1830daefd0bcSKan Liang int smi; 1831daefd0bcSKan Liang 1832daefd0bcSKan Liang if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) { 1833daefd0bcSKan Liang fprintf(stderr, "freeze_on_smi is not supported.\n"); 1834daefd0bcSKan Liang return -1; 1835daefd0bcSKan Liang } 1836daefd0bcSKan Liang 1837daefd0bcSKan Liang if (!smi) { 1838daefd0bcSKan Liang if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) { 1839daefd0bcSKan Liang fprintf(stderr, "Failed to set freeze_on_smi.\n"); 1840daefd0bcSKan Liang return -1; 1841daefd0bcSKan Liang } 1842daefd0bcSKan Liang smi_reset = true; 1843daefd0bcSKan Liang } 1844daefd0bcSKan Liang 184507eafd4eSIan Rogers if (!pmu_have_event("msr", "aperf") || 184607eafd4eSIan Rogers !pmu_have_event("msr", "smi")) { 1847daefd0bcSKan Liang fprintf(stderr, "To measure SMI cost, it needs " 1848daefd0bcSKan Liang "msr/aperf/, msr/smi/ and cpu/cycles/ support\n"); 1849daefd0bcSKan Liang return -1; 1850daefd0bcSKan Liang } 185107eafd4eSIan Rogers if (!force_metric_only) 185207eafd4eSIan Rogers stat_config.metric_only = true; 185307eafd4eSIan Rogers 185407eafd4eSIan Rogers parse_events_error__init(&errinfo); 185507eafd4eSIan Rogers err = parse_events(evsel_list, smi_cost_attrs, &errinfo); 1856daefd0bcSKan Liang if (err) { 18576c191289SIan Rogers parse_events_error__print(&errinfo, smi_cost_attrs); 1858daefd0bcSKan Liang fprintf(stderr, "Cannot set up SMI cost events\n"); 1859daefd0bcSKan Liang } 186007eafd4eSIan Rogers parse_events_error__exit(&errinfo); 186107eafd4eSIan Rogers return err ? -1 : 0; 1862daefd0bcSKan Liang } 1863daefd0bcSKan Liang 186444b1e60aSAndi Kleen if (topdown_run) { 186563e39aa6SKan Liang const char **metric_attrs = topdown_metric_attrs; 186663e39aa6SKan Liang unsigned int max_level = 1; 186744b1e60aSAndi Kleen char *str = NULL; 186844b1e60aSAndi Kleen bool warn = false; 18699a0b3626SZhengjun Xing const char *pmu_name = arch_get_topdown_pmu_name(evsel_list, true); 187044b1e60aSAndi Kleen 187155c36a9fSAndi Kleen if (!force_metric_only) 187255c36a9fSAndi Kleen stat_config.metric_only = true; 187355c36a9fSAndi Kleen 1874d7e3c397SZhengjun Xing if (pmu_have_event(pmu_name, topdown_metric_L2_attrs[5])) { 187563e39aa6SKan Liang metric_attrs = topdown_metric_L2_attrs; 187663e39aa6SKan Liang max_level = 2; 187763e39aa6SKan Liang } 187863e39aa6SKan Liang 187963e39aa6SKan Liang if (stat_config.topdown_level > max_level) { 188063e39aa6SKan Liang pr_err("Invalid top-down metrics level. The max level is %u.\n", max_level); 188163e39aa6SKan Liang return -1; 188263e39aa6SKan Liang } else if (!stat_config.topdown_level) 188363e39aa6SKan Liang stat_config.topdown_level = max_level; 188463e39aa6SKan Liang 1885d7e3c397SZhengjun Xing if (topdown_filter_events(metric_attrs, &str, 1, pmu_name) < 0) { 188655c36a9fSAndi Kleen pr_err("Out of memory\n"); 188755c36a9fSAndi Kleen return -1; 188855c36a9fSAndi Kleen } 1889d7e3c397SZhengjun Xing 189063e39aa6SKan Liang if (metric_attrs[0] && str) { 189155c36a9fSAndi Kleen if (!stat_config.interval && !stat_config.metric_only) { 189255c36a9fSAndi Kleen fprintf(stat_config.output, 189355c36a9fSAndi Kleen "Topdown accuracy may decrease when measuring long periods.\n" 189455c36a9fSAndi Kleen "Please print the result regularly, e.g. -I1000\n"); 189555c36a9fSAndi Kleen } 189655c36a9fSAndi Kleen goto setup_metrics; 189755c36a9fSAndi Kleen } 189855c36a9fSAndi Kleen 189955c36a9fSAndi Kleen zfree(&str); 190055c36a9fSAndi Kleen 190144b1e60aSAndi Kleen if (stat_config.aggr_mode != AGGR_GLOBAL && 190244b1e60aSAndi Kleen stat_config.aggr_mode != AGGR_CORE) { 190344b1e60aSAndi Kleen pr_err("top down event configuration requires --per-core mode\n"); 190444b1e60aSAndi Kleen return -1; 190544b1e60aSAndi Kleen } 190644b1e60aSAndi Kleen stat_config.aggr_mode = AGGR_CORE; 190744b1e60aSAndi Kleen if (nr_cgroups || !target__has_cpu(&target)) { 190844b1e60aSAndi Kleen pr_err("top down event configuration requires system-wide mode (-a)\n"); 190944b1e60aSAndi Kleen return -1; 191044b1e60aSAndi Kleen } 191144b1e60aSAndi Kleen 191244b1e60aSAndi Kleen if (topdown_filter_events(topdown_attrs, &str, 1913d7e3c397SZhengjun Xing arch_topdown_check_group(&warn), 1914d7e3c397SZhengjun Xing pmu_name) < 0) { 191544b1e60aSAndi Kleen pr_err("Out of memory\n"); 191644b1e60aSAndi Kleen return -1; 191744b1e60aSAndi Kleen } 1918d7e3c397SZhengjun Xing 191944b1e60aSAndi Kleen if (topdown_attrs[0] && str) { 192007eafd4eSIan Rogers struct parse_events_error errinfo; 192144b1e60aSAndi Kleen if (warn) 192244b1e60aSAndi Kleen arch_topdown_group_warn(); 192355c36a9fSAndi Kleen setup_metrics: 192407eafd4eSIan Rogers parse_events_error__init(&errinfo); 1925a5cfa621SJiri Olsa err = parse_events(evsel_list, str, &errinfo); 192644b1e60aSAndi Kleen if (err) { 192744b1e60aSAndi Kleen fprintf(stderr, 192844b1e60aSAndi Kleen "Cannot set up top down events %s: %d\n", 192944b1e60aSAndi Kleen str, err); 19306c191289SIan Rogers parse_events_error__print(&errinfo, str); 193107eafd4eSIan Rogers parse_events_error__exit(&errinfo); 1932c74b0503SLeo Yan free(str); 193344b1e60aSAndi Kleen return -1; 193444b1e60aSAndi Kleen } 193507eafd4eSIan Rogers parse_events_error__exit(&errinfo); 193644b1e60aSAndi Kleen } else { 193744b1e60aSAndi Kleen fprintf(stderr, "System does not support topdown\n"); 193844b1e60aSAndi Kleen return -1; 193944b1e60aSAndi Kleen } 194044b1e60aSAndi Kleen free(str); 194144b1e60aSAndi Kleen } 194244b1e60aSAndi Kleen 1943f0c86a2bSZhengjun Xing if (!stat_config.topdown_level) 1944f0c86a2bSZhengjun Xing stat_config.topdown_level = TOPDOWN_MAX_LEVEL; 1945f0c86a2bSZhengjun Xing 19466484d2f9SJiri Olsa if (!evsel_list->core.nr_entries) { 1947a1f3d567SNamhyung Kim if (target__has_cpu(&target)) 1948a1f3d567SNamhyung Kim default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK; 1949a1f3d567SNamhyung Kim 1950e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, default_attrs0) < 0) 19519dec4473SAndi Kleen return -1; 19529dec4473SAndi Kleen if (pmu_have_event("cpu", "stalled-cycles-frontend")) { 1953e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, frontend_attrs) < 0) 19549dec4473SAndi Kleen return -1; 19559dec4473SAndi Kleen } 19569dec4473SAndi Kleen if (pmu_have_event("cpu", "stalled-cycles-backend")) { 1957e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, backend_attrs) < 0) 19589dec4473SAndi Kleen return -1; 19599dec4473SAndi Kleen } 1960e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, default_attrs1) < 0) 19612cba3ffbSIngo Molnar return -1; 1962a9c1ecdaSKan Liang /* Platform specific attrs */ 1963a9c1ecdaSKan Liang if (evlist__add_default_attrs(evsel_list, default_null_attrs) < 0) 196442641d6fSKan Liang return -1; 19652cba3ffbSIngo Molnar } 19662cba3ffbSIngo Molnar 19672cba3ffbSIngo Molnar /* Detailed events get appended to the event list: */ 19682cba3ffbSIngo Molnar 19692cba3ffbSIngo Molnar if (detailed_run < 1) 19702cba3ffbSIngo Molnar return 0; 19712cba3ffbSIngo Molnar 19722cba3ffbSIngo Molnar /* Append detailed run extra attributes: */ 1973e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) 19742cba3ffbSIngo Molnar return -1; 19752cba3ffbSIngo Molnar 19762cba3ffbSIngo Molnar if (detailed_run < 2) 19772cba3ffbSIngo Molnar return 0; 19782cba3ffbSIngo Molnar 19792cba3ffbSIngo Molnar /* Append very detailed run extra attributes: */ 1980e251abeeSArnaldo Carvalho de Melo if (evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) 19812cba3ffbSIngo Molnar return -1; 19822cba3ffbSIngo Molnar 19832cba3ffbSIngo Molnar if (detailed_run < 3) 19842cba3ffbSIngo Molnar return 0; 19852cba3ffbSIngo Molnar 19862cba3ffbSIngo Molnar /* Append very, very detailed run extra attributes: */ 1987e251abeeSArnaldo Carvalho de Melo return evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); 19882cba3ffbSIngo Molnar } 19892cba3ffbSIngo Molnar 19908a59f3ccSJiri Olsa static const char * const stat_record_usage[] = { 19914979d0c7SJiri Olsa "perf stat record [<options>]", 19924979d0c7SJiri Olsa NULL, 19934979d0c7SJiri Olsa }; 19944979d0c7SJiri Olsa 19953ba78bd0SJiri Olsa static void init_features(struct perf_session *session) 19963ba78bd0SJiri Olsa { 19973ba78bd0SJiri Olsa int feat; 19983ba78bd0SJiri Olsa 19993ba78bd0SJiri Olsa for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) 20003ba78bd0SJiri Olsa perf_header__set_feat(&session->header, feat); 20013ba78bd0SJiri Olsa 20028002a63fSJiri Olsa perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT); 20033ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_BUILD_ID); 20043ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); 20053ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 20063ba78bd0SJiri Olsa perf_header__clear_feat(&session->header, HEADER_AUXTRACE); 20073ba78bd0SJiri Olsa } 20083ba78bd0SJiri Olsa 20094979d0c7SJiri Olsa static int __cmd_record(int argc, const char **argv) 20104979d0c7SJiri Olsa { 20114979d0c7SJiri Olsa struct perf_session *session; 20128ceb41d7SJiri Olsa struct perf_data *data = &perf_stat.data; 20134979d0c7SJiri Olsa 20148a59f3ccSJiri Olsa argc = parse_options(argc, argv, stat_options, stat_record_usage, 20154979d0c7SJiri Olsa PARSE_OPT_STOP_AT_NON_OPTION); 20164979d0c7SJiri Olsa 20174979d0c7SJiri Olsa if (output_name) 20182d4f2799SJiri Olsa data->path = output_name; 20194979d0c7SJiri Olsa 2020d97ae04bSJiri Olsa if (stat_config.run_count != 1 || forever) { 2021e9d6db8eSJiri Olsa pr_err("Cannot use -r option with perf stat record.\n"); 2022e9d6db8eSJiri Olsa return -1; 2023e9d6db8eSJiri Olsa } 2024e9d6db8eSJiri Olsa 20252681bd85SNamhyung Kim session = perf_session__new(data, NULL); 20266ef81c55SMamatha Inamdar if (IS_ERR(session)) { 20276ef81c55SMamatha Inamdar pr_err("Perf session creation failed\n"); 20286ef81c55SMamatha Inamdar return PTR_ERR(session); 20294979d0c7SJiri Olsa } 20304979d0c7SJiri Olsa 20313ba78bd0SJiri Olsa init_features(session); 20323ba78bd0SJiri Olsa 20334979d0c7SJiri Olsa session->evlist = evsel_list; 20344979d0c7SJiri Olsa perf_stat.session = session; 20354979d0c7SJiri Olsa perf_stat.record = true; 20364979d0c7SJiri Olsa return argc; 20374979d0c7SJiri Olsa } 20384979d0c7SJiri Olsa 203989f1688aSJiri Olsa static int process_stat_round_event(struct perf_session *session, 204089f1688aSJiri Olsa union perf_event *event) 2041a56f9390SJiri Olsa { 204272932371SJiri Olsa struct perf_record_stat_round *stat_round = &event->stat_round; 204332dcd021SJiri Olsa struct evsel *counter; 2044a56f9390SJiri Olsa struct timespec tsh, *ts = NULL; 2045a56f9390SJiri Olsa const char **argv = session->header.env.cmdline_argv; 2046a56f9390SJiri Olsa int argc = session->header.env.nr_cmdline; 2047a56f9390SJiri Olsa 2048e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evsel_list, counter) 2049a56f9390SJiri Olsa perf_stat_process_counter(&stat_config, counter); 2050a56f9390SJiri Olsa 2051e3b03b6cSAndi Kleen if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL) 2052e3b03b6cSAndi Kleen update_stats(&walltime_nsecs_stats, stat_round->time); 2053a56f9390SJiri Olsa 2054e3b03b6cSAndi Kleen if (stat_config.interval && stat_round->time) { 2055bd48c63eSArnaldo Carvalho de Melo tsh.tv_sec = stat_round->time / NSEC_PER_SEC; 2056bd48c63eSArnaldo Carvalho de Melo tsh.tv_nsec = stat_round->time % NSEC_PER_SEC; 2057a56f9390SJiri Olsa ts = &tsh; 2058a56f9390SJiri Olsa } 2059a56f9390SJiri Olsa 2060a56f9390SJiri Olsa print_counters(ts, argc, argv); 2061a56f9390SJiri Olsa return 0; 2062a56f9390SJiri Olsa } 2063a56f9390SJiri Olsa 206462ba18baSJiri Olsa static 206589f1688aSJiri Olsa int process_stat_config_event(struct perf_session *session, 206689f1688aSJiri Olsa union perf_event *event) 206762ba18baSJiri Olsa { 206889f1688aSJiri Olsa struct perf_tool *tool = session->tool; 206968d702f7SJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 207068d702f7SJiri Olsa 207162ba18baSJiri Olsa perf_event__read_stat_config(&stat_config, &event->stat_config); 207268d702f7SJiri Olsa 2073315c0a1fSJiri Olsa if (perf_cpu_map__empty(st->cpus)) { 207489af4e05SJiri Olsa if (st->aggr_mode != AGGR_UNSET) 207589af4e05SJiri Olsa pr_warning("warning: processing task data, aggregation mode not set\n"); 207689af4e05SJiri Olsa return 0; 207789af4e05SJiri Olsa } 207889af4e05SJiri Olsa 207989af4e05SJiri Olsa if (st->aggr_mode != AGGR_UNSET) 208089af4e05SJiri Olsa stat_config.aggr_mode = st->aggr_mode; 208189af4e05SJiri Olsa 20828ceb41d7SJiri Olsa if (perf_stat.data.is_pipe) 208368d702f7SJiri Olsa perf_stat_init_aggr_mode(); 208468d702f7SJiri Olsa else 208568d702f7SJiri Olsa perf_stat_init_aggr_mode_file(st); 208668d702f7SJiri Olsa 208762ba18baSJiri Olsa return 0; 208862ba18baSJiri Olsa } 208962ba18baSJiri Olsa 20901975d36eSJiri Olsa static int set_maps(struct perf_stat *st) 20911975d36eSJiri Olsa { 20921975d36eSJiri Olsa if (!st->cpus || !st->threads) 20931975d36eSJiri Olsa return 0; 20941975d36eSJiri Olsa 20951975d36eSJiri Olsa if (WARN_ONCE(st->maps_allocated, "stats double allocation\n")) 20961975d36eSJiri Olsa return -EINVAL; 20971975d36eSJiri Olsa 2098453fa030SJiri Olsa perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads); 20991975d36eSJiri Olsa 210053f5e908SArnaldo Carvalho de Melo if (evlist__alloc_stats(evsel_list, true)) 21011975d36eSJiri Olsa return -ENOMEM; 21021975d36eSJiri Olsa 21031975d36eSJiri Olsa st->maps_allocated = true; 21041975d36eSJiri Olsa return 0; 21051975d36eSJiri Olsa } 21061975d36eSJiri Olsa 21071975d36eSJiri Olsa static 210889f1688aSJiri Olsa int process_thread_map_event(struct perf_session *session, 210989f1688aSJiri Olsa union perf_event *event) 21101975d36eSJiri Olsa { 211189f1688aSJiri Olsa struct perf_tool *tool = session->tool; 21121975d36eSJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 21131975d36eSJiri Olsa 21141975d36eSJiri Olsa if (st->threads) { 21151975d36eSJiri Olsa pr_warning("Extra thread map event, ignoring.\n"); 21161975d36eSJiri Olsa return 0; 21171975d36eSJiri Olsa } 21181975d36eSJiri Olsa 21191975d36eSJiri Olsa st->threads = thread_map__new_event(&event->thread_map); 21201975d36eSJiri Olsa if (!st->threads) 21211975d36eSJiri Olsa return -ENOMEM; 21221975d36eSJiri Olsa 21231975d36eSJiri Olsa return set_maps(st); 21241975d36eSJiri Olsa } 21251975d36eSJiri Olsa 21261975d36eSJiri Olsa static 212789f1688aSJiri Olsa int process_cpu_map_event(struct perf_session *session, 212889f1688aSJiri Olsa union perf_event *event) 21291975d36eSJiri Olsa { 213089f1688aSJiri Olsa struct perf_tool *tool = session->tool; 21311975d36eSJiri Olsa struct perf_stat *st = container_of(tool, struct perf_stat, tool); 2132f854839bSJiri Olsa struct perf_cpu_map *cpus; 21331975d36eSJiri Olsa 21341975d36eSJiri Olsa if (st->cpus) { 21351975d36eSJiri Olsa pr_warning("Extra cpu map event, ignoring.\n"); 21361975d36eSJiri Olsa return 0; 21371975d36eSJiri Olsa } 21381975d36eSJiri Olsa 21391975d36eSJiri Olsa cpus = cpu_map__new_data(&event->cpu_map.data); 21401975d36eSJiri Olsa if (!cpus) 21411975d36eSJiri Olsa return -ENOMEM; 21421975d36eSJiri Olsa 21431975d36eSJiri Olsa st->cpus = cpus; 21441975d36eSJiri Olsa return set_maps(st); 21451975d36eSJiri Olsa } 21461975d36eSJiri Olsa 21478a59f3ccSJiri Olsa static const char * const stat_report_usage[] = { 2148ba6039b6SJiri Olsa "perf stat report [<options>]", 2149ba6039b6SJiri Olsa NULL, 2150ba6039b6SJiri Olsa }; 2151ba6039b6SJiri Olsa 2152ba6039b6SJiri Olsa static struct perf_stat perf_stat = { 2153ba6039b6SJiri Olsa .tool = { 2154ba6039b6SJiri Olsa .attr = perf_event__process_attr, 2155fa6ea781SJiri Olsa .event_update = perf_event__process_event_update, 21561975d36eSJiri Olsa .thread_map = process_thread_map_event, 21571975d36eSJiri Olsa .cpu_map = process_cpu_map_event, 215862ba18baSJiri Olsa .stat_config = process_stat_config_event, 2159a56f9390SJiri Olsa .stat = perf_event__process_stat_event, 2160a56f9390SJiri Olsa .stat_round = process_stat_round_event, 2161ba6039b6SJiri Olsa }, 216289af4e05SJiri Olsa .aggr_mode = AGGR_UNSET, 2163ba6039b6SJiri Olsa }; 2164ba6039b6SJiri Olsa 2165ba6039b6SJiri Olsa static int __cmd_report(int argc, const char **argv) 2166ba6039b6SJiri Olsa { 2167ba6039b6SJiri Olsa struct perf_session *session; 2168ba6039b6SJiri Olsa const struct option options[] = { 2169ba6039b6SJiri Olsa OPT_STRING('i', "input", &input_name, "file", "input file name"), 217089af4e05SJiri Olsa OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode, 217189af4e05SJiri Olsa "aggregate counts per processor socket", AGGR_SOCKET), 2172db5742b6SKan Liang OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode, 2173db5742b6SKan Liang "aggregate counts per processor die", AGGR_DIE), 217489af4e05SJiri Olsa OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode, 217589af4e05SJiri Olsa "aggregate counts per physical processor core", AGGR_CORE), 217686895b48SJiri Olsa OPT_SET_UINT(0, "per-node", &perf_stat.aggr_mode, 217786895b48SJiri Olsa "aggregate counts per numa node", AGGR_NODE), 217889af4e05SJiri Olsa OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode, 217989af4e05SJiri Olsa "disable CPU count aggregation", AGGR_NONE), 2180ba6039b6SJiri Olsa OPT_END() 2181ba6039b6SJiri Olsa }; 2182ba6039b6SJiri Olsa struct stat st; 2183ba6039b6SJiri Olsa int ret; 2184ba6039b6SJiri Olsa 21858a59f3ccSJiri Olsa argc = parse_options(argc, argv, options, stat_report_usage, 0); 2186ba6039b6SJiri Olsa 2187ba6039b6SJiri Olsa if (!input_name || !strlen(input_name)) { 2188ba6039b6SJiri Olsa if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) 2189ba6039b6SJiri Olsa input_name = "-"; 2190ba6039b6SJiri Olsa else 2191ba6039b6SJiri Olsa input_name = "perf.data"; 2192ba6039b6SJiri Olsa } 2193ba6039b6SJiri Olsa 2194*a4b8cfcaSIan Rogers perf_stat__init_shadow_stats(); 2195*a4b8cfcaSIan Rogers 21962d4f2799SJiri Olsa perf_stat.data.path = input_name; 21978ceb41d7SJiri Olsa perf_stat.data.mode = PERF_DATA_MODE_READ; 2198ba6039b6SJiri Olsa 21992681bd85SNamhyung Kim session = perf_session__new(&perf_stat.data, &perf_stat.tool); 22006ef81c55SMamatha Inamdar if (IS_ERR(session)) 22016ef81c55SMamatha Inamdar return PTR_ERR(session); 2202ba6039b6SJiri Olsa 2203ba6039b6SJiri Olsa perf_stat.session = session; 2204ba6039b6SJiri Olsa stat_config.output = stderr; 2205ba6039b6SJiri Olsa evsel_list = session->evlist; 2206ba6039b6SJiri Olsa 2207ba6039b6SJiri Olsa ret = perf_session__process_events(session); 2208ba6039b6SJiri Olsa if (ret) 2209ba6039b6SJiri Olsa return ret; 2210ba6039b6SJiri Olsa 2211ba6039b6SJiri Olsa perf_session__delete(session); 2212ba6039b6SJiri Olsa return 0; 2213ba6039b6SJiri Olsa } 2214ba6039b6SJiri Olsa 2215e3ba76deSJiri Olsa static void setup_system_wide(int forks) 2216e3ba76deSJiri Olsa { 2217e3ba76deSJiri Olsa /* 2218e3ba76deSJiri Olsa * Make system wide (-a) the default target if 2219e3ba76deSJiri Olsa * no target was specified and one of following 2220e3ba76deSJiri Olsa * conditions is met: 2221e3ba76deSJiri Olsa * 2222e3ba76deSJiri Olsa * - there's no workload specified 2223e3ba76deSJiri Olsa * - there is workload specified but all requested 2224e3ba76deSJiri Olsa * events are system wide events 2225e3ba76deSJiri Olsa */ 2226e3ba76deSJiri Olsa if (!target__none(&target)) 2227e3ba76deSJiri Olsa return; 2228e3ba76deSJiri Olsa 2229e3ba76deSJiri Olsa if (!forks) 2230e3ba76deSJiri Olsa target.system_wide = true; 2231e3ba76deSJiri Olsa else { 223232dcd021SJiri Olsa struct evsel *counter; 2233e3ba76deSJiri Olsa 2234e3ba76deSJiri Olsa evlist__for_each_entry(evsel_list, counter) { 2235d3345fecSAdrian Hunter if (!counter->core.requires_cpu && 2236002a3d69SJin Yao strcmp(counter->name, "duration_time")) { 2237e3ba76deSJiri Olsa return; 2238e3ba76deSJiri Olsa } 2239002a3d69SJin Yao } 2240e3ba76deSJiri Olsa 22416484d2f9SJiri Olsa if (evsel_list->core.nr_entries) 2242e3ba76deSJiri Olsa target.system_wide = true; 2243e3ba76deSJiri Olsa } 2244e3ba76deSJiri Olsa } 2245e3ba76deSJiri Olsa 2246b0ad8ea6SArnaldo Carvalho de Melo int cmd_stat(int argc, const char **argv) 224786470930SIngo Molnar { 2248b070a547SArnaldo Carvalho de Melo const char * const stat_usage[] = { 2249b070a547SArnaldo Carvalho de Melo "perf stat [<options>] [<command>]", 2250b070a547SArnaldo Carvalho de Melo NULL 2251b070a547SArnaldo Carvalho de Melo }; 2252fa853c4bSSong Liu int status = -EINVAL, run_idx, err; 22534aa9015fSStephane Eranian const char *mode; 22545821522eSJiri Olsa FILE *output = stderr; 2255f1f8ad52Syuzhoujian unsigned int interval, timeout; 2256ba6039b6SJiri Olsa const char * const stat_subcommands[] = { "record", "report" }; 2257fa853c4bSSong Liu char errbuf[BUFSIZ]; 225842202dd5SIngo Molnar 22595af52b51SStephane Eranian setlocale(LC_ALL, ""); 22605af52b51SStephane Eranian 22610f98b11cSJiri Olsa evsel_list = evlist__new(); 2262361c99a6SArnaldo Carvalho de Melo if (evsel_list == NULL) 2263361c99a6SArnaldo Carvalho de Melo return -ENOMEM; 2264361c99a6SArnaldo Carvalho de Melo 22651669e509SWang Nan parse_events__shrink_config_terms(); 226651433eadSMichael Petlan 226751433eadSMichael Petlan /* String-parsing callback-based options would segfault when negated */ 226851433eadSMichael Petlan set_option_flag(stat_options, 'e', "event", PARSE_OPT_NONEG); 226951433eadSMichael Petlan set_option_flag(stat_options, 'M', "metrics", PARSE_OPT_NONEG); 227051433eadSMichael Petlan set_option_flag(stat_options, 'G', "cgroup", PARSE_OPT_NONEG); 227151433eadSMichael Petlan 22724979d0c7SJiri Olsa argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands, 22734979d0c7SJiri Olsa (const char **) stat_usage, 2274a0541234SAnton Blanchard PARSE_OPT_STOP_AT_NON_OPTION); 2275d7470b6aSStephane Eranian 2276fa7070a3SJiri Olsa if (stat_config.csv_sep) { 2277fa7070a3SJiri Olsa stat_config.csv_output = true; 2278fa7070a3SJiri Olsa if (!strcmp(stat_config.csv_sep, "\\t")) 2279fa7070a3SJiri Olsa stat_config.csv_sep = "\t"; 22806edb78a2SJiri Olsa } else 2281fa7070a3SJiri Olsa stat_config.csv_sep = DEFAULT_SEPARATOR; 22826edb78a2SJiri Olsa 2283ae0f4eb3SWei Li if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) { 22844979d0c7SJiri Olsa argc = __cmd_record(argc, argv); 22854979d0c7SJiri Olsa if (argc < 0) 22864979d0c7SJiri Olsa return -1; 2287ae0f4eb3SWei Li } else if (argc && strlen(argv[0]) > 2 && strstarts("report", argv[0])) 2288ba6039b6SJiri Olsa return __cmd_report(argc, argv); 22894979d0c7SJiri Olsa 2290ec0d3d1fSJiri Olsa interval = stat_config.interval; 2291f1f8ad52Syuzhoujian timeout = stat_config.timeout; 2292ec0d3d1fSJiri Olsa 22934979d0c7SJiri Olsa /* 22944979d0c7SJiri Olsa * For record command the -o is already taken care of. 22954979d0c7SJiri Olsa */ 22964979d0c7SJiri Olsa if (!STAT_RECORD && output_name && strcmp(output_name, "-")) 22974aa9015fSStephane Eranian output = NULL; 22984aa9015fSStephane Eranian 229956f3bae7SJim Cromie if (output_name && output_fd) { 230056f3bae7SJim Cromie fprintf(stderr, "cannot use both --output and --log-fd\n"); 2301e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "o", 1); 2302e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "log-fd", 0); 2303cc03c542SNamhyung Kim goto out; 230456f3bae7SJim Cromie } 2305fc3e4d07SStephane Eranian 23060ce5aa02SJiri Olsa if (stat_config.metric_only && stat_config.aggr_mode == AGGR_THREAD) { 230754b50916SAndi Kleen fprintf(stderr, "--metric-only is not supported with --per-thread\n"); 230854b50916SAndi Kleen goto out; 230954b50916SAndi Kleen } 231054b50916SAndi Kleen 2311d97ae04bSJiri Olsa if (stat_config.metric_only && stat_config.run_count > 1) { 231254b50916SAndi Kleen fprintf(stderr, "--metric-only is not supported with -r\n"); 231354b50916SAndi Kleen goto out; 231454b50916SAndi Kleen } 231554b50916SAndi Kleen 231654ac0b1bSJiri Olsa if (stat_config.walltime_run_table && stat_config.run_count <= 1) { 2317e55c14afSJiri Olsa fprintf(stderr, "--table is only supported with -r\n"); 2318e55c14afSJiri Olsa parse_options_usage(stat_usage, stat_options, "r", 1); 2319e55c14afSJiri Olsa parse_options_usage(NULL, stat_options, "table", 0); 2320e55c14afSJiri Olsa goto out; 2321e55c14afSJiri Olsa } 2322e55c14afSJiri Olsa 2323fc3e4d07SStephane Eranian if (output_fd < 0) { 2324fc3e4d07SStephane Eranian fprintf(stderr, "argument to --log-fd must be a > 0\n"); 2325e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "log-fd", 0); 2326cc03c542SNamhyung Kim goto out; 2327fc3e4d07SStephane Eranian } 2328fc3e4d07SStephane Eranian 232955a4de94SAndi Kleen if (!output && !stat_config.quiet) { 23304aa9015fSStephane Eranian struct timespec tm; 23314aa9015fSStephane Eranian mode = append_file ? "a" : "w"; 23324aa9015fSStephane Eranian 23334aa9015fSStephane Eranian output = fopen(output_name, mode); 23344aa9015fSStephane Eranian if (!output) { 23354aa9015fSStephane Eranian perror("failed to create output file"); 2336fceda7feSDavid Ahern return -1; 23374aa9015fSStephane Eranian } 23384aa9015fSStephane Eranian clock_gettime(CLOCK_REALTIME, &tm); 23394aa9015fSStephane Eranian fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); 2340fc3e4d07SStephane Eranian } else if (output_fd > 0) { 234156f3bae7SJim Cromie mode = append_file ? "a" : "w"; 234256f3bae7SJim Cromie output = fdopen(output_fd, mode); 234356f3bae7SJim Cromie if (!output) { 234456f3bae7SJim Cromie perror("Failed opening logfd"); 234556f3bae7SJim Cromie return -errno; 234656f3bae7SJim Cromie } 23474aa9015fSStephane Eranian } 23484aa9015fSStephane Eranian 23495821522eSJiri Olsa stat_config.output = output; 23505821522eSJiri Olsa 2351d7470b6aSStephane Eranian /* 2352d7470b6aSStephane Eranian * let the spreadsheet do the pretty-printing 2353d7470b6aSStephane Eranian */ 2354fa7070a3SJiri Olsa if (stat_config.csv_output) { 235561a9f324SJim Cromie /* User explicitly passed -B? */ 2356d7470b6aSStephane Eranian if (big_num_opt == 1) { 2357d7470b6aSStephane Eranian fprintf(stderr, "-B option not supported with -x\n"); 2358e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "B", 1); 2359e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "x", 1); 2360cc03c542SNamhyung Kim goto out; 2361d7470b6aSStephane Eranian } else /* Nope, so disable big number formatting */ 236234ff0866SJiri Olsa stat_config.big_num = false; 2363d7470b6aSStephane Eranian } else if (big_num_opt == 0) /* User passed --no-big-num */ 236434ff0866SJiri Olsa stat_config.big_num = false; 2365d7470b6aSStephane Eranian 2366fa853c4bSSong Liu err = target__validate(&target); 2367fa853c4bSSong Liu if (err) { 2368fa853c4bSSong Liu target__strerror(&target, err, errbuf, BUFSIZ); 2369fa853c4bSSong Liu pr_warning("%s\n", errbuf); 2370fa853c4bSSong Liu } 2371fa853c4bSSong Liu 2372e3ba76deSJiri Olsa setup_system_wide(argc); 2373ac3063bdSDavid Ahern 23740ce2da14SJiri Olsa /* 23750ce2da14SJiri Olsa * Display user/system times only for single 23760ce2da14SJiri Olsa * run and when there's specified tracee. 23770ce2da14SJiri Olsa */ 2378d97ae04bSJiri Olsa if ((stat_config.run_count == 1) && target__none(&target)) 23798897a891SJiri Olsa stat_config.ru_display = true; 23800ce2da14SJiri Olsa 2381d97ae04bSJiri Olsa if (stat_config.run_count < 0) { 2382cc03c542SNamhyung Kim pr_err("Run count must be a positive number\n"); 2383e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "r", 1); 2384cc03c542SNamhyung Kim goto out; 2385d97ae04bSJiri Olsa } else if (stat_config.run_count == 0) { 2386a7e191c3SFrederik Deweerdt forever = true; 2387d97ae04bSJiri Olsa stat_config.run_count = 1; 2388a7e191c3SFrederik Deweerdt } 238986470930SIngo Molnar 239054ac0b1bSJiri Olsa if (stat_config.walltime_run_table) { 239154ac0b1bSJiri Olsa stat_config.walltime_run = zalloc(stat_config.run_count * sizeof(stat_config.walltime_run[0])); 239254ac0b1bSJiri Olsa if (!stat_config.walltime_run) { 2393e55c14afSJiri Olsa pr_err("failed to setup -r option"); 2394e55c14afSJiri Olsa goto out; 2395e55c14afSJiri Olsa } 2396e55c14afSJiri Olsa } 2397e55c14afSJiri Olsa 23981d9f8d1bSJin Yao if ((stat_config.aggr_mode == AGGR_THREAD) && 23991d9f8d1bSJin Yao !target__has_task(&target)) { 24001d9f8d1bSJin Yao if (!target.system_wide || target.cpu_list) { 24011d9f8d1bSJin Yao fprintf(stderr, "The --per-thread option is only " 24021d9f8d1bSJin Yao "available when monitoring via -p -t -a " 24031d9f8d1bSJin Yao "options or only --per-thread.\n"); 2404e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "p", 1); 2405e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "t", 1); 240632b8af82SJiri Olsa goto out; 240732b8af82SJiri Olsa } 24081d9f8d1bSJin Yao } 240932b8af82SJiri Olsa 241032b8af82SJiri Olsa /* 241132b8af82SJiri Olsa * no_aggr, cgroup are for system-wide only 241232b8af82SJiri Olsa * --per-thread is aggregated per thread, we dont mix it with cpu mode 241332b8af82SJiri Olsa */ 2414421a50f3SJiri Olsa if (((stat_config.aggr_mode != AGGR_GLOBAL && 24151c02f6c9SNamhyung Kim stat_config.aggr_mode != AGGR_THREAD) || 24161c02f6c9SNamhyung Kim (nr_cgroups || stat_config.cgroup_list)) && 2417602ad878SArnaldo Carvalho de Melo !target__has_cpu(&target)) { 2418023695d9SStephane Eranian fprintf(stderr, "both cgroup and no-aggregation " 2419023695d9SStephane Eranian "modes only available in system-wide mode\n"); 2420023695d9SStephane Eranian 2421e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "G", 1); 2422e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "A", 1); 2423e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "a", 1); 24241c02f6c9SNamhyung Kim parse_options_usage(NULL, stat_options, "for-each-cgroup", 0); 2425cc03c542SNamhyung Kim goto out; 2426d7e7a451SStephane Eranian } 2427d7e7a451SStephane Eranian 2428f07952b1SAlexander Antonov if (stat_config.iostat_run) { 2429f07952b1SAlexander Antonov status = iostat_prepare(evsel_list, &stat_config); 2430f07952b1SAlexander Antonov if (status) 2431f07952b1SAlexander Antonov goto out; 2432f07952b1SAlexander Antonov if (iostat_mode == IOSTAT_LIST) { 2433f07952b1SAlexander Antonov iostat_list(evsel_list, &stat_config); 2434f07952b1SAlexander Antonov goto out; 2435f07952b1SAlexander Antonov } else if (verbose) 2436f07952b1SAlexander Antonov iostat_list(evsel_list, &stat_config); 2437e4fe5d73SLike Xu if (iostat_mode == IOSTAT_RUN && !target__has_cpu(&target)) 2438e4fe5d73SLike Xu target.system_wide = true; 2439f07952b1SAlexander Antonov } 2440f07952b1SAlexander Antonov 2441*a4b8cfcaSIan Rogers if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide)) 2442*a4b8cfcaSIan Rogers target.per_thread = true; 2443*a4b8cfcaSIan Rogers 2444*a4b8cfcaSIan Rogers /* 2445*a4b8cfcaSIan Rogers * Metric parsing needs to be delayed as metrics may optimize events 2446*a4b8cfcaSIan Rogers * knowing the target is system-wide. 2447*a4b8cfcaSIan Rogers */ 2448*a4b8cfcaSIan Rogers if (metrics) { 2449*a4b8cfcaSIan Rogers metricgroup__parse_groups(evsel_list, metrics, 2450*a4b8cfcaSIan Rogers stat_config.metric_no_group, 2451*a4b8cfcaSIan Rogers stat_config.metric_no_merge, 2452*a4b8cfcaSIan Rogers &stat_config.metric_events); 2453*a4b8cfcaSIan Rogers zfree(&metrics); 2454*a4b8cfcaSIan Rogers } 2455*a4b8cfcaSIan Rogers perf_stat__collect_metric_expr(evsel_list); 2456*a4b8cfcaSIan Rogers perf_stat__init_shadow_stats(); 2457*a4b8cfcaSIan Rogers 24582cba3ffbSIngo Molnar if (add_default_attributes()) 2459c6264defSIngo Molnar goto out; 246086470930SIngo Molnar 2461d1c5a0e8SNamhyung Kim if (stat_config.cgroup_list) { 2462d1c5a0e8SNamhyung Kim if (nr_cgroups > 0) { 2463d1c5a0e8SNamhyung Kim pr_err("--cgroup and --for-each-cgroup cannot be used together\n"); 2464d1c5a0e8SNamhyung Kim parse_options_usage(stat_usage, stat_options, "G", 1); 2465d1c5a0e8SNamhyung Kim parse_options_usage(NULL, stat_options, "for-each-cgroup", 0); 2466d1c5a0e8SNamhyung Kim goto out; 2467d1c5a0e8SNamhyung Kim } 2468d1c5a0e8SNamhyung Kim 2469b214ba8cSNamhyung Kim if (evlist__expand_cgroup(evsel_list, stat_config.cgroup_list, 2470bb1c15b6SNamhyung Kim &stat_config.metric_events, true) < 0) { 2471bb1c15b6SNamhyung Kim parse_options_usage(stat_usage, stat_options, 2472bb1c15b6SNamhyung Kim "for-each-cgroup", 0); 2473d1c5a0e8SNamhyung Kim goto out; 2474d1c5a0e8SNamhyung Kim } 2475bb1c15b6SNamhyung Kim } 2476d1c5a0e8SNamhyung Kim 24771d3351e6SJin Yao if (evlist__fix_hybrid_cpus(evsel_list, target.cpu_list)) { 24781d3351e6SJin Yao pr_err("failed to use cpu list %s\n", target.cpu_list); 24791d3351e6SJin Yao goto out; 24801d3351e6SJin Yao } 24811d3351e6SJin Yao 24821d3351e6SJin Yao target.hybrid = perf_pmu__has_hybrid(); 24837748bb71SArnaldo Carvalho de Melo if (evlist__create_maps(evsel_list, &target) < 0) { 2484602ad878SArnaldo Carvalho de Melo if (target__has_task(&target)) { 24855c98d466SArnaldo Carvalho de Melo pr_err("Problems finding threads of monitor\n"); 2486e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "p", 1); 2487e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "t", 1); 2488602ad878SArnaldo Carvalho de Melo } else if (target__has_cpu(&target)) { 248960d567e2SArnaldo Carvalho de Melo perror("failed to parse CPUs map"); 2490e0547311SJiri Olsa parse_options_usage(stat_usage, stat_options, "C", 1); 2491e0547311SJiri Olsa parse_options_usage(NULL, stat_options, "a", 1); 2492cc03c542SNamhyung Kim } 2493cc03c542SNamhyung Kim goto out; 249460d567e2SArnaldo Carvalho de Melo } 249532b8af82SJiri Olsa 2496a9a17902SJiri Olsa evlist__check_cpu_maps(evsel_list); 2497a9a17902SJiri Olsa 249832b8af82SJiri Olsa /* 249932b8af82SJiri Olsa * Initialize thread_map with comm names, 250032b8af82SJiri Olsa * so we could print it out on output. 250132b8af82SJiri Olsa */ 250256739444SJin Yao if (stat_config.aggr_mode == AGGR_THREAD) { 250303617c22SJiri Olsa thread_map__read_comms(evsel_list->core.threads); 250456739444SJin Yao if (target.system_wide) { 250556739444SJin Yao if (runtime_stat_new(&stat_config, 2506a2f354e3SJiri Olsa perf_thread_map__nr(evsel_list->core.threads))) { 250756739444SJin Yao goto out; 250856739444SJin Yao } 250956739444SJin Yao } 251056739444SJin Yao } 251132b8af82SJiri Olsa 251286895b48SJiri Olsa if (stat_config.aggr_mode == AGGR_NODE) 251386895b48SJiri Olsa cpu__setup_cpunode_map(); 251486895b48SJiri Olsa 2515db06a269Syuzhoujian if (stat_config.times && interval) 2516db06a269Syuzhoujian interval_count = true; 2517db06a269Syuzhoujian else if (stat_config.times && !interval) { 2518db06a269Syuzhoujian pr_err("interval-count option should be used together with " 2519db06a269Syuzhoujian "interval-print.\n"); 2520db06a269Syuzhoujian parse_options_usage(stat_usage, stat_options, "interval-count", 0); 2521db06a269Syuzhoujian parse_options_usage(stat_usage, stat_options, "I", 1); 2522db06a269Syuzhoujian goto out; 2523db06a269Syuzhoujian } 2524c45c6ea2SStephane Eranian 2525f1f8ad52Syuzhoujian if (timeout && timeout < 100) { 2526f1f8ad52Syuzhoujian if (timeout < 10) { 2527f1f8ad52Syuzhoujian pr_err("timeout must be >= 10ms.\n"); 2528f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "timeout", 0); 2529f1f8ad52Syuzhoujian goto out; 2530f1f8ad52Syuzhoujian } else 2531f1f8ad52Syuzhoujian pr_warning("timeout < 100ms. " 2532f1f8ad52Syuzhoujian "The overhead percentage could be high in some cases. " 2533f1f8ad52Syuzhoujian "Please proceed with caution.\n"); 2534f1f8ad52Syuzhoujian } 2535f1f8ad52Syuzhoujian if (timeout && interval) { 2536f1f8ad52Syuzhoujian pr_err("timeout option is not supported with interval-print.\n"); 2537f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "timeout", 0); 2538f1f8ad52Syuzhoujian parse_options_usage(stat_usage, stat_options, "I", 1); 2539f1f8ad52Syuzhoujian goto out; 2540f1f8ad52Syuzhoujian } 2541f1f8ad52Syuzhoujian 254253f5e908SArnaldo Carvalho de Melo if (evlist__alloc_stats(evsel_list, interval)) 254303ad9747SArnaldo Carvalho de Melo goto out; 2544d6d901c2SZhang, Yanmin 254586ee6e18SStephane Eranian if (perf_stat_init_aggr_mode()) 254603ad9747SArnaldo Carvalho de Melo goto out; 254786ee6e18SStephane Eranian 254886470930SIngo Molnar /* 25497d9ad16aSJiri Olsa * Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless 25507d9ad16aSJiri Olsa * while avoiding that older tools show confusing messages. 25517d9ad16aSJiri Olsa * 25527d9ad16aSJiri Olsa * However for pipe sessions we need to keep it zero, 25537d9ad16aSJiri Olsa * because script's perf_evsel__check_attr is triggered 25547d9ad16aSJiri Olsa * by attr->sample_type != 0, and we can't run it on 25557d9ad16aSJiri Olsa * stat sessions. 25567d9ad16aSJiri Olsa */ 25577d9ad16aSJiri Olsa stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe); 25587d9ad16aSJiri Olsa 25597d9ad16aSJiri Olsa /* 256086470930SIngo Molnar * We dont want to block the signals - that would cause 256186470930SIngo Molnar * child tasks to inherit that and Ctrl-C would not work. 256286470930SIngo Molnar * What we want is for Ctrl-C to work in the exec()-ed 256386470930SIngo Molnar * task, but being ignored by perf stat itself: 256486470930SIngo Molnar */ 2565f7b7c26eSPeter Zijlstra atexit(sig_atexit); 2566a7e191c3SFrederik Deweerdt if (!forever) 256786470930SIngo Molnar signal(SIGINT, skip_signal); 256813370a9bSStephane Eranian signal(SIGCHLD, skip_signal); 256986470930SIngo Molnar signal(SIGALRM, skip_signal); 257086470930SIngo Molnar signal(SIGABRT, skip_signal); 257186470930SIngo Molnar 257227e9769aSAlexey Budankov if (evlist__initialize_ctlfd(evsel_list, stat_config.ctl_fd, stat_config.ctl_fd_ack)) 257327e9769aSAlexey Budankov goto out; 257427e9769aSAlexey Budankov 2575448ce0e6SGang Li /* Enable ignoring missing threads when -p option is defined. */ 2576448ce0e6SGang Li evlist__first(evsel_list)->ignore_missing_thread = target.pid; 257742202dd5SIngo Molnar status = 0; 2578d97ae04bSJiri Olsa for (run_idx = 0; forever || run_idx < stat_config.run_count; run_idx++) { 2579d97ae04bSJiri Olsa if (stat_config.run_count != 1 && verbose > 0) 25804aa9015fSStephane Eranian fprintf(output, "[ perf stat: executing run #%d ... ]\n", 25814aa9015fSStephane Eranian run_idx + 1); 2582f9cef0a9SIngo Molnar 2583b63fd11cSSrikar Dronamraju if (run_idx != 0) 258453f5e908SArnaldo Carvalho de Melo evlist__reset_prev_raw_counts(evsel_list); 2585b63fd11cSSrikar Dronamraju 2586e55c14afSJiri Olsa status = run_perf_stat(argc, argv, run_idx); 2587443f2d5bSSrikar Dronamraju if (forever && status != -1 && !interval) { 2588d4f63a47SJiri Olsa print_counters(NULL, argc, argv); 2589254ecbc7SJiri Olsa perf_stat__reset_stats(); 2590a7e191c3SFrederik Deweerdt } 259142202dd5SIngo Molnar } 259242202dd5SIngo Molnar 2593c7e5b328SJin Yao if (!forever && status != -1 && (!interval || stat_config.summary)) 2594d4f63a47SJiri Olsa print_counters(NULL, argc, argv); 2595d134ffb9SArnaldo Carvalho de Melo 259627e9769aSAlexey Budankov evlist__finalize_ctlfd(evsel_list); 259727e9769aSAlexey Budankov 25984979d0c7SJiri Olsa if (STAT_RECORD) { 25994979d0c7SJiri Olsa /* 26004979d0c7SJiri Olsa * We synthesize the kernel mmap record just so that older tools 26014979d0c7SJiri Olsa * don't emit warnings about not being able to resolve symbols 26024d39c89fSIngo Molnar * due to /proc/sys/kernel/kptr_restrict settings and instead provide 26034979d0c7SJiri Olsa * a saner message about no samples being in the perf.data file. 26044979d0c7SJiri Olsa * 26054979d0c7SJiri Olsa * This also serves to suppress a warning about f_header.data.size == 0 26068b99b1a4SJiri Olsa * in header.c at the moment 'perf stat record' gets introduced, which 26078b99b1a4SJiri Olsa * is not really needed once we start adding the stat specific PERF_RECORD_ 26088b99b1a4SJiri Olsa * records, but the need to suppress the kptr_restrict messages in older 26098b99b1a4SJiri Olsa * tools remain -acme 26104979d0c7SJiri Olsa */ 26118ceb41d7SJiri Olsa int fd = perf_data__fd(&perf_stat.data); 2612fa853c4bSSong Liu 2613fa853c4bSSong Liu err = perf_event__synthesize_kernel_mmap((void *)&perf_stat, 26144979d0c7SJiri Olsa process_synthesized_event, 26154979d0c7SJiri Olsa &perf_stat.session->machines.host); 26164979d0c7SJiri Olsa if (err) { 26174979d0c7SJiri Olsa pr_warning("Couldn't synthesize the kernel mmap record, harmless, " 26184979d0c7SJiri Olsa "older tools may produce warnings about this file\n."); 26194979d0c7SJiri Olsa } 26204979d0c7SJiri Olsa 26217aad0c32SJiri Olsa if (!interval) { 26227aad0c32SJiri Olsa if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL)) 26237aad0c32SJiri Olsa pr_err("failed to write stat round event\n"); 26247aad0c32SJiri Olsa } 26257aad0c32SJiri Olsa 26268ceb41d7SJiri Olsa if (!perf_stat.data.is_pipe) { 26274979d0c7SJiri Olsa perf_stat.session->header.data_size += perf_stat.bytes_written; 26284979d0c7SJiri Olsa perf_session__write_header(perf_stat.session, evsel_list, fd, true); 2629664c98d4SJiri Olsa } 26304979d0c7SJiri Olsa 2631750b4edeSJiri Olsa evlist__close(evsel_list); 26324979d0c7SJiri Olsa perf_session__delete(perf_stat.session); 26334979d0c7SJiri Olsa } 26344979d0c7SJiri Olsa 2635544c2ae7SMasami Hiramatsu perf_stat__exit_aggr_mode(); 263653f5e908SArnaldo Carvalho de Melo evlist__free_stats(evsel_list); 26370015e2e1SArnaldo Carvalho de Melo out: 2638f07952b1SAlexander Antonov if (stat_config.iostat_run) 2639f07952b1SAlexander Antonov iostat_release(evsel_list); 2640f07952b1SAlexander Antonov 2641d8f9da24SArnaldo Carvalho de Melo zfree(&stat_config.walltime_run); 2642e55c14afSJiri Olsa 2643daefd0bcSKan Liang if (smi_cost && smi_reset) 2644daefd0bcSKan Liang sysfs__write_int(FREEZE_ON_SMI_PATH, 0); 2645daefd0bcSKan Liang 2646c12995a5SJiri Olsa evlist__delete(evsel_list); 264756739444SJin Yao 26489afe5658SJiri Olsa metricgroup__rblist_exit(&stat_config.metric_events); 264956739444SJin Yao runtime_stat_delete(&stat_config); 2650ee7fe31eSAdrian Hunter evlist__close_control(stat_config.ctl_fd, stat_config.ctl_fd_ack, &stat_config.ctl_fd_close); 265156739444SJin Yao 265242202dd5SIngo Molnar return status; 265386470930SIngo Molnar } 2654