.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * intel-bts.c: Intel Processor Trace support |
---|
3 | 4 | * Copyright (c) 2013-2015, Intel Corporation. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms and conditions of the GNU General Public License, |
---|
7 | | - * version 2, as published by the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
12 | | - * more details. |
---|
13 | | - * |
---|
14 | 5 | */ |
---|
15 | 6 | |
---|
16 | 7 | #include <errno.h> |
---|
.. | .. |
---|
18 | 9 | #include <linux/types.h> |
---|
19 | 10 | #include <linux/bitops.h> |
---|
20 | 11 | #include <linux/log2.h> |
---|
| 12 | +#include <linux/zalloc.h> |
---|
21 | 13 | |
---|
22 | | -#include "../../util/cpumap.h" |
---|
23 | | -#include "../../util/evsel.h" |
---|
24 | | -#include "../../util/evlist.h" |
---|
25 | | -#include "../../util/session.h" |
---|
26 | | -#include "../../util/util.h" |
---|
27 | | -#include "../../util/pmu.h" |
---|
28 | | -#include "../../util/debug.h" |
---|
29 | | -#include "../../util/tsc.h" |
---|
30 | | -#include "../../util/auxtrace.h" |
---|
31 | | -#include "../../util/intel-bts.h" |
---|
| 14 | +#include "../../../util/cpumap.h" |
---|
| 15 | +#include "../../../util/event.h" |
---|
| 16 | +#include "../../../util/evsel.h" |
---|
| 17 | +#include "../../../util/evlist.h" |
---|
| 18 | +#include "../../../util/mmap.h" |
---|
| 19 | +#include "../../../util/session.h" |
---|
| 20 | +#include "../../../util/pmu.h" |
---|
| 21 | +#include "../../../util/debug.h" |
---|
| 22 | +#include "../../../util/record.h" |
---|
| 23 | +#include "../../../util/tsc.h" |
---|
| 24 | +#include "../../../util/auxtrace.h" |
---|
| 25 | +#include "../../../util/intel-bts.h" |
---|
| 26 | +#include <internal/lib.h> // page_size |
---|
32 | 27 | |
---|
33 | 28 | #define KiB(x) ((x) * 1024) |
---|
34 | 29 | #define MiB(x) ((x) * 1024 * 1024) |
---|
.. | .. |
---|
44 | 39 | struct intel_bts_recording { |
---|
45 | 40 | struct auxtrace_record itr; |
---|
46 | 41 | struct perf_pmu *intel_bts_pmu; |
---|
47 | | - struct perf_evlist *evlist; |
---|
| 42 | + struct evlist *evlist; |
---|
48 | 43 | bool snapshot_mode; |
---|
49 | 44 | size_t snapshot_size; |
---|
50 | 45 | int snapshot_ref_cnt; |
---|
.. | .. |
---|
59 | 54 | |
---|
60 | 55 | static size_t |
---|
61 | 56 | intel_bts_info_priv_size(struct auxtrace_record *itr __maybe_unused, |
---|
62 | | - struct perf_evlist *evlist __maybe_unused) |
---|
| 57 | + struct evlist *evlist __maybe_unused) |
---|
63 | 58 | { |
---|
64 | 59 | return INTEL_BTS_AUXTRACE_PRIV_SIZE; |
---|
65 | 60 | } |
---|
66 | 61 | |
---|
67 | 62 | static int intel_bts_info_fill(struct auxtrace_record *itr, |
---|
68 | 63 | struct perf_session *session, |
---|
69 | | - struct auxtrace_info_event *auxtrace_info, |
---|
| 64 | + struct perf_record_auxtrace_info *auxtrace_info, |
---|
70 | 65 | size_t priv_size) |
---|
71 | 66 | { |
---|
72 | 67 | struct intel_bts_recording *btsr = |
---|
.. | .. |
---|
80 | 75 | if (priv_size != INTEL_BTS_AUXTRACE_PRIV_SIZE) |
---|
81 | 76 | return -EINVAL; |
---|
82 | 77 | |
---|
83 | | - if (!session->evlist->nr_mmaps) |
---|
| 78 | + if (!session->evlist->core.nr_mmaps) |
---|
84 | 79 | return -EINVAL; |
---|
85 | 80 | |
---|
86 | | - pc = session->evlist->mmap[0].base; |
---|
| 81 | + pc = session->evlist->mmap[0].core.base; |
---|
87 | 82 | if (pc) { |
---|
88 | 83 | err = perf_read_tsc_conversion(pc, &tc); |
---|
89 | 84 | if (err) { |
---|
.. | .. |
---|
108 | 103 | } |
---|
109 | 104 | |
---|
110 | 105 | static int intel_bts_recording_options(struct auxtrace_record *itr, |
---|
111 | | - struct perf_evlist *evlist, |
---|
| 106 | + struct evlist *evlist, |
---|
112 | 107 | struct record_opts *opts) |
---|
113 | 108 | { |
---|
114 | 109 | struct intel_bts_recording *btsr = |
---|
115 | 110 | container_of(itr, struct intel_bts_recording, itr); |
---|
116 | 111 | struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu; |
---|
117 | | - struct perf_evsel *evsel, *intel_bts_evsel = NULL; |
---|
118 | | - const struct cpu_map *cpus = evlist->cpus; |
---|
119 | | - bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; |
---|
| 112 | + struct evsel *evsel, *intel_bts_evsel = NULL; |
---|
| 113 | + const struct perf_cpu_map *cpus = evlist->core.cpus; |
---|
| 114 | + bool privileged = perf_event_paranoid_check(-1); |
---|
| 115 | + |
---|
| 116 | + if (opts->auxtrace_sample_mode) { |
---|
| 117 | + pr_err("Intel BTS does not support AUX area sampling\n"); |
---|
| 118 | + return -EINVAL; |
---|
| 119 | + } |
---|
120 | 120 | |
---|
121 | 121 | btsr->evlist = evlist; |
---|
122 | 122 | btsr->snapshot_mode = opts->auxtrace_snapshot_mode; |
---|
123 | 123 | |
---|
124 | 124 | evlist__for_each_entry(evlist, evsel) { |
---|
125 | | - if (evsel->attr.type == intel_bts_pmu->type) { |
---|
| 125 | + if (evsel->core.attr.type == intel_bts_pmu->type) { |
---|
126 | 126 | if (intel_bts_evsel) { |
---|
127 | 127 | pr_err("There may be only one " INTEL_BTS_PMU_NAME " event\n"); |
---|
128 | 128 | return -EINVAL; |
---|
129 | 129 | } |
---|
130 | | - evsel->attr.freq = 0; |
---|
131 | | - evsel->attr.sample_period = 1; |
---|
| 130 | + evsel->core.attr.freq = 0; |
---|
| 131 | + evsel->core.attr.sample_period = 1; |
---|
132 | 132 | intel_bts_evsel = evsel; |
---|
133 | 133 | opts->full_auxtrace = true; |
---|
134 | 134 | } |
---|
.. | .. |
---|
142 | 142 | if (!opts->full_auxtrace) |
---|
143 | 143 | return 0; |
---|
144 | 144 | |
---|
145 | | - if (opts->full_auxtrace && !cpu_map__empty(cpus)) { |
---|
| 145 | + if (opts->full_auxtrace && !perf_cpu_map__empty(cpus)) { |
---|
146 | 146 | pr_err(INTEL_BTS_PMU_NAME " does not support per-cpu recording\n"); |
---|
147 | 147 | return -EINVAL; |
---|
148 | 148 | } |
---|
.. | .. |
---|
223 | 223 | * In the case of per-cpu mmaps, we need the CPU on the |
---|
224 | 224 | * AUX event. |
---|
225 | 225 | */ |
---|
226 | | - if (!cpu_map__empty(cpus)) |
---|
227 | | - perf_evsel__set_sample_bit(intel_bts_evsel, CPU); |
---|
| 226 | + if (!perf_cpu_map__empty(cpus)) |
---|
| 227 | + evsel__set_sample_bit(intel_bts_evsel, CPU); |
---|
228 | 228 | } |
---|
229 | 229 | |
---|
230 | 230 | /* Add dummy event to keep tracking */ |
---|
231 | 231 | if (opts->full_auxtrace) { |
---|
232 | | - struct perf_evsel *tracking_evsel; |
---|
| 232 | + struct evsel *tracking_evsel; |
---|
233 | 233 | int err; |
---|
234 | 234 | |
---|
235 | 235 | err = parse_events(evlist, "dummy:u", NULL); |
---|
236 | 236 | if (err) |
---|
237 | 237 | return err; |
---|
238 | 238 | |
---|
239 | | - tracking_evsel = perf_evlist__last(evlist); |
---|
| 239 | + tracking_evsel = evlist__last(evlist); |
---|
240 | 240 | |
---|
241 | 241 | perf_evlist__set_tracking_event(evlist, tracking_evsel); |
---|
242 | 242 | |
---|
243 | | - tracking_evsel->attr.freq = 0; |
---|
244 | | - tracking_evsel->attr.sample_period = 1; |
---|
| 243 | + tracking_evsel->core.attr.freq = 0; |
---|
| 244 | + tracking_evsel->core.attr.sample_period = 1; |
---|
245 | 245 | } |
---|
246 | 246 | |
---|
247 | 247 | return 0; |
---|
.. | .. |
---|
322 | 322 | { |
---|
323 | 323 | struct intel_bts_recording *btsr = |
---|
324 | 324 | container_of(itr, struct intel_bts_recording, itr); |
---|
325 | | - struct perf_evsel *evsel; |
---|
| 325 | + struct evsel *evsel; |
---|
326 | 326 | |
---|
327 | 327 | evlist__for_each_entry(btsr->evlist, evsel) { |
---|
328 | | - if (evsel->attr.type == btsr->intel_bts_pmu->type) |
---|
329 | | - return perf_evsel__disable(evsel); |
---|
| 328 | + if (evsel->core.attr.type == btsr->intel_bts_pmu->type) |
---|
| 329 | + return evsel__disable(evsel); |
---|
330 | 330 | } |
---|
331 | 331 | return -EINVAL; |
---|
332 | 332 | } |
---|
.. | .. |
---|
335 | 335 | { |
---|
336 | 336 | struct intel_bts_recording *btsr = |
---|
337 | 337 | container_of(itr, struct intel_bts_recording, itr); |
---|
338 | | - struct perf_evsel *evsel; |
---|
| 338 | + struct evsel *evsel; |
---|
339 | 339 | |
---|
340 | 340 | evlist__for_each_entry(btsr->evlist, evsel) { |
---|
341 | | - if (evsel->attr.type == btsr->intel_bts_pmu->type) |
---|
342 | | - return perf_evsel__enable(evsel); |
---|
| 341 | + if (evsel->core.attr.type == btsr->intel_bts_pmu->type) |
---|
| 342 | + return evsel__enable(evsel); |
---|
343 | 343 | } |
---|
344 | 344 | return -EINVAL; |
---|
345 | 345 | } |
---|
.. | .. |
---|
413 | 413 | return err; |
---|
414 | 414 | } |
---|
415 | 415 | |
---|
416 | | -static int intel_bts_read_finish(struct auxtrace_record *itr, int idx) |
---|
417 | | -{ |
---|
418 | | - struct intel_bts_recording *btsr = |
---|
419 | | - container_of(itr, struct intel_bts_recording, itr); |
---|
420 | | - struct perf_evsel *evsel; |
---|
421 | | - |
---|
422 | | - evlist__for_each_entry(btsr->evlist, evsel) { |
---|
423 | | - if (evsel->attr.type == btsr->intel_bts_pmu->type) |
---|
424 | | - return perf_evlist__enable_event_idx(btsr->evlist, |
---|
425 | | - evsel, idx); |
---|
426 | | - } |
---|
427 | | - return -EINVAL; |
---|
428 | | -} |
---|
429 | | - |
---|
430 | 416 | struct auxtrace_record *intel_bts_recording_init(int *err) |
---|
431 | 417 | { |
---|
432 | 418 | struct perf_pmu *intel_bts_pmu = perf_pmu__find(INTEL_BTS_PMU_NAME); |
---|
.. | .. |
---|
447 | 433 | } |
---|
448 | 434 | |
---|
449 | 435 | btsr->intel_bts_pmu = intel_bts_pmu; |
---|
| 436 | + btsr->itr.pmu = intel_bts_pmu; |
---|
450 | 437 | btsr->itr.recording_options = intel_bts_recording_options; |
---|
451 | 438 | btsr->itr.info_priv_size = intel_bts_info_priv_size; |
---|
452 | 439 | btsr->itr.info_fill = intel_bts_info_fill; |
---|
.. | .. |
---|
456 | 443 | btsr->itr.find_snapshot = intel_bts_find_snapshot; |
---|
457 | 444 | btsr->itr.parse_snapshot_options = intel_bts_parse_snapshot_options; |
---|
458 | 445 | btsr->itr.reference = intel_bts_reference; |
---|
459 | | - btsr->itr.read_finish = intel_bts_read_finish; |
---|
| 446 | + btsr->itr.read_finish = auxtrace_record__read_finish; |
---|
460 | 447 | btsr->itr.alignment = sizeof(struct branch); |
---|
461 | 448 | return &btsr->itr; |
---|
462 | 449 | } |
---|