Blame view
tools/perf/builtin-stat.c
50.4 KB
910070454 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
ddcacfa0f perf_counter tool... |
2 |
/* |
bf9e18763 perf_counter tool... |
3 4 5 6 7 8 |
* builtin-stat.c * * Builtin stat command: Give a precise performance counters summary * overview about any workload, CPU or specific PID. * * Sample output: |
ddcacfa0f perf_counter tool... |
9 |
|
2cba3ffb9 perf stat: Add -d... |
10 |
$ perf stat ./hackbench 10 |
ddcacfa0f perf_counter tool... |
11 |
|
2cba3ffb9 perf stat: Add -d... |
12 |
Time: 0.118 |
ddcacfa0f perf_counter tool... |
13 |
|
2cba3ffb9 perf stat: Add -d... |
14 |
Performance counter stats for './hackbench 10': |
ddcacfa0f perf_counter tool... |
15 |
|
2cba3ffb9 perf stat: Add -d... |
16 17 18 19 20 21 22 23 24 25 26 27 28 |
1708.761321 task-clock # 11.037 CPUs utilized 41,190 context-switches # 0.024 M/sec 6,735 CPU-migrations # 0.004 M/sec 17,318 page-faults # 0.010 M/sec 5,205,202,243 cycles # 3.046 GHz 3,856,436,920 stalled-cycles-frontend # 74.09% frontend cycles idle 1,600,790,871 stalled-cycles-backend # 30.75% backend cycles idle 2,603,501,247 instructions # 0.50 insns per cycle # 1.48 stalled cycles per insn 484,357,498 branches # 283.455 M/sec 6,388,934 branch-misses # 1.32% of all branches 0.154822978 seconds time elapsed |
ddcacfa0f perf_counter tool... |
29 |
|
5242519b0 perf stat: Conver... |
30 |
* |
2cba3ffb9 perf stat: Add -d... |
31 |
* Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com> |
5242519b0 perf stat: Conver... |
32 33 34 35 36 37 38 39 |
* * Improvements and fixes by: * * Arjan van de Ven <arjan@linux.intel.com> * Yanmin Zhang <yanmin.zhang@intel.com> * Wu Fengguang <fengguang.wu@intel.com> * Mike Galbraith <efault@gmx.de> * Paul Mackerras <paulus@samba.org> |
6e750a8fc perf stat: Improv... |
40 |
* Jaswinder Singh Rajput <jaswinder@kernel.org> |
ddcacfa0f perf_counter tool... |
41 |
*/ |
1a482f38c perf_counter: Fix... |
42 |
#include "perf.h" |
16f762a2a perf_counter tool... |
43 |
#include "builtin.h" |
f14d57078 perf evsel: No ne... |
44 |
#include "util/cgroup.h" |
148be2c15 perf_counter tool... |
45 |
#include "util/util.h" |
4b6ab94ea perf subcmd: Crea... |
46 |
#include <subcmd/parse-options.h> |
5242519b0 perf stat: Conver... |
47 |
#include "util/parse-events.h" |
4cabc3d1c tools/perf/stat: ... |
48 |
#include "util/pmu.h" |
8f28827a1 perf tools: Libra... |
49 |
#include "util/event.h" |
361c99a66 perf evsel: Intro... |
50 |
#include "util/evlist.h" |
69aad6f1e perf tools: Intro... |
51 |
#include "util/evsel.h" |
8f28827a1 perf tools: Libra... |
52 |
#include "util/debug.h" |
a5d243d04 perf stat: Print ... |
53 |
#include "util/color.h" |
0007eceac perf stat: Move s... |
54 |
#include "util/stat.h" |
60666c630 perf tools: Fix -... |
55 |
#include "util/header.h" |
a12b51c47 perf tools: Fix s... |
56 |
#include "util/cpumap.h" |
d6d901c23 perf events: Chan... |
57 |
#include "util/thread.h" |
fd78260b5 perf threads: Mov... |
58 |
#include "util/thread_map.h" |
d809560b3 perf stat: Move p... |
59 |
#include "util/counts.h" |
44b1e60ab perf stat: Basic ... |
60 |
#include "util/group.h" |
4979d0c7d perf stat record:... |
61 |
#include "util/session.h" |
ba6039b6c perf stat report:... |
62 |
#include "util/tool.h" |
a067558e2 perf tools: Move ... |
63 |
#include "util/string2.h" |
b18f3e365 perf stat: Suppor... |
64 |
#include "util/metricgroup.h" |
9660e08ee perf stat: Add --... |
65 |
#include "util/top.h" |
ba6039b6c perf stat report:... |
66 |
#include "asm/bug.h" |
ddcacfa0f perf_counter tool... |
67 |
|
bd48c63eb tools: Introduce ... |
68 |
#include <linux/time64.h> |
44b1e60ab perf stat: Basic ... |
69 |
#include <api/fs/fs.h> |
a43783aee perf tools: Inclu... |
70 |
#include <errno.h> |
9607ad3a6 perf tools: Add s... |
71 |
#include <signal.h> |
1f16c5754 perf stat: Add --... |
72 |
#include <stdlib.h> |
ddcacfa0f perf_counter tool... |
73 |
#include <sys/prctl.h> |
fd20e8111 perf tools: Inclu... |
74 |
#include <inttypes.h> |
5af52b51f perf stat: add pe... |
75 |
#include <locale.h> |
e3b03b6c1 perf stat: Avoid ... |
76 |
#include <math.h> |
7a8ef4c4b perf tools: Remov... |
77 78 |
#include <sys/types.h> #include <sys/stat.h> |
4208735d8 perf tools: Remov... |
79 |
#include <sys/wait.h> |
7a8ef4c4b perf tools: Remov... |
80 |
#include <unistd.h> |
0ce2da148 perf stat: Displa... |
81 82 |
#include <sys/time.h> #include <sys/resource.h> |
16c8a1093 perf_counter: too... |
83 |
|
3d689ed60 perf tools: Move ... |
84 |
#include "sane_ctype.h" |
d7470b6af perf stat: Add cs... |
85 |
#define DEFAULT_SEPARATOR " " |
daefd0bc0 perf stat: Add su... |
86 |
#define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi" |
d7470b6af perf stat: Add cs... |
87 |
|
d4f63a474 perf stat: Introd... |
88 |
static void print_counters(struct timespec *ts, int argc, const char **argv); |
13370a9b5 perf stat: Add in... |
89 |
|
4cabc3d1c tools/perf/stat: ... |
90 |
/* Default events used for perf stat -T */ |
a454742c1 perf stat: Remove... |
91 92 |
static const char *transaction_attrs = { "task-clock," |
4cabc3d1c tools/perf/stat: ... |
93 94 95 96 97 98 99 100 101 102 103 |
"{" "instructions," "cycles," "cpu/cycles-t/," "cpu/tx-start/," "cpu/el-start/," "cpu/cycles-ct/" "}" }; /* More limited version when the CPU does not have all events. */ |
a454742c1 perf stat: Remove... |
104 105 |
static const char * transaction_limited_attrs = { "task-clock," |
4cabc3d1c tools/perf/stat: ... |
106 107 108 109 110 111 112 |
"{" "instructions," "cycles," "cpu/cycles-t/," "cpu/tx-start/" "}" }; |
44b1e60ab perf stat: Basic ... |
113 114 115 116 117 118 119 120 |
static const char * topdown_attrs[] = { "topdown-total-slots", "topdown-slots-retired", "topdown-recovery-bubbles", "topdown-fetch-bubbles", "topdown-slots-issued", NULL, }; |
daefd0bc0 perf stat: Add su... |
121 122 123 124 125 126 127 |
static const char *smi_cost_attrs = { "{" "msr/aperf/," "msr/smi/," "cycles" "}" }; |
666e6d48c perf stat: Declar... |
128 |
static struct perf_evlist *evsel_list; |
361c99a66 perf evsel: Intro... |
129 |
|
602ad878d perf target: Shor... |
130 |
static struct target target = { |
77a6f014e perf stat: Use pe... |
131 132 |
.uid = UINT_MAX, }; |
ddcacfa0f perf_counter tool... |
133 |
|
c1a1f5d9d perf stat: Allow ... |
134 |
#define METRIC_ONLY_LEN 20 |
d07f0b120 perf stat: Avoid ... |
135 |
static volatile pid_t child_pid = -1; |
2cba3ffb9 perf stat: Add -d... |
136 |
static int detailed_run = 0; |
4cabc3d1c tools/perf/stat: ... |
137 |
static bool transaction_run; |
44b1e60ab perf stat: Basic ... |
138 |
static bool topdown_run = false; |
daefd0bc0 perf stat: Add su... |
139 140 |
static bool smi_cost = false; static bool smi_reset = false; |
d7470b6af perf stat: Add cs... |
141 |
static int big_num_opt = -1; |
43bece797 perf tools: Add g... |
142 |
static bool group = false; |
1f16c5754 perf stat: Add --... |
143 144 145 |
static const char *pre_cmd = NULL; static const char *post_cmd = NULL; static bool sync_run = false; |
a7e191c37 perf stat: Introd... |
146 |
static bool forever = false; |
44b1e60ab perf stat: Basic ... |
147 |
static bool force_metric_only = false; |
13370a9b5 perf stat: Add in... |
148 |
static struct timespec ref_time; |
e05473111 perf stat: Make s... |
149 |
static bool append_file; |
db06a269e perf stat: Add su... |
150 |
static bool interval_count; |
e05473111 perf stat: Make s... |
151 152 |
static const char *output_name; static int output_fd; |
5af52b51f perf stat: add pe... |
153 |
|
4979d0c7d perf stat record:... |
154 155 |
struct perf_stat { bool record; |
8ceb41d7e perf tools: Renam... |
156 |
struct perf_data data; |
4979d0c7d perf stat record:... |
157 158 |
struct perf_session *session; u64 bytes_written; |
ba6039b6c perf stat report:... |
159 |
struct perf_tool tool; |
1975d36e1 perf stat report:... |
160 161 162 |
bool maps_allocated; struct cpu_map *cpus; struct thread_map *threads; |
89af4e05c perf stat report:... |
163 |
enum aggr_mode aggr_mode; |
4979d0c7d perf stat record:... |
164 165 166 167 |
}; static struct perf_stat perf_stat; #define STAT_RECORD perf_stat.record |
60666c630 perf tools: Fix -... |
168 |
static volatile int done = 0; |
421a50f3f perf stat: Introd... |
169 |
static struct perf_stat_config stat_config = { |
26893a601 perf stat: Add 'w... |
170 171 172 173 174 175 |
.aggr_mode = AGGR_GLOBAL, .scale = true, .unit_width = 4, /* strlen("unit") */ .run_count = 1, .metric_only_len = METRIC_ONLY_LEN, .walltime_nsecs_stats = &walltime_nsecs_stats, |
34ff0866d perf stat: Move '... |
176 |
.big_num = true, |
421a50f3f perf stat: Introd... |
177 |
}; |
13370a9b5 perf stat: Add in... |
178 179 180 181 182 |
static inline void diff_timespec(struct timespec *r, struct timespec *a, struct timespec *b) { r->tv_sec = a->tv_sec - b->tv_sec; if (a->tv_nsec < b->tv_nsec) { |
310ebb936 perf stat: Use *S... |
183 |
r->tv_nsec = a->tv_nsec + NSEC_PER_SEC - b->tv_nsec; |
13370a9b5 perf stat: Add in... |
184 185 186 187 188 |
r->tv_sec--; } else { r->tv_nsec = a->tv_nsec - b->tv_nsec ; } } |
254ecbc74 perf stat: Introd... |
189 190 |
static void perf_stat__reset_stats(void) { |
56739444d perf stat: Alloca... |
191 |
int i; |
254ecbc74 perf stat: Introd... |
192 |
perf_evlist__reset_stats(evsel_list); |
f87027b96 perf stat: Move s... |
193 |
perf_stat__reset_shadow_stats(); |
56739444d perf stat: Alloca... |
194 195 196 |
for (i = 0; i < stat_config.stats_num; i++) perf_stat__reset_shadow_per_stat(&stat_config.stats[i]); |
1eda3b214 perf stat: Introd... |
197 |
} |
8b99b1a4e perf stat record:... |
198 199 200 201 |
static int process_synthesized_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) |
4979d0c7d perf stat record:... |
202 |
{ |
8ceb41d7e perf tools: Renam... |
203 |
if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) { |
4979d0c7d perf stat record:... |
204 205 206 207 |
pr_err("failed to write perf data, error: %m "); return -1; } |
8b99b1a4e perf stat record:... |
208 |
perf_stat.bytes_written += event->header.size; |
4979d0c7d perf stat record:... |
209 210 |
return 0; } |
1975d36e1 perf stat report:... |
211 |
static int write_stat_round_event(u64 tm, u64 type) |
7aad0c32b perf stat record:... |
212 |
{ |
1975d36e1 perf stat report:... |
213 |
return perf_event__synthesize_stat_round(NULL, tm, type, |
7aad0c32b perf stat record:... |
214 215 216 217 218 219 |
process_synthesized_event, NULL); } #define WRITE_STAT_ROUND_EVENT(time, interval) \ write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval) |
5a6ea81b8 perf stat record:... |
220 221 222 223 224 225 226 227 228 229 230 |
#define SID(e, x, y) xyarray__entry(e->sample_id, x, y) static int perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread, struct perf_counts_values *count) { struct perf_sample_id *sid = SID(counter, cpu, thread); return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count, process_synthesized_event, NULL); } |
f0fbb114e perf stat: Implem... |
231 232 233 234 235 236 237 238 239 240 241 242 243 |
static int read_single_counter(struct perf_evsel *counter, int cpu, int thread, struct timespec *rs) { if (counter->tool_event == PERF_TOOL_DURATION_TIME) { u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL; struct perf_counts_values *count = perf_counts(counter->counts, cpu, thread); count->ena = count->run = val; count->val = val; return 0; } return perf_evsel__read_counter(counter, cpu, thread); } |
f5b4a9c3a perf stat: Add no... |
244 245 246 247 |
/* * Read out the results of a single counter: * do not aggregate counts across CPUs in system-wide mode */ |
f0fbb114e perf stat: Implem... |
248 |
static int read_counter(struct perf_evsel *counter, struct timespec *rs) |
f5b4a9c3a perf stat: Add no... |
249 |
{ |
9bf1a5291 perf stat: Make r... |
250 |
int nthreads = thread_map__nr(evsel_list->threads); |
00e727bb3 perf stat: Balanc... |
251 |
int ncpus, cpu, thread; |
1d9f8d1b8 perf stat: Remove... |
252 |
if (target__has_cpu(&target) && !target__has_per_thread(&target)) |
00e727bb3 perf stat: Balanc... |
253 254 255 |
ncpus = perf_evsel__nr_cpus(counter); else ncpus = 1; |
f5b4a9c3a perf stat: Add no... |
256 |
|
3b4331d9a perf stat: Report... |
257 258 |
if (!counter->supported) return -ENOENT; |
9bf1a5291 perf stat: Make r... |
259 260 261 262 263 |
if (counter->system_wide) nthreads = 1; for (thread = 0; thread < nthreads; thread++) { for (cpu = 0; cpu < ncpus; cpu++) { |
3b3eb0445 perf stat: Separa... |
264 265 266 |
struct perf_counts_values *count; count = perf_counts(counter->counts, cpu, thread); |
82bf311e1 perf stat: Use gr... |
267 268 269 270 271 272 |
/* * The leader's group read loads data into its group members * (via perf_evsel__read_counter) and sets threir count->loaded. */ if (!count->loaded && |
f0fbb114e perf stat: Implem... |
273 |
read_single_counter(counter, cpu, thread, rs)) { |
db49a7179 perf stat: Fix bu... |
274 275 276 |
counter->counts->scaled = -1; perf_counts(counter->counts, cpu, thread)->ena = 0; perf_counts(counter->counts, cpu, thread)->run = 0; |
9bf1a5291 perf stat: Make r... |
277 |
return -1; |
db49a7179 perf stat: Fix bu... |
278 |
} |
5a6ea81b8 perf stat record:... |
279 |
|
82bf311e1 perf stat: Use gr... |
280 |
count->loaded = false; |
5a6ea81b8 perf stat record:... |
281 282 283 284 285 286 287 |
if (STAT_RECORD) { if (perf_evsel__write_stat_event(counter, cpu, thread, count)) { pr_err("failed to write stat event "); return -1; } } |
0b1abbf4a perf stat: Add ex... |
288 289 290 291 292 293 294 295 296 |
if (verbose > 1) { fprintf(stat_config.output, "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 " ", perf_evsel__name(counter), cpu, count->val, count->ena, count->run); } |
9bf1a5291 perf stat: Make r... |
297 |
} |
f5b4a9c3a perf stat: Add no... |
298 |
} |
c52b12ed2 perf evsel: Steal... |
299 300 |
return 0; |
2996f5ddb perf_counter tool... |
301 |
} |
f0fbb114e perf stat: Implem... |
302 |
static void read_counters(struct timespec *rs) |
13370a9b5 perf stat: Add in... |
303 |
{ |
13370a9b5 perf stat: Add in... |
304 |
struct perf_evsel *counter; |
db49a7179 perf stat: Fix bu... |
305 |
int ret; |
13370a9b5 perf stat: Add in... |
306 |
|
e5cadb93d perf evlist: Rena... |
307 |
evlist__for_each_entry(evsel_list, counter) { |
f0fbb114e perf stat: Implem... |
308 |
ret = read_counter(counter, rs); |
db49a7179 perf stat: Fix bu... |
309 |
if (ret) |
245bad8eb perf stat: Quiete... |
310 311 |
pr_debug("failed to read counter %s ", counter->name); |
3b3eb0445 perf stat: Separa... |
312 |
|
db49a7179 perf stat: Fix bu... |
313 |
if (ret == 0 && perf_stat_process_counter(&stat_config, counter)) |
3b3eb0445 perf stat: Separa... |
314 315 |
pr_warning("failed to process counter %s ", counter->name); |
13370a9b5 perf stat: Add in... |
316 |
} |
106a94a0f perf stat: Introd... |
317 |
} |
ba411a954 perf stat: Rename... |
318 |
static void process_interval(void) |
106a94a0f perf stat: Introd... |
319 |
{ |
106a94a0f perf stat: Introd... |
320 |
struct timespec ts, rs; |
106a94a0f perf stat: Introd... |
321 |
|
13370a9b5 perf stat: Add in... |
322 323 |
clock_gettime(CLOCK_MONOTONIC, &ts); diff_timespec(&rs, &ts, &ref_time); |
13370a9b5 perf stat: Add in... |
324 |
|
f0fbb114e perf stat: Implem... |
325 |
read_counters(&rs); |
7aad0c32b perf stat record:... |
326 |
if (STAT_RECORD) { |
bd48c63eb tools: Introduce ... |
327 |
if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL)) |
7aad0c32b perf stat record:... |
328 329 330 |
pr_err("failed to write stat round event "); } |
b90f1333e perf stat: Update... |
331 332 |
init_stats(&walltime_nsecs_stats); update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000); |
d4f63a474 perf stat: Introd... |
333 |
print_counters(&rs, 0, NULL); |
13370a9b5 perf stat: Add in... |
334 |
} |
67ccdecd0 perf stat: Create... |
335 |
static void enable_counters(void) |
411916880 perf stat: Add su... |
336 |
{ |
728c0ee0a perf stat: Move '... |
337 338 |
if (stat_config.initial_delay) usleep(stat_config.initial_delay * USEC_PER_MSEC); |
67ccdecd0 perf stat: Create... |
339 340 341 342 343 344 |
/* * We need to enable counters only if: * - we don't have tracee (attaching to task or cpu) * - we have initial delay configured */ |
728c0ee0a perf stat: Move '... |
345 |
if (!target__none(&target) || stat_config.initial_delay) |
ab46db0a3 perf stat: Use pe... |
346 |
perf_evlist__enable(evsel_list); |
411916880 perf stat: Add su... |
347 |
} |
3df33eff2 perf stat: Avoid ... |
348 349 350 351 352 353 354 355 356 357 |
static void disable_counters(void) { /* * If we don't have tracee (attaching to task or cpu), counters may * still be running. To get accurate group ratios, we must stop groups * from counting before reading their constituent counters. */ if (!target__none(&target)) perf_evlist__disable(evsel_list); } |
f33cbe72e perf evlist: Send... |
358 |
static volatile int workload_exec_errno; |
6af206fd9 perf stat: Don't ... |
359 360 361 362 363 364 |
/* * perf_evlist__prepare_workload will send a SIGUSR1 * if the fork fails, since we asked by setting its * want_signal to true. */ |
f33cbe72e perf evlist: Send... |
365 366 |
static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info, void *ucontext __maybe_unused) |
6af206fd9 perf stat: Don't ... |
367 |
{ |
f33cbe72e perf evlist: Send... |
368 |
workload_exec_errno = info->si_value.sival_int; |
6af206fd9 perf stat: Don't ... |
369 |
} |
82bf311e1 perf stat: Use gr... |
370 371 372 373 |
static bool perf_evsel__should_store_id(struct perf_evsel *counter) { return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID; } |
cbb5df7e9 perf stat: Poll f... |
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
static bool is_target_alive(struct target *_target, struct thread_map *threads) { struct stat st; int i; if (!target__has_task(_target)) return true; for (i = 0; i < threads->nr; i++) { char path[PATH_MAX]; scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(), threads->map[i].pid); if (!stat(path, &st)) return true; } return false; } |
e55c14af4 perf stat: Add --... |
395 |
static int __run_perf_stat(int argc, const char **argv, int run_idx) |
42202dd56 perf stat: Add fe... |
396 |
{ |
ec0d3d1fd perf stat: Move '... |
397 |
int interval = stat_config.interval; |
db06a269e perf stat: Add su... |
398 |
int times = stat_config.times; |
f1f8ad52f perf stat: Add su... |
399 |
int timeout = stat_config.timeout; |
d6195a6a2 perf evsel: Infor... |
400 |
char msg[BUFSIZ]; |
42202dd56 perf stat: Add fe... |
401 |
unsigned long long t0, t1; |
cac214255 perf tools: Fix a... |
402 |
struct perf_evsel *counter; |
13370a9b5 perf stat: Add in... |
403 |
struct timespec ts; |
410136f5d tools/perf/stat: ... |
404 |
size_t l; |
42202dd56 perf stat: Add fe... |
405 |
int status = 0; |
6be2850ef perf stat: Enable... |
406 |
const bool forks = (argc > 0); |
8ceb41d7e perf tools: Renam... |
407 |
bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false; |
42202dd56 perf stat: Add fe... |
408 |
|
13370a9b5 perf stat: Add in... |
409 |
if (interval) { |
310ebb936 perf stat: Use *S... |
410 411 |
ts.tv_sec = interval / USEC_PER_MSEC; ts.tv_nsec = (interval % USEC_PER_MSEC) * NSEC_PER_MSEC; |
f1f8ad52f perf stat: Add su... |
412 413 414 |
} else if (timeout) { ts.tv_sec = timeout / USEC_PER_MSEC; ts.tv_nsec = (timeout % USEC_PER_MSEC) * NSEC_PER_MSEC; |
13370a9b5 perf stat: Add in... |
415 416 417 418 |
} else { ts.tv_sec = 1; ts.tv_nsec = 0; } |
60666c630 perf tools: Fix -... |
419 |
if (forks) { |
664c98d4e perf stat record:... |
420 |
if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe, |
735f7e0bb perf evlist: Move... |
421 |
workload_exec_failed_signal) < 0) { |
acf289227 perf stat: Use pe... |
422 423 |
perror("failed to prepare workload"); return -1; |
60666c630 perf tools: Fix -... |
424 |
} |
d20a47e70 perf stat: Set ch... |
425 |
child_pid = evsel_list->workload.pid; |
051ae7f73 perf_counter tool... |
426 |
} |
6a4bb04ca perf tools: Enabl... |
427 |
if (group) |
63dab225f perf evlist: Rena... |
428 |
perf_evlist__set_leader(evsel_list); |
6a4bb04ca perf tools: Enabl... |
429 |
|
e5cadb93d perf evlist: Rena... |
430 |
evlist__for_each_entry(evsel_list, counter) { |
42ef8a78c perf stat: Fallba... |
431 |
try_again: |
d09cefd2e perf stat: Move c... |
432 |
if (create_perf_stat_counter(counter, &stat_config, &target) < 0) { |
5a5dfe4b8 perf tools: Suppo... |
433 434 |
/* Weak group failed. Reset the group. */ |
35c1980eb perf stat: Fall w... |
435 |
if ((errno == EINVAL || errno == EBADF) && |
5a5dfe4b8 perf tools: Suppo... |
436 437 |
counter->leader != counter && counter->weak_group) { |
c3537fc25 perf evlist: Move... |
438 |
counter = perf_evlist__reset_weak_group(evsel_list, counter); |
5a5dfe4b8 perf tools: Suppo... |
439 440 |
goto try_again; } |
979987a56 perf stat: handle... |
441 442 443 444 |
/* * PPC returns ENXIO for HW counters until 2.6.37 * (behavior changed with commit b0a873e). */ |
38f6ae1e1 perf stat: Failur... |
445 |
if (errno == EINVAL || errno == ENOSYS || |
979987a56 perf stat: handle... |
446 447 |
errno == ENOENT || errno == EOPNOTSUPP || errno == ENXIO) { |
bb963e165 perf utils: Check... |
448 |
if (verbose > 0) |
c63ca0c01 perf stat: Tell u... |
449 450 |
ui__warning("%s event is not supported by the kernel. ", |
7289f83cc perf tools: Move ... |
451 |
perf_evsel__name(counter)); |
2cee77c45 perf stat: clarif... |
452 |
counter->supported = false; |
cb5ef6006 perf stat: Error ... |
453 454 455 456 |
if ((counter->leader != counter) || !(counter->leader->nr_members > 1)) continue; |
42ef8a78c perf stat: Fallba... |
457 |
} else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { |
bb963e165 perf utils: Check... |
458 |
if (verbose > 0) |
42ef8a78c perf stat: Fallba... |
459 460 461 |
ui__warning("%s ", msg); goto try_again; |
ab6c79b81 perf stat: Ignore... |
462 463 464 465 466 467 468 469 470 471 472 473 474 |
} else if (target__has_per_thread(&target) && evsel_list->threads && evsel_list->threads->err_thread != -1) { /* * For global --per-thread case, skip current * error thread. */ if (!thread_map__remove(evsel_list->threads, evsel_list->threads->err_thread)) { evsel_list->threads->err_thread = -1; goto try_again; } } |
ede702900 perf stat: Fix co... |
475 |
|
56e52e853 perf evsel: Intro... |
476 477 478 479 |
perf_evsel__open_strerror(counter, &target, errno, msg, sizeof(msg)); ui__error("%s ", msg); |
48290609c perf evsel: Intro... |
480 481 |
if (child_pid != -1) kill(child_pid, SIGTERM); |
fceda7feb perf stat: Remove... |
482 |
|
48290609c perf evsel: Intro... |
483 484 |
return -1; } |
2cee77c45 perf stat: clarif... |
485 |
counter->supported = true; |
410136f5d tools/perf/stat: ... |
486 487 |
l = strlen(counter->unit); |
df4f7b4d4 perf stat: Move '... |
488 489 |
if (l > stat_config.unit_width) stat_config.unit_width = l; |
2af4646d1 perf stat record:... |
490 |
|
82bf311e1 perf stat: Use gr... |
491 |
if (perf_evsel__should_store_id(counter) && |
650d62204 perf evsel: Intro... |
492 |
perf_evsel__store_ids(counter, evsel_list)) |
2af4646d1 perf stat record:... |
493 |
return -1; |
084ab9f86 perf stat: Better... |
494 |
} |
42202dd56 perf stat: Add fe... |
495 |
|
23d4aad48 perf evlist: Retu... |
496 |
if (perf_evlist__apply_filters(evsel_list, &counter)) { |
62d94b00f perf tools: Repla... |
497 498 |
pr_err("failed to set filter \"%s\" on event %s with %d (%s) ", |
23d4aad48 perf evlist: Retu... |
499 |
counter->filter, perf_evsel__name(counter), errno, |
c8b5f2c96 tools: Introduce ... |
500 |
str_error_r(errno, msg, sizeof(msg))); |
cfd748ae0 perf stat: Provid... |
501 502 |
return -1; } |
4979d0c7d perf stat record:... |
503 |
if (STAT_RECORD) { |
8ceb41d7e perf tools: Renam... |
504 |
int err, fd = perf_data__fd(&perf_stat.data); |
4979d0c7d perf stat record:... |
505 |
|
664c98d4e perf stat record:... |
506 |
if (is_pipe) { |
8ceb41d7e perf tools: Renam... |
507 |
err = perf_header__write_pipe(perf_data__fd(&perf_stat.data)); |
664c98d4e perf stat record:... |
508 509 510 511 |
} else { err = perf_session__write_header(perf_stat.session, evsel_list, fd, false); } |
4979d0c7d perf stat record:... |
512 513 |
if (err < 0) return err; |
8b99b1a4e perf stat record:... |
514 |
|
1c21e9899 perf stat: Add 's... |
515 |
err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list, |
c2c247f2d perf stat: Add 'p... |
516 |
process_synthesized_event, is_pipe); |
8b99b1a4e perf stat record:... |
517 518 |
if (err < 0) return err; |
4979d0c7d perf stat record:... |
519 |
} |
42202dd56 perf stat: Add fe... |
520 521 522 523 |
/* * Enable counters and exec the command: */ t0 = rdclock(); |
13370a9b5 perf stat: Add in... |
524 |
clock_gettime(CLOCK_MONOTONIC, &ref_time); |
42202dd56 perf stat: Add fe... |
525 |
|
60666c630 perf tools: Fix -... |
526 |
if (forks) { |
acf289227 perf stat: Use pe... |
527 |
perf_evlist__start_workload(evsel_list); |
67ccdecd0 perf stat: Create... |
528 |
enable_counters(); |
acf289227 perf stat: Use pe... |
529 |
|
f1f8ad52f perf stat: Add su... |
530 |
if (interval || timeout) { |
13370a9b5 perf stat: Add in... |
531 532 |
while (!waitpid(child_pid, &status, WNOHANG)) { nanosleep(&ts, NULL); |
f1f8ad52f perf stat: Add su... |
533 534 |
if (timeout) break; |
ba411a954 perf stat: Rename... |
535 |
process_interval(); |
db06a269e perf stat: Add su... |
536 537 |
if (interval_count && !(--times)) break; |
13370a9b5 perf stat: Add in... |
538 539 |
} } |
8a99255a5 perf stat: Fix en... |
540 541 |
if (child_pid != -1) wait4(child_pid, &status, 0, &stat_config.ru_data); |
6af206fd9 perf stat: Don't ... |
542 |
|
f33cbe72e perf evlist: Send... |
543 |
if (workload_exec_errno) { |
c8b5f2c96 tools: Introduce ... |
544 |
const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); |
f33cbe72e perf evlist: Send... |
545 546 |
pr_err("Workload failed: %s ", emsg); |
6af206fd9 perf stat: Don't ... |
547 |
return -1; |
f33cbe72e perf evlist: Send... |
548 |
} |
6af206fd9 perf stat: Don't ... |
549 |
|
33e49ea70 perf tools: Make ... |
550 551 |
if (WIFSIGNALED(status)) psignal(WTERMSIG(status), argv[0]); |
60666c630 perf tools: Fix -... |
552 |
} else { |
67ccdecd0 perf stat: Create... |
553 |
enable_counters(); |
13370a9b5 perf stat: Add in... |
554 555 |
while (!done) { nanosleep(&ts, NULL); |
cbb5df7e9 perf stat: Poll f... |
556 557 |
if (!is_target_alive(&target, evsel_list->threads)) break; |
f1f8ad52f perf stat: Add su... |
558 559 |
if (timeout) break; |
db06a269e perf stat: Add su... |
560 |
if (interval) { |
ba411a954 perf stat: Rename... |
561 |
process_interval(); |
db06a269e perf stat: Add su... |
562 563 564 |
if (interval_count && !(--times)) break; } |
13370a9b5 perf stat: Add in... |
565 |
} |
60666c630 perf tools: Fix -... |
566 |
} |
42202dd56 perf stat: Add fe... |
567 |
|
3df33eff2 perf stat: Avoid ... |
568 |
disable_counters(); |
42202dd56 perf stat: Add fe... |
569 |
t1 = rdclock(); |
54ac0b1bd perf stat: Move '... |
570 571 |
if (stat_config.walltime_run_table) stat_config.walltime_run[run_idx] = t1 - t0; |
e55c14af4 perf stat: Add --... |
572 |
|
9e9772c45 perf stat: Remove... |
573 |
update_stats(&walltime_nsecs_stats, t1 - t0); |
42202dd56 perf stat: Add fe... |
574 |
|
3df33eff2 perf stat: Avoid ... |
575 576 577 578 579 580 |
/* * Closing a group leader splits the group, and as we only disable * group leaders, results in remaining events becoming enabled. To * avoid arbitrary skew, we must read all counters before closing any * group leaders. */ |
f0fbb114e perf stat: Implem... |
581 |
read_counters(&(struct timespec) { .tv_nsec = t1-t0 }); |
3df33eff2 perf stat: Avoid ... |
582 |
perf_evlist__close(evsel_list); |
c52b12ed2 perf evsel: Steal... |
583 |
|
42202dd56 perf stat: Add fe... |
584 585 |
return WEXITSTATUS(status); } |
e55c14af4 perf stat: Add --... |
586 |
static int run_perf_stat(int argc, const char **argv, int run_idx) |
1f16c5754 perf stat: Add --... |
587 588 589 590 591 592 593 594 595 596 597 |
{ int ret; if (pre_cmd) { ret = system(pre_cmd); if (ret) return ret; } if (sync_run) sync(); |
e55c14af4 perf stat: Add --... |
598 |
ret = __run_perf_stat(argc, argv, run_idx); |
1f16c5754 perf stat: Add --... |
599 600 601 602 603 604 605 606 607 608 609 |
if (ret) return ret; if (post_cmd) { ret = system(post_cmd); if (ret) return ret; } return ret; } |
a5a9eac1a perf stat: Introd... |
610 611 |
static void print_counters(struct timespec *ts, int argc, const char **argv) { |
0174820a8 perf stat: Move S... |
612 613 614 |
/* Do not print anything if we record to the pipe. */ if (STAT_RECORD && perf_stat.data.is_pipe) return; |
c512e0eae perf stat: Add 't... |
615 |
perf_evlist__print_counters(evsel_list, &stat_config, &target, |
b64df7f33 perf stat: Add 's... |
616 |
ts, argc, argv); |
a5a9eac1a perf stat: Introd... |
617 |
} |
f7b7c26e0 perf_counter tool... |
618 |
static volatile int signr = -1; |
5242519b0 perf stat: Conver... |
619 |
static void skip_signal(int signo) |
ddcacfa0f perf_counter tool... |
620 |
{ |
ec0d3d1fd perf stat: Move '... |
621 |
if ((child_pid == -1) || stat_config.interval) |
60666c630 perf tools: Fix -... |
622 |
done = 1; |
f7b7c26e0 perf_counter tool... |
623 |
signr = signo; |
d07f0b120 perf stat: Avoid ... |
624 625 626 627 628 629 630 |
/* * render child_pid harmless * won't send SIGTERM to a random * process in case of race condition * and fast PID recycling */ child_pid = -1; |
f7b7c26e0 perf_counter tool... |
631 632 633 634 |
} static void sig_atexit(void) { |
d07f0b120 perf stat: Avoid ... |
635 636 637 638 639 640 641 642 643 644 645 |
sigset_t set, oset; /* * avoid race condition with SIGCHLD handler * in skip_signal() which is modifying child_pid * goal is to avoid send SIGTERM to a random * process */ sigemptyset(&set); sigaddset(&set, SIGCHLD); sigprocmask(SIG_BLOCK, &set, &oset); |
933da83aa perf: Propagate t... |
646 647 |
if (child_pid != -1) kill(child_pid, SIGTERM); |
d07f0b120 perf stat: Avoid ... |
648 |
sigprocmask(SIG_SETMASK, &oset, NULL); |
f7b7c26e0 perf_counter tool... |
649 650 651 652 653 |
if (signr == -1) return; signal(signr, SIG_DFL); kill(getpid(), signr); |
5242519b0 perf stat: Conver... |
654 |
} |
1d037ca16 perf tools: Use _... |
655 656 |
static int stat__set_big_num(const struct option *opt __maybe_unused, const char *s __maybe_unused, int unset) |
d7470b6af perf stat: Add cs... |
657 658 659 660 |
{ big_num_opt = unset ? 0 : 1; return 0; } |
44b1e60ab perf stat: Basic ... |
661 662 663 664 |
static int enable_metric_only(const struct option *opt __maybe_unused, const char *s __maybe_unused, int unset) { force_metric_only = true; |
0ce5aa026 perf stat: Move '... |
665 |
stat_config.metric_only = !unset; |
44b1e60ab perf stat: Basic ... |
666 667 |
return 0; } |
b18f3e365 perf stat: Suppor... |
668 669 670 671 |
static int parse_metric_groups(const struct option *opt, const char *str, int unset __maybe_unused) { |
d0192fdba perf stat: Move '... |
672 |
return metricgroup__parse_groups(opt, str, &stat_config.metric_events); |
b18f3e365 perf stat: Suppor... |
673 |
} |
51433ead1 perf stat: Avoid ... |
674 |
static struct option stat_options[] = { |
e05473111 perf stat: Make s... |
675 676 677 678 679 680 681 |
OPT_BOOLEAN('T', "transaction", &transaction_run, "hardware transaction statistics"), OPT_CALLBACK('e', "event", &evsel_list, "event", "event selector. use 'perf list' to list available events", parse_events_option), OPT_CALLBACK(0, "filter", &evsel_list, "filter", "event filter", parse_filter), |
5698f26b4 perf stat: Move '... |
682 |
OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit, |
e05473111 perf stat: Make s... |
683 684 685 686 687 688 689 690 691 |
"child tasks do not inherit counters"), OPT_STRING('p', "pid", &target.pid, "pid", "stat events on existing process id"), OPT_STRING('t', "tid", &target.tid, "tid", "stat events on existing thread id"), OPT_BOOLEAN('a', "all-cpus", &target.system_wide, "system-wide collection from all CPUs"), OPT_BOOLEAN('g', "group", &group, "put the counters into a counter group"), |
75998bb26 perf stat: Fix --... |
692 693 |
OPT_BOOLEAN(0, "scale", &stat_config.scale, "Use --no-scale to disable counter scaling for multiplexing"), |
e05473111 perf stat: Make s... |
694 695 |
OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), |
d97ae04b3 perf stat: Move '... |
696 |
OPT_INTEGER('r', "repeat", &stat_config.run_count, |
e05473111 perf stat: Make s... |
697 |
"repeat command and print average + stddev (max: 100, forever: 0)"), |
54ac0b1bd perf stat: Move '... |
698 |
OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table, |
e55c14af4 perf stat: Add --... |
699 |
"display details about each run (only with -r option)"), |
aea0dca16 perf stat: Move '... |
700 |
OPT_BOOLEAN('n', "null", &stat_config.null_run, |
e05473111 perf stat: Make s... |
701 702 703 704 705 706 707 708 709 710 711 712 |
"null run - dont start any counters"), OPT_INCR('d', "detailed", &detailed_run, "detailed run - start a lot of events"), OPT_BOOLEAN('S', "sync", &sync_run, "call sync() before starting a run"), OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, "print large numbers with thousands\' separators", stat__set_big_num), OPT_STRING('C', "cpu", &target.cpu_list, "cpu", "list of cpus to monitor in system-wide"), OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode, "disable CPU count aggregation", AGGR_NONE), |
fdee335b0 perf stat: Move '... |
713 |
OPT_BOOLEAN(0, "no-merge", &stat_config.no_merge, "Do not merge identical named events"), |
fa7070a38 perf stat: Move c... |
714 |
OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator", |
e05473111 perf stat: Make s... |
715 716 717 718 719 720 721 722 723 724 725 726 |
"print counts with custom separator"), OPT_CALLBACK('G', "cgroup", &evsel_list, "name", "monitor event in cgroup name only", parse_cgroups), OPT_STRING('o', "output", &output_name, "file", "output file name"), OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), OPT_INTEGER(0, "log-fd", &output_fd, "log output to fd, instead of stderr"), OPT_STRING(0, "pre", &pre_cmd, "command", "command to run prior to the measured command"), OPT_STRING(0, "post", &post_cmd, "command", "command to run after to the measured command"), OPT_UINTEGER('I', "interval-print", &stat_config.interval, |
9dc9a95f0 perf stat: Enable... |
727 728 |
"print counts at regular interval in ms " "(overhead is possible for values <= 100ms)"), |
db06a269e perf stat: Add su... |
729 730 |
OPT_INTEGER(0, "interval-count", &stat_config.times, "print counts for fixed number of times"), |
132c6ba3c perf stat: Move '... |
731 |
OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear, |
9660e08ee perf stat: Add --... |
732 |
"clear screen in between new interval"), |
f1f8ad52f perf stat: Add su... |
733 734 |
OPT_UINTEGER(0, "timeout", &stat_config.timeout, "stop workload and print counts after a timeout period in ms (>= 10ms)"), |
e05473111 perf stat: Make s... |
735 736 737 738 739 740 |
OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode, "aggregate counts per processor socket", AGGR_SOCKET), OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode, "aggregate counts per physical processor core", AGGR_CORE), OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode, "aggregate counts per thread", AGGR_THREAD), |
728c0ee0a perf stat: Move '... |
741 |
OPT_UINTEGER('D', "delay", &stat_config.initial_delay, |
e05473111 perf stat: Make s... |
742 |
"ms to wait before starting measurement after program start"), |
0ce5aa026 perf stat: Move '... |
743 |
OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL, |
44b1e60ab perf stat: Basic ... |
744 745 746 |
"Only print computed metrics. No raw values", enable_metric_only), OPT_BOOLEAN(0, "topdown", &topdown_run, "measure topdown level 1 statistics"), |
daefd0bc0 perf stat: Add su... |
747 748 |
OPT_BOOLEAN(0, "smi-cost", &smi_cost, "measure SMI cost"), |
b18f3e365 perf stat: Suppor... |
749 750 751 |
OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list", "monitor specified metrics or metric groups (separated by ,)", parse_metric_groups), |
e05473111 perf stat: Make s... |
752 753 |
OPT_END() }; |
6f6b6594b perf stat: Move *... |
754 755 |
static int perf_stat__get_socket(struct perf_stat_config *config __maybe_unused, struct cpu_map *map, int cpu) |
1fe7a3002 perf cpu_map: Add... |
756 757 758 |
{ return cpu_map__get_socket(map, cpu, NULL); } |
6f6b6594b perf stat: Move *... |
759 760 |
static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused, struct cpu_map *map, int cpu) |
1fe7a3002 perf cpu_map: Add... |
761 762 763 |
{ return cpu_map__get_core(map, cpu, NULL); } |
1e5a29318 perf stat: Cache ... |
764 765 766 767 768 769 770 771 772 773 774 |
static int cpu_map__get_max(struct cpu_map *map) { int i, max = -1; for (i = 0; i < map->nr; i++) { if (map->map[i] > max) max = map->map[i]; } return max; } |
6f6b6594b perf stat: Move *... |
775 776 |
static int perf_stat__get_aggr(struct perf_stat_config *config, aggr_get_id_t get_id, struct cpu_map *map, int idx) |
1e5a29318 perf stat: Cache ... |
777 778 779 780 781 782 783 |
{ int cpu; if (idx >= map->nr) return -1; cpu = map->map[idx]; |
6f6b6594b perf stat: Move *... |
784 785 |
if (config->cpus_aggr_map->map[cpu] == -1) config->cpus_aggr_map->map[cpu] = get_id(config, map, idx); |
1e5a29318 perf stat: Cache ... |
786 |
|
6f6b6594b perf stat: Move *... |
787 |
return config->cpus_aggr_map->map[cpu]; |
1e5a29318 perf stat: Cache ... |
788 |
} |
6f6b6594b perf stat: Move *... |
789 790 |
static int perf_stat__get_socket_cached(struct perf_stat_config *config, struct cpu_map *map, int idx) |
1e5a29318 perf stat: Cache ... |
791 |
{ |
6f6b6594b perf stat: Move *... |
792 |
return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx); |
1e5a29318 perf stat: Cache ... |
793 |
} |
6f6b6594b perf stat: Move *... |
794 795 |
static int perf_stat__get_core_cached(struct perf_stat_config *config, struct cpu_map *map, int idx) |
1e5a29318 perf stat: Cache ... |
796 |
{ |
6f6b6594b perf stat: Move *... |
797 |
return perf_stat__get_aggr(config, perf_stat__get_core, map, idx); |
1e5a29318 perf stat: Cache ... |
798 |
} |
4fc4d8dfa perf stat: Suppor... |
799 800 801 802 803 804 805 806 807 808 809 |
static bool term_percore_set(void) { struct perf_evsel *counter; evlist__for_each_entry(evsel_list, counter) { if (counter->percore) return true; } return false; } |
86ee6e18f perf stat: Refact... |
810 811 |
static int perf_stat_init_aggr_mode(void) { |
1e5a29318 perf stat: Cache ... |
812 |
int nr; |
421a50f3f perf stat: Introd... |
813 |
switch (stat_config.aggr_mode) { |
86ee6e18f perf stat: Refact... |
814 |
case AGGR_SOCKET: |
6f6b6594b perf stat: Move *... |
815 |
if (cpu_map__build_socket_map(evsel_list->cpus, &stat_config.aggr_map)) { |
86ee6e18f perf stat: Refact... |
816 817 818 |
perror("cannot build socket map"); return -1; } |
6f6b6594b perf stat: Move *... |
819 |
stat_config.aggr_get_id = perf_stat__get_socket_cached; |
86ee6e18f perf stat: Refact... |
820 |
break; |
12c08a9f5 perf stat: Add pe... |
821 |
case AGGR_CORE: |
6f6b6594b perf stat: Move *... |
822 |
if (cpu_map__build_core_map(evsel_list->cpus, &stat_config.aggr_map)) { |
12c08a9f5 perf stat: Add pe... |
823 824 825 |
perror("cannot build core map"); return -1; } |
6f6b6594b perf stat: Move *... |
826 |
stat_config.aggr_get_id = perf_stat__get_core_cached; |
12c08a9f5 perf stat: Add pe... |
827 |
break; |
86ee6e18f perf stat: Refact... |
828 |
case AGGR_NONE: |
4fc4d8dfa perf stat: Suppor... |
829 830 831 832 833 834 835 836 837 |
if (term_percore_set()) { if (cpu_map__build_core_map(evsel_list->cpus, &stat_config.aggr_map)) { perror("cannot build core map"); return -1; } stat_config.aggr_get_id = perf_stat__get_core_cached; } break; |
86ee6e18f perf stat: Refact... |
838 |
case AGGR_GLOBAL: |
32b8af82e perf stat: Introd... |
839 |
case AGGR_THREAD: |
208df99ed perf stat: Add AG... |
840 |
case AGGR_UNSET: |
86ee6e18f perf stat: Refact... |
841 842 843 |
default: break; } |
1e5a29318 perf stat: Cache ... |
844 845 846 847 848 849 850 |
/* * The evsel_list->cpus is the base we operate on, * taking the highest cpu number to be the size of * the aggregation translate cpumap. */ nr = cpu_map__get_max(evsel_list->cpus); |
6f6b6594b perf stat: Move *... |
851 852 |
stat_config.cpus_aggr_map = cpu_map__empty_new(nr + 1); return stat_config.cpus_aggr_map ? 0 : -ENOMEM; |
86ee6e18f perf stat: Refact... |
853 |
} |
544c2ae7b perf stat: Fix cm... |
854 855 |
static void perf_stat__exit_aggr_mode(void) { |
6f6b6594b perf stat: Move *... |
856 857 858 859 |
cpu_map__put(stat_config.aggr_map); cpu_map__put(stat_config.cpus_aggr_map); stat_config.aggr_map = NULL; stat_config.cpus_aggr_map = NULL; |
544c2ae7b perf stat: Fix cm... |
860 |
} |
68d702f7a perf stat report:... |
861 862 863 864 865 866 867 868 |
static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, int idx) { int cpu; if (idx > map->nr) return -1; cpu = map->map[idx]; |
da8a58b56 perf tools: Repla... |
869 |
if (cpu >= env->nr_cpus_avail) |
68d702f7a perf stat report:... |
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 |
return -1; return cpu; } static int perf_env__get_socket(struct cpu_map *map, int idx, void *data) { struct perf_env *env = data; int cpu = perf_env__get_cpu(env, map, idx); return cpu == -1 ? -1 : env->cpu[cpu].socket_id; } static int perf_env__get_core(struct cpu_map *map, int idx, void *data) { struct perf_env *env = data; int core = -1, cpu = perf_env__get_cpu(env, map, idx); if (cpu != -1) { int socket_id = env->cpu[cpu].socket_id; /* * Encode socket in upper 16 bits * core_id is relative to socket, and * we need a global id. So we combine * socket + core id. */ core = (socket_id << 16) | (env->cpu[cpu].core_id & 0xffff); } return core; } static int perf_env__build_socket_map(struct perf_env *env, struct cpu_map *cpus, struct cpu_map **sockp) { return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env); } static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus, struct cpu_map **corep) { return cpu_map__build_map(cpus, corep, perf_env__get_core, env); } |
6f6b6594b perf stat: Move *... |
914 915 |
static int perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused, struct cpu_map *map, int idx) |
68d702f7a perf stat report:... |
916 917 918 |
{ return perf_env__get_socket(map, idx, &perf_stat.session->header.env); } |
6f6b6594b perf stat: Move *... |
919 920 |
static int perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused, struct cpu_map *map, int idx) |
68d702f7a perf stat report:... |
921 922 923 924 925 926 927 928 929 930 |
{ return perf_env__get_core(map, idx, &perf_stat.session->header.env); } static int perf_stat_init_aggr_mode_file(struct perf_stat *st) { struct perf_env *env = &st->session->header.env; switch (stat_config.aggr_mode) { case AGGR_SOCKET: |
6f6b6594b perf stat: Move *... |
931 |
if (perf_env__build_socket_map(env, evsel_list->cpus, &stat_config.aggr_map)) { |
68d702f7a perf stat report:... |
932 933 934 |
perror("cannot build socket map"); return -1; } |
6f6b6594b perf stat: Move *... |
935 |
stat_config.aggr_get_id = perf_stat__get_socket_file; |
68d702f7a perf stat report:... |
936 937 |
break; case AGGR_CORE: |
6f6b6594b perf stat: Move *... |
938 |
if (perf_env__build_core_map(env, evsel_list->cpus, &stat_config.aggr_map)) { |
68d702f7a perf stat report:... |
939 940 941 |
perror("cannot build core map"); return -1; } |
6f6b6594b perf stat: Move *... |
942 |
stat_config.aggr_get_id = perf_stat__get_core_file; |
68d702f7a perf stat report:... |
943 944 945 946 947 948 949 950 951 952 953 |
break; case AGGR_NONE: case AGGR_GLOBAL: case AGGR_THREAD: case AGGR_UNSET: default: break; } return 0; } |
44b1e60ab perf stat: Basic ... |
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 |
static int topdown_filter_events(const char **attr, char **str, bool use_group) { int off = 0; int i; int len = 0; char *s; for (i = 0; attr[i]; i++) { if (pmu_have_event("cpu", attr[i])) { len += strlen(attr[i]) + 1; attr[i - off] = attr[i]; } else off++; } attr[i - off] = NULL; *str = malloc(len + 1 + 2); if (!*str) return -1; s = *str; if (i - off == 0) { *s = 0; return 0; } if (use_group) *s++ = '{'; for (i = 0; attr[i]; i++) { strcpy(s, attr[i]); s += strlen(s); *s++ = ','; } if (use_group) { s[-1] = '}'; *s = 0; } else s[-1] = 0; return 0; } __weak bool arch_topdown_check_group(bool *warn) { *warn = false; return false; } __weak void arch_topdown_group_warn(void) { } |
2cba3ffb9 perf stat: Add -d... |
1002 1003 1004 1005 1006 1007 |
/* * Add default attributes, if there were no attributes specified or * if -d/--detailed, -d -d or -d -d -d is used: */ static int add_default_attributes(void) { |
44b1e60ab perf stat: Basic ... |
1008 |
int err; |
9dec4473a perf stat: Check ... |
1009 |
struct perf_event_attr default_attrs0[] = { |
b070a547f perf stat: Don't ... |
1010 1011 1012 1013 1014 1015 1016 |
{ .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES }, { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS }, { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, |
9dec4473a perf stat: Check ... |
1017 1018 |
}; struct perf_event_attr frontend_attrs[] = { |
b070a547f perf stat: Don't ... |
1019 |
{ .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, |
9dec4473a perf stat: Check ... |
1020 1021 |
}; struct perf_event_attr backend_attrs[] = { |
b070a547f perf stat: Don't ... |
1022 |
{ .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, |
9dec4473a perf stat: Check ... |
1023 1024 |
}; struct perf_event_attr default_attrs1[] = { |
b070a547f perf stat: Don't ... |
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 |
{ .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, }; /* * Detailed stats (-d), covering the L1 and last level data caches: */ struct perf_event_attr detailed_attrs[] = { { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_L1D << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_L1D << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_LL << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_LL << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, }; /* * Very detailed stats (-d -d), covering the instruction cache and the TLB caches: */ struct perf_event_attr very_detailed_attrs[] = { { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_L1I << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_L1I << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_DTLB << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_DTLB << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_ITLB << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_ITLB << 0 | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, }; /* * Very, very detailed stats (-d -d -d), adding prefetch events: */ struct perf_event_attr very_very_detailed_attrs[] = { { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_L1D << 0 | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) }, { .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_L1D << 0 | (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) }, }; |
a5cfa6217 perf stat: Add ev... |
1121 |
struct parse_events_error errinfo; |
b070a547f perf stat: Don't ... |
1122 |
|
2cba3ffb9 perf stat: Add -d... |
1123 |
/* Set attrs if no event is selected and !null_run: */ |
aea0dca16 perf stat: Move '... |
1124 |
if (stat_config.null_run) |
2cba3ffb9 perf stat: Add -d... |
1125 |
return 0; |
4cabc3d1c tools/perf/stat: ... |
1126 |
if (transaction_run) { |
742d92ff2 perf stat: Add tr... |
1127 1128 1129 1130 1131 1132 1133 1134 1135 |
/* Handle -T as -M transaction. Once platform specific metrics * support has been added to the json files, all archictures * will use this approach. To determine transaction support * on an architecture test for such a metric name. */ if (metricgroup__has_metric("transaction")) { struct option opt = { .value = &evsel_list }; return metricgroup__parse_groups(&opt, "transaction", |
d0192fdba perf stat: Move '... |
1136 |
&stat_config.metric_events); |
742d92ff2 perf stat: Add tr... |
1137 |
} |
4cabc3d1c tools/perf/stat: ... |
1138 1139 |
if (pmu_have_event("cpu", "cycles-ct") && pmu_have_event("cpu", "el-start")) |
fca32340a perf stat: Fix co... |
1140 1141 |
err = parse_events(evsel_list, transaction_attrs, &errinfo); |
4cabc3d1c tools/perf/stat: ... |
1142 |
else |
fca32340a perf stat: Fix co... |
1143 1144 1145 |
err = parse_events(evsel_list, transaction_limited_attrs, &errinfo); |
a454742c1 perf stat: Remove... |
1146 |
if (err) { |
4cabc3d1c tools/perf/stat: ... |
1147 1148 |
fprintf(stderr, "Cannot set up transaction events "); |
a5cfa6217 perf stat: Add ev... |
1149 |
parse_events_print_error(&errinfo, transaction_attrs); |
4cabc3d1c tools/perf/stat: ... |
1150 1151 1152 1153 |
return -1; } return 0; } |
daefd0bc0 perf stat: Add su... |
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 |
if (smi_cost) { int smi; if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) { fprintf(stderr, "freeze_on_smi is not supported. "); return -1; } if (!smi) { if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) { fprintf(stderr, "Failed to set freeze_on_smi. "); return -1; } smi_reset = true; } if (pmu_have_event("msr", "aperf") && pmu_have_event("msr", "smi")) { if (!force_metric_only) |
0ce5aa026 perf stat: Move '... |
1175 |
stat_config.metric_only = true; |
a5cfa6217 perf stat: Add ev... |
1176 |
err = parse_events(evsel_list, smi_cost_attrs, &errinfo); |
daefd0bc0 perf stat: Add su... |
1177 1178 1179 1180 |
} else { fprintf(stderr, "To measure SMI cost, it needs " "msr/aperf/, msr/smi/ and cpu/cycles/ support "); |
a5cfa6217 perf stat: Add ev... |
1181 |
parse_events_print_error(&errinfo, smi_cost_attrs); |
daefd0bc0 perf stat: Add su... |
1182 1183 1184 1185 1186 1187 1188 1189 1190 |
return -1; } if (err) { fprintf(stderr, "Cannot set up SMI cost events "); return -1; } return 0; } |
44b1e60ab perf stat: Basic ... |
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 |
if (topdown_run) { char *str = NULL; bool warn = false; if (stat_config.aggr_mode != AGGR_GLOBAL && stat_config.aggr_mode != AGGR_CORE) { pr_err("top down event configuration requires --per-core mode "); return -1; } stat_config.aggr_mode = AGGR_CORE; if (nr_cgroups || !target__has_cpu(&target)) { pr_err("top down event configuration requires system-wide mode (-a) "); return -1; } if (!force_metric_only) |
0ce5aa026 perf stat: Move '... |
1209 |
stat_config.metric_only = true; |
44b1e60ab perf stat: Basic ... |
1210 1211 1212 1213 1214 1215 1216 1217 1218 |
if (topdown_filter_events(topdown_attrs, &str, arch_topdown_check_group(&warn)) < 0) { pr_err("Out of memory "); return -1; } if (topdown_attrs[0] && str) { if (warn) arch_topdown_group_warn(); |
a5cfa6217 perf stat: Add ev... |
1219 |
err = parse_events(evsel_list, str, &errinfo); |
44b1e60ab perf stat: Basic ... |
1220 1221 1222 1223 1224 1225 |
if (err) { fprintf(stderr, "Cannot set up top down events %s: %d ", str, err); free(str); |
a5cfa6217 perf stat: Add ev... |
1226 |
parse_events_print_error(&errinfo, str); |
44b1e60ab perf stat: Basic ... |
1227 1228 1229 1230 1231 1232 1233 1234 1235 |
return -1; } } else { fprintf(stderr, "System does not support topdown "); return -1; } free(str); } |
2cba3ffb9 perf stat: Add -d... |
1236 |
if (!evsel_list->nr_entries) { |
a1f3d5676 perf stat: Use cp... |
1237 1238 |
if (target__has_cpu(&target)) default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK; |
9dec4473a perf stat: Check ... |
1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 |
if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0) return -1; if (pmu_have_event("cpu", "stalled-cycles-frontend")) { if (perf_evlist__add_default_attrs(evsel_list, frontend_attrs) < 0) return -1; } if (pmu_have_event("cpu", "stalled-cycles-backend")) { if (perf_evlist__add_default_attrs(evsel_list, backend_attrs) < 0) return -1; } if (perf_evlist__add_default_attrs(evsel_list, default_attrs1) < 0) |
50d08e47b perf evlist: Intr... |
1252 |
return -1; |
2cba3ffb9 perf stat: Add -d... |
1253 1254 1255 1256 1257 1258 1259 1260 |
} /* Detailed events get appended to the event list: */ if (detailed_run < 1) return 0; /* Append detailed run extra attributes: */ |
79695e1bb perf stat: Initia... |
1261 |
if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) |
50d08e47b perf evlist: Intr... |
1262 |
return -1; |
2cba3ffb9 perf stat: Add -d... |
1263 1264 1265 1266 1267 |
if (detailed_run < 2) return 0; /* Append very detailed run extra attributes: */ |
79695e1bb perf stat: Initia... |
1268 |
if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) |
50d08e47b perf evlist: Intr... |
1269 |
return -1; |
2cba3ffb9 perf stat: Add -d... |
1270 1271 1272 1273 1274 |
if (detailed_run < 3) return 0; /* Append very, very detailed run extra attributes: */ |
79695e1bb perf stat: Initia... |
1275 |
return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); |
2cba3ffb9 perf stat: Add -d... |
1276 |
} |
8a59f3ccb perf stat: Fix re... |
1277 |
static const char * const stat_record_usage[] = { |
4979d0c7d perf stat record:... |
1278 1279 1280 |
"perf stat record [<options>]", NULL, }; |
3ba78bd00 perf stat record:... |
1281 1282 1283 1284 1285 1286 |
static void init_features(struct perf_session *session) { int feat; for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) perf_header__set_feat(&session->header, feat); |
8002a63f9 perf stat: Disabl... |
1287 |
perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT); |
3ba78bd00 perf stat record:... |
1288 1289 1290 1291 1292 |
perf_header__clear_feat(&session->header, HEADER_BUILD_ID); perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); perf_header__clear_feat(&session->header, HEADER_AUXTRACE); } |
4979d0c7d perf stat record:... |
1293 1294 1295 |
static int __cmd_record(int argc, const char **argv) { struct perf_session *session; |
8ceb41d7e perf tools: Renam... |
1296 |
struct perf_data *data = &perf_stat.data; |
4979d0c7d perf stat record:... |
1297 |
|
8a59f3ccb perf stat: Fix re... |
1298 |
argc = parse_options(argc, argv, stat_options, stat_record_usage, |
4979d0c7d perf stat record:... |
1299 1300 1301 |
PARSE_OPT_STOP_AT_NON_OPTION); if (output_name) |
2d4f27999 perf data: Add gl... |
1302 |
data->path = output_name; |
4979d0c7d perf stat record:... |
1303 |
|
d97ae04b3 perf stat: Move '... |
1304 |
if (stat_config.run_count != 1 || forever) { |
e9d6db8e8 perf stat record:... |
1305 1306 1307 1308 |
pr_err("Cannot use -r option with perf stat record. "); return -1; } |
8ceb41d7e perf tools: Renam... |
1309 |
session = perf_session__new(data, false, NULL); |
4979d0c7d perf stat record:... |
1310 1311 1312 1313 1314 |
if (session == NULL) { pr_err("Perf session creation failed. "); return -1; } |
3ba78bd00 perf stat record:... |
1315 |
init_features(session); |
4979d0c7d perf stat record:... |
1316 1317 1318 1319 1320 |
session->evlist = evsel_list; perf_stat.session = session; perf_stat.record = true; return argc; } |
89f1688a5 perf tools: Remov... |
1321 1322 |
static int process_stat_round_event(struct perf_session *session, union perf_event *event) |
a56f9390a perf stat report:... |
1323 |
{ |
e3b03b6c1 perf stat: Avoid ... |
1324 |
struct stat_round_event *stat_round = &event->stat_round; |
a56f9390a perf stat report:... |
1325 1326 1327 1328 |
struct perf_evsel *counter; struct timespec tsh, *ts = NULL; const char **argv = session->header.env.cmdline_argv; int argc = session->header.env.nr_cmdline; |
e5cadb93d perf evlist: Rena... |
1329 |
evlist__for_each_entry(evsel_list, counter) |
a56f9390a perf stat report:... |
1330 |
perf_stat_process_counter(&stat_config, counter); |
e3b03b6c1 perf stat: Avoid ... |
1331 1332 |
if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL) update_stats(&walltime_nsecs_stats, stat_round->time); |
a56f9390a perf stat report:... |
1333 |
|
e3b03b6c1 perf stat: Avoid ... |
1334 |
if (stat_config.interval && stat_round->time) { |
bd48c63eb tools: Introduce ... |
1335 1336 |
tsh.tv_sec = stat_round->time / NSEC_PER_SEC; tsh.tv_nsec = stat_round->time % NSEC_PER_SEC; |
a56f9390a perf stat report:... |
1337 1338 1339 1340 1341 1342 |
ts = &tsh; } print_counters(ts, argc, argv); return 0; } |
62ba18ba9 perf stat report:... |
1343 |
static |
89f1688a5 perf tools: Remov... |
1344 1345 |
int process_stat_config_event(struct perf_session *session, union perf_event *event) |
62ba18ba9 perf stat report:... |
1346 |
{ |
89f1688a5 perf tools: Remov... |
1347 |
struct perf_tool *tool = session->tool; |
68d702f7a perf stat report:... |
1348 |
struct perf_stat *st = container_of(tool, struct perf_stat, tool); |
62ba18ba9 perf stat report:... |
1349 |
perf_event__read_stat_config(&stat_config, &event->stat_config); |
68d702f7a perf stat report:... |
1350 |
|
89af4e05c perf stat report:... |
1351 1352 1353 1354 1355 1356 1357 1358 1359 |
if (cpu_map__empty(st->cpus)) { if (st->aggr_mode != AGGR_UNSET) pr_warning("warning: processing task data, aggregation mode not set "); return 0; } if (st->aggr_mode != AGGR_UNSET) stat_config.aggr_mode = st->aggr_mode; |
8ceb41d7e perf tools: Renam... |
1360 |
if (perf_stat.data.is_pipe) |
68d702f7a perf stat report:... |
1361 1362 1363 |
perf_stat_init_aggr_mode(); else perf_stat_init_aggr_mode_file(st); |
62ba18ba9 perf stat report:... |
1364 1365 |
return 0; } |
1975d36e1 perf stat report:... |
1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 |
static int set_maps(struct perf_stat *st) { if (!st->cpus || !st->threads) return 0; if (WARN_ONCE(st->maps_allocated, "stats double allocation ")) return -EINVAL; perf_evlist__set_maps(evsel_list, st->cpus, st->threads); if (perf_evlist__alloc_stats(evsel_list, true)) return -ENOMEM; st->maps_allocated = true; return 0; } static |
89f1688a5 perf tools: Remov... |
1385 1386 |
int process_thread_map_event(struct perf_session *session, union perf_event *event) |
1975d36e1 perf stat report:... |
1387 |
{ |
89f1688a5 perf tools: Remov... |
1388 |
struct perf_tool *tool = session->tool; |
1975d36e1 perf stat report:... |
1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 |
struct perf_stat *st = container_of(tool, struct perf_stat, tool); if (st->threads) { pr_warning("Extra thread map event, ignoring. "); return 0; } st->threads = thread_map__new_event(&event->thread_map); if (!st->threads) return -ENOMEM; return set_maps(st); } static |
89f1688a5 perf tools: Remov... |
1405 1406 |
int process_cpu_map_event(struct perf_session *session, union perf_event *event) |
1975d36e1 perf stat report:... |
1407 |
{ |
89f1688a5 perf tools: Remov... |
1408 |
struct perf_tool *tool = session->tool; |
1975d36e1 perf stat report:... |
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 |
struct perf_stat *st = container_of(tool, struct perf_stat, tool); struct cpu_map *cpus; if (st->cpus) { pr_warning("Extra cpu map event, ignoring. "); return 0; } cpus = cpu_map__new_data(&event->cpu_map.data); if (!cpus) return -ENOMEM; st->cpus = cpus; return set_maps(st); } |
56739444d perf stat: Alloca... |
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 |
static int runtime_stat_new(struct perf_stat_config *config, int nthreads) { int i; config->stats = calloc(nthreads, sizeof(struct runtime_stat)); if (!config->stats) return -1; config->stats_num = nthreads; for (i = 0; i < nthreads; i++) runtime_stat__init(&config->stats[i]); return 0; } static void runtime_stat_delete(struct perf_stat_config *config) { int i; if (!config->stats) return; for (i = 0; i < config->stats_num; i++) runtime_stat__exit(&config->stats[i]); free(config->stats); } |
8a59f3ccb perf stat: Fix re... |
1453 |
static const char * const stat_report_usage[] = { |
ba6039b6c perf stat report:... |
1454 1455 1456 1457 1458 1459 1460 |
"perf stat report [<options>]", NULL, }; static struct perf_stat perf_stat = { .tool = { .attr = perf_event__process_attr, |
fa6ea7817 perf stat report:... |
1461 |
.event_update = perf_event__process_event_update, |
1975d36e1 perf stat report:... |
1462 1463 |
.thread_map = process_thread_map_event, .cpu_map = process_cpu_map_event, |
62ba18ba9 perf stat report:... |
1464 |
.stat_config = process_stat_config_event, |
a56f9390a perf stat report:... |
1465 1466 |
.stat = perf_event__process_stat_event, .stat_round = process_stat_round_event, |
ba6039b6c perf stat report:... |
1467 |
}, |
89af4e05c perf stat report:... |
1468 |
.aggr_mode = AGGR_UNSET, |
ba6039b6c perf stat report:... |
1469 1470 1471 1472 1473 1474 1475 |
}; static int __cmd_report(int argc, const char **argv) { struct perf_session *session; const struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), |
89af4e05c perf stat report:... |
1476 1477 1478 1479 1480 1481 |
OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode, "aggregate counts per processor socket", AGGR_SOCKET), OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode, "aggregate counts per physical processor core", AGGR_CORE), OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode, "disable CPU count aggregation", AGGR_NONE), |
ba6039b6c perf stat report:... |
1482 1483 1484 1485 |
OPT_END() }; struct stat st; int ret; |
8a59f3ccb perf stat: Fix re... |
1486 |
argc = parse_options(argc, argv, options, stat_report_usage, 0); |
ba6039b6c perf stat report:... |
1487 1488 1489 1490 1491 1492 1493 |
if (!input_name || !strlen(input_name)) { if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) input_name = "-"; else input_name = "perf.data"; } |
2d4f27999 perf data: Add gl... |
1494 1495 |
perf_stat.data.path = input_name; perf_stat.data.mode = PERF_DATA_MODE_READ; |
ba6039b6c perf stat report:... |
1496 |
|
8ceb41d7e perf tools: Renam... |
1497 |
session = perf_session__new(&perf_stat.data, false, &perf_stat.tool); |
ba6039b6c perf stat report:... |
1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 |
if (session == NULL) return -1; perf_stat.session = session; stat_config.output = stderr; evsel_list = session->evlist; ret = perf_session__process_events(session); if (ret) return ret; perf_session__delete(session); return 0; } |
e3ba76dee perf tools: Force... |
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 |
static void setup_system_wide(int forks) { /* * Make system wide (-a) the default target if * no target was specified and one of following * conditions is met: * * - there's no workload specified * - there is workload specified but all requested * events are system wide events */ if (!target__none(&target)) return; if (!forks) target.system_wide = true; else { struct perf_evsel *counter; evlist__for_each_entry(evsel_list, counter) { if (!counter->system_wide) return; } if (evsel_list->nr_entries) target.system_wide = true; } } |
b0ad8ea66 perf tools: Remov... |
1540 |
int cmd_stat(int argc, const char **argv) |
5242519b0 perf stat: Conver... |
1541 |
{ |
b070a547f perf stat: Don't ... |
1542 1543 1544 1545 |
const char * const stat_usage[] = { "perf stat [<options>] [<command>]", NULL }; |
cc03c5429 perf stat: Enhanc... |
1546 |
int status = -EINVAL, run_idx; |
4aa9015f8 perf stat: Add -o... |
1547 |
const char *mode; |
5821522e9 perf stat: Move '... |
1548 |
FILE *output = stderr; |
f1f8ad52f perf stat: Add su... |
1549 |
unsigned int interval, timeout; |
ba6039b6c perf stat report:... |
1550 |
const char * const stat_subcommands[] = { "record", "report" }; |
42202dd56 perf stat: Add fe... |
1551 |
|
5af52b51f perf stat: add pe... |
1552 |
setlocale(LC_ALL, ""); |
334fe7a3c perf evlist: Remo... |
1553 |
evsel_list = perf_evlist__new(); |
361c99a66 perf evsel: Intro... |
1554 1555 |
if (evsel_list == NULL) return -ENOMEM; |
1669e509e perf stat: Bail o... |
1556 |
parse_events__shrink_config_terms(); |
51433ead1 perf stat: Avoid ... |
1557 1558 1559 1560 1561 |
/* String-parsing callback-based options would segfault when negated */ set_option_flag(stat_options, 'e', "event", PARSE_OPT_NONEG); set_option_flag(stat_options, 'M', "metrics", PARSE_OPT_NONEG); set_option_flag(stat_options, 'G', "cgroup", PARSE_OPT_NONEG); |
4979d0c7d perf stat record:... |
1562 1563 1564 |
argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands, (const char **) stat_usage, PARSE_OPT_STOP_AT_NON_OPTION); |
37932c188 perf stat: Output... |
1565 |
perf_stat__collect_metric_expr(evsel_list); |
fb4605ba4 perf stat: Check ... |
1566 |
perf_stat__init_shadow_stats(); |
4979d0c7d perf stat record:... |
1567 |
|
fa7070a38 perf stat: Move c... |
1568 1569 1570 1571 |
if (stat_config.csv_sep) { stat_config.csv_output = true; if (!strcmp(stat_config.csv_sep, "\\t")) stat_config.csv_sep = "\t"; |
6edb78a21 perf stat report:... |
1572 |
} else |
fa7070a38 perf stat: Move c... |
1573 |
stat_config.csv_sep = DEFAULT_SEPARATOR; |
6edb78a21 perf stat report:... |
1574 |
|
4979d0c7d perf stat record:... |
1575 1576 1577 1578 |
if (argc && !strncmp(argv[0], "rec", 3)) { argc = __cmd_record(argc, argv); if (argc < 0) return -1; |
ba6039b6c perf stat report:... |
1579 1580 |
} else if (argc && !strncmp(argv[0], "rep", 3)) return __cmd_report(argc, argv); |
d7470b6af perf stat: Add cs... |
1581 |
|
ec0d3d1fd perf stat: Move '... |
1582 |
interval = stat_config.interval; |
f1f8ad52f perf stat: Add su... |
1583 |
timeout = stat_config.timeout; |
ec0d3d1fd perf stat: Move '... |
1584 |
|
4979d0c7d perf stat record:... |
1585 1586 1587 1588 |
/* * For record command the -o is already taken care of. */ if (!STAT_RECORD && output_name && strcmp(output_name, "-")) |
4aa9015f8 perf stat: Add -o... |
1589 |
output = NULL; |
56f3bae70 perf stat: Add --... |
1590 1591 1592 |
if (output_name && output_fd) { fprintf(stderr, "cannot use both --output and --log-fd "); |
e05473111 perf stat: Make s... |
1593 1594 |
parse_options_usage(stat_usage, stat_options, "o", 1); parse_options_usage(NULL, stat_options, "log-fd", 0); |
cc03c5429 perf stat: Enhanc... |
1595 |
goto out; |
56f3bae70 perf stat: Add --... |
1596 |
} |
fc3e4d077 perf stat: Fix de... |
1597 |
|
0ce5aa026 perf stat: Move '... |
1598 |
if (stat_config.metric_only && stat_config.aggr_mode == AGGR_THREAD) { |
54b509160 perf stat: Implem... |
1599 1600 1601 1602 |
fprintf(stderr, "--metric-only is not supported with --per-thread "); goto out; } |
d97ae04b3 perf stat: Move '... |
1603 |
if (stat_config.metric_only && stat_config.run_count > 1) { |
54b509160 perf stat: Implem... |
1604 1605 1606 1607 |
fprintf(stderr, "--metric-only is not supported with -r "); goto out; } |
54ac0b1bd perf stat: Move '... |
1608 |
if (stat_config.walltime_run_table && stat_config.run_count <= 1) { |
e55c14af4 perf stat: Add --... |
1609 1610 1611 1612 1613 1614 |
fprintf(stderr, "--table is only supported with -r "); parse_options_usage(stat_usage, stat_options, "r", 1); parse_options_usage(NULL, stat_options, "table", 0); goto out; } |
fc3e4d077 perf stat: Fix de... |
1615 1616 1617 |
if (output_fd < 0) { fprintf(stderr, "argument to --log-fd must be a > 0 "); |
e05473111 perf stat: Make s... |
1618 |
parse_options_usage(stat_usage, stat_options, "log-fd", 0); |
cc03c5429 perf stat: Enhanc... |
1619 |
goto out; |
fc3e4d077 perf stat: Fix de... |
1620 |
} |
4aa9015f8 perf stat: Add -o... |
1621 1622 1623 1624 1625 1626 1627 |
if (!output) { struct timespec tm; mode = append_file ? "a" : "w"; output = fopen(output_name, mode); if (!output) { perror("failed to create output file"); |
fceda7feb perf stat: Remove... |
1628 |
return -1; |
4aa9015f8 perf stat: Add -o... |
1629 1630 1631 1632 |
} clock_gettime(CLOCK_REALTIME, &tm); fprintf(output, "# started on %s ", ctime(&tm.tv_sec)); |
fc3e4d077 perf stat: Fix de... |
1633 |
} else if (output_fd > 0) { |
56f3bae70 perf stat: Add --... |
1634 1635 1636 1637 1638 1639 |
mode = append_file ? "a" : "w"; output = fdopen(output_fd, mode); if (!output) { perror("Failed opening logfd"); return -errno; } |
4aa9015f8 perf stat: Add -o... |
1640 |
} |
5821522e9 perf stat: Move '... |
1641 |
stat_config.output = output; |
d7470b6af perf stat: Add cs... |
1642 1643 1644 |
/* * let the spreadsheet do the pretty-printing */ |
fa7070a38 perf stat: Move c... |
1645 |
if (stat_config.csv_output) { |
61a9f3242 perf stat: Fix sp... |
1646 |
/* User explicitly passed -B? */ |
d7470b6af perf stat: Add cs... |
1647 1648 1649 |
if (big_num_opt == 1) { fprintf(stderr, "-B option not supported with -x "); |
e05473111 perf stat: Make s... |
1650 1651 |
parse_options_usage(stat_usage, stat_options, "B", 1); parse_options_usage(NULL, stat_options, "x", 1); |
cc03c5429 perf stat: Enhanc... |
1652 |
goto out; |
d7470b6af perf stat: Add cs... |
1653 |
} else /* Nope, so disable big number formatting */ |
34ff0866d perf stat: Move '... |
1654 |
stat_config.big_num = false; |
d7470b6af perf stat: Add cs... |
1655 |
} else if (big_num_opt == 0) /* User passed --no-big-num */ |
34ff0866d perf stat: Move '... |
1656 |
stat_config.big_num = false; |
d7470b6af perf stat: Add cs... |
1657 |
|
e3ba76dee perf tools: Force... |
1658 |
setup_system_wide(argc); |
ac3063bd4 perf stat: Don't ... |
1659 |
|
0ce2da148 perf stat: Displa... |
1660 1661 1662 1663 |
/* * Display user/system times only for single * run and when there's specified tracee. */ |
d97ae04b3 perf stat: Move '... |
1664 |
if ((stat_config.run_count == 1) && target__none(&target)) |
8897a8916 perf stat: Move r... |
1665 |
stat_config.ru_display = true; |
0ce2da148 perf stat: Displa... |
1666 |
|
d97ae04b3 perf stat: Move '... |
1667 |
if (stat_config.run_count < 0) { |
cc03c5429 perf stat: Enhanc... |
1668 1669 |
pr_err("Run count must be a positive number "); |
e05473111 perf stat: Make s... |
1670 |
parse_options_usage(stat_usage, stat_options, "r", 1); |
cc03c5429 perf stat: Enhanc... |
1671 |
goto out; |
d97ae04b3 perf stat: Move '... |
1672 |
} else if (stat_config.run_count == 0) { |
a7e191c37 perf stat: Introd... |
1673 |
forever = true; |
d97ae04b3 perf stat: Move '... |
1674 |
stat_config.run_count = 1; |
a7e191c37 perf stat: Introd... |
1675 |
} |
ddcacfa0f perf_counter tool... |
1676 |
|
54ac0b1bd perf stat: Move '... |
1677 1678 1679 |
if (stat_config.walltime_run_table) { stat_config.walltime_run = zalloc(stat_config.run_count * sizeof(stat_config.walltime_run[0])); if (!stat_config.walltime_run) { |
e55c14af4 perf stat: Add --... |
1680 1681 1682 1683 |
pr_err("failed to setup -r option"); goto out; } } |
1d9f8d1b8 perf stat: Remove... |
1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 |
if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) { if (!target.system_wide || target.cpu_list) { fprintf(stderr, "The --per-thread option is only " "available when monitoring via -p -t -a " "options or only --per-thread. "); parse_options_usage(NULL, stat_options, "p", 1); parse_options_usage(NULL, stat_options, "t", 1); goto out; } |
32b8af82e perf stat: Introd... |
1695 1696 1697 1698 1699 1700 |
} /* * no_aggr, cgroup are for system-wide only * --per-thread is aggregated per thread, we dont mix it with cpu mode */ |
421a50f3f perf stat: Introd... |
1701 1702 |
if (((stat_config.aggr_mode != AGGR_GLOBAL && stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) && |
602ad878d perf target: Shor... |
1703 |
!target__has_cpu(&target)) { |
023695d96 perf tool: Add cg... |
1704 1705 1706 |
fprintf(stderr, "both cgroup and no-aggregation " "modes only available in system-wide mode "); |
e05473111 perf stat: Make s... |
1707 1708 1709 |
parse_options_usage(stat_usage, stat_options, "G", 1); parse_options_usage(NULL, stat_options, "A", 1); parse_options_usage(NULL, stat_options, "a", 1); |
cc03c5429 perf stat: Enhanc... |
1710 |
goto out; |
d7e7a451c perf stat: Add pe... |
1711 |
} |
2cba3ffb9 perf stat: Add -d... |
1712 1713 |
if (add_default_attributes()) goto out; |
ddcacfa0f perf_counter tool... |
1714 |
|
602ad878d perf target: Shor... |
1715 |
target__validate(&target); |
5c98d466e perf tools: Refac... |
1716 |
|
1d9f8d1b8 perf stat: Remove... |
1717 1718 |
if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide)) target.per_thread = true; |
77a6f014e perf stat: Use pe... |
1719 |
if (perf_evlist__create_maps(evsel_list, &target) < 0) { |
602ad878d perf target: Shor... |
1720 |
if (target__has_task(&target)) { |
77a6f014e perf stat: Use pe... |
1721 1722 |
pr_err("Problems finding threads of monitor "); |
e05473111 perf stat: Make s... |
1723 1724 |
parse_options_usage(stat_usage, stat_options, "p", 1); parse_options_usage(NULL, stat_options, "t", 1); |
602ad878d perf target: Shor... |
1725 |
} else if (target__has_cpu(&target)) { |
77a6f014e perf stat: Use pe... |
1726 |
perror("failed to parse CPUs map"); |
e05473111 perf stat: Make s... |
1727 1728 |
parse_options_usage(stat_usage, stat_options, "C", 1); parse_options_usage(NULL, stat_options, "a", 1); |
cc03c5429 perf stat: Enhanc... |
1729 1730 |
} goto out; |
60d567e2d perf tools: Refac... |
1731 |
} |
32b8af82e perf stat: Introd... |
1732 1733 1734 1735 1736 |
/* * Initialize thread_map with comm names, * so we could print it out on output. */ |
56739444d perf stat: Alloca... |
1737 |
if (stat_config.aggr_mode == AGGR_THREAD) { |
32b8af82e perf stat: Introd... |
1738 |
thread_map__read_comms(evsel_list->threads); |
56739444d perf stat: Alloca... |
1739 1740 1741 1742 1743 1744 1745 |
if (target.system_wide) { if (runtime_stat_new(&stat_config, thread_map__nr(evsel_list->threads))) { goto out; } } } |
32b8af82e perf stat: Introd... |
1746 |
|
db06a269e perf stat: Add su... |
1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 |
if (stat_config.times && interval) interval_count = true; else if (stat_config.times && !interval) { pr_err("interval-count option should be used together with " "interval-print. "); parse_options_usage(stat_usage, stat_options, "interval-count", 0); parse_options_usage(stat_usage, stat_options, "I", 1); goto out; } |
c45c6ea2e perf tools: Add t... |
1757 |
|
f1f8ad52f perf stat: Add su... |
1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 |
if (timeout && timeout < 100) { if (timeout < 10) { pr_err("timeout must be >= 10ms. "); parse_options_usage(stat_usage, stat_options, "timeout", 0); goto out; } else pr_warning("timeout < 100ms. " "The overhead percentage could be high in some cases. " "Please proceed with caution. "); } if (timeout && interval) { pr_err("timeout option is not supported with interval-print. "); parse_options_usage(stat_usage, stat_options, "timeout", 0); parse_options_usage(stat_usage, stat_options, "I", 1); goto out; } |
d134ffb91 perf stat: Introd... |
1777 |
if (perf_evlist__alloc_stats(evsel_list, interval)) |
03ad9747c perf evlist: Move... |
1778 |
goto out; |
d6d901c23 perf events: Chan... |
1779 |
|
86ee6e18f perf stat: Refact... |
1780 |
if (perf_stat_init_aggr_mode()) |
03ad9747c perf evlist: Move... |
1781 |
goto out; |
86ee6e18f perf stat: Refact... |
1782 |
|
58d7e993b perf stat: handle... |
1783 |
/* |
7d9ad16af perf stat: Add 'i... |
1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 |
* Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless * while avoiding that older tools show confusing messages. * * However for pipe sessions we need to keep it zero, * because script's perf_evsel__check_attr is triggered * by attr->sample_type != 0, and we can't run it on * stat sessions. */ stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe); /* |
58d7e993b perf stat: handle... |
1795 1796 1797 1798 1799 |
* We dont want to block the signals - that would cause * child tasks to inherit that and Ctrl-C would not work. * What we want is for Ctrl-C to work in the exec()-ed * task, but being ignored by perf stat itself: */ |
f7b7c26e0 perf_counter tool... |
1800 |
atexit(sig_atexit); |
a7e191c37 perf stat: Introd... |
1801 1802 |
if (!forever) signal(SIGINT, skip_signal); |
13370a9b5 perf stat: Add in... |
1803 |
signal(SIGCHLD, skip_signal); |
58d7e993b perf stat: handle... |
1804 1805 |
signal(SIGALRM, skip_signal); signal(SIGABRT, skip_signal); |
42202dd56 perf stat: Add fe... |
1806 |
status = 0; |
d97ae04b3 perf stat: Move '... |
1807 1808 |
for (run_idx = 0; forever || run_idx < stat_config.run_count; run_idx++) { if (stat_config.run_count != 1 && verbose > 0) |
4aa9015f8 perf stat: Add -o... |
1809 1810 1811 |
fprintf(output, "[ perf stat: executing run #%d ... ] ", run_idx + 1); |
f9cef0a90 perf stat: Add --... |
1812 |
|
e55c14af4 perf stat: Add --... |
1813 |
status = run_perf_stat(argc, argv, run_idx); |
a7e191c37 perf stat: Introd... |
1814 |
if (forever && status != -1) { |
d4f63a474 perf stat: Introd... |
1815 |
print_counters(NULL, argc, argv); |
254ecbc74 perf stat: Introd... |
1816 |
perf_stat__reset_stats(); |
a7e191c37 perf stat: Introd... |
1817 |
} |
42202dd56 perf stat: Add fe... |
1818 |
} |
a7e191c37 perf stat: Introd... |
1819 |
if (!forever && status != -1 && !interval) |
d4f63a474 perf stat: Introd... |
1820 |
print_counters(NULL, argc, argv); |
d134ffb91 perf stat: Introd... |
1821 |
|
4979d0c7d perf stat record:... |
1822 1823 1824 1825 1826 1827 1828 1829 |
if (STAT_RECORD) { /* * We synthesize the kernel mmap record just so that older tools * don't emit warnings about not being able to resolve symbols * due to /proc/sys/kernel/kptr_restrict settings and instear provide * a saner message about no samples being in the perf.data file. * * This also serves to suppress a warning about f_header.data.size == 0 |
8b99b1a4e perf stat record:... |
1830 1831 1832 1833 |
* in header.c at the moment 'perf stat record' gets introduced, which * is not really needed once we start adding the stat specific PERF_RECORD_ * records, but the need to suppress the kptr_restrict messages in older * tools remain -acme |
4979d0c7d perf stat record:... |
1834 |
*/ |
8ceb41d7e perf tools: Renam... |
1835 |
int fd = perf_data__fd(&perf_stat.data); |
4979d0c7d perf stat record:... |
1836 1837 1838 1839 1840 1841 1842 1843 |
int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat, process_synthesized_event, &perf_stat.session->machines.host); if (err) { pr_warning("Couldn't synthesize the kernel mmap record, harmless, " "older tools may produce warnings about this file ."); } |
7aad0c32b perf stat record:... |
1844 1845 1846 1847 1848 |
if (!interval) { if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL)) pr_err("failed to write stat round event "); } |
8ceb41d7e perf tools: Renam... |
1849 |
if (!perf_stat.data.is_pipe) { |
664c98d4e perf stat record:... |
1850 1851 1852 |
perf_stat.session->header.data_size += perf_stat.bytes_written; perf_session__write_header(perf_stat.session, evsel_list, fd, true); } |
4979d0c7d perf stat record:... |
1853 1854 1855 |
perf_session__delete(perf_stat.session); } |
544c2ae7b perf stat: Fix cm... |
1856 |
perf_stat__exit_aggr_mode(); |
d134ffb91 perf stat: Introd... |
1857 |
perf_evlist__free_stats(evsel_list); |
0015e2e10 perf stat: Fix up... |
1858 |
out: |
54ac0b1bd perf stat: Move '... |
1859 |
free(stat_config.walltime_run); |
e55c14af4 perf stat: Add --... |
1860 |
|
daefd0bc0 perf stat: Add su... |
1861 1862 |
if (smi_cost && smi_reset) sysfs__write_int(FREEZE_ON_SMI_PATH, 0); |
0015e2e10 perf stat: Fix up... |
1863 |
perf_evlist__delete(evsel_list); |
56739444d perf stat: Alloca... |
1864 1865 |
runtime_stat_delete(&stat_config); |
42202dd56 perf stat: Add fe... |
1866 |
return status; |
ddcacfa0f perf_counter tool... |
1867 |
} |