xref: /linux/tools/perf/arch/x86/util/intel-bts.c (revision 03f5a800545eb483308988b578f8f8543aaf9c86)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * intel-bts.c: Intel Processor Trace support
4  * Copyright (c) 2013-2015, Intel Corporation.
5  */
6 
7 #include "../../../util/intel-bts.h"
8 
9 #include <errno.h>
10 
11 #include <linux/bitops.h>
12 #include <linux/kernel.h>
13 #include <linux/log2.h>
14 #include <linux/types.h>
15 #include <linux/zalloc.h>
16 
17 #include <internal/lib.h> // page_size
18 
19 #include "../../../util/auxtrace.h"
20 #include "../../../util/cpumap.h"
21 #include "../../../util/debug.h"
22 #include "../../../util/event.h"
23 #include "../../../util/evlist.h"
24 #include "../../../util/evsel.h"
25 #include "../../../util/mmap.h"
26 #include "../../../util/pmu.h"
27 #include "../../../util/pmus.h"
28 #include "../../../util/record.h"
29 #include "../../../util/session.h"
30 #include "../../../util/tsc.h"
31 
32 #define KiB(x) ((x) * 1024)
33 #define MiB(x) ((x) * 1024 * 1024)
34 #define KiB_MASK(x) (KiB(x) - 1)
35 #define MiB_MASK(x) (MiB(x) - 1)
36 
37 struct intel_bts_snapshot_ref {
38 	void	*ref_buf;
39 	size_t	ref_offset;
40 	bool	wrapped;
41 };
42 
43 struct intel_bts_recording {
44 	struct auxtrace_record		itr;
45 	struct perf_pmu			*intel_bts_pmu;
46 	struct evlist		*evlist;
47 	bool				snapshot_mode;
48 	size_t				snapshot_size;
49 	int				snapshot_ref_cnt;
50 	struct intel_bts_snapshot_ref	*snapshot_refs;
51 };
52 
53 struct branch {
54 	u64 from;
55 	u64 to;
56 	u64 misc;
57 };
58 
59 static size_t
60 intel_bts_info_priv_size(struct auxtrace_record *itr __maybe_unused,
61 			 struct evlist *evlist __maybe_unused)
62 {
63 	return INTEL_BTS_AUXTRACE_PRIV_SIZE;
64 }
65 
66 static int intel_bts_info_fill(struct auxtrace_record *itr,
67 			       struct perf_session *session,
68 			       struct perf_record_auxtrace_info *auxtrace_info,
69 			       size_t priv_size)
70 {
71 	struct intel_bts_recording *btsr =
72 			container_of(itr, struct intel_bts_recording, itr);
73 	struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu;
74 	struct perf_event_mmap_page *pc;
75 	struct perf_tsc_conversion tc = { .time_mult = 0, };
76 	bool cap_user_time_zero = false;
77 	int err;
78 
79 	if (priv_size != INTEL_BTS_AUXTRACE_PRIV_SIZE)
80 		return -EINVAL;
81 
82 	if (!session->evlist->core.nr_mmaps)
83 		return -EINVAL;
84 
85 	pc = session->evlist->mmap[0].core.base;
86 	if (pc) {
87 		err = perf_read_tsc_conversion(pc, &tc);
88 		if (err) {
89 			if (err != -EOPNOTSUPP)
90 				return err;
91 		} else {
92 			cap_user_time_zero = tc.time_mult != 0;
93 		}
94 		if (!cap_user_time_zero)
95 			ui__warning("Intel BTS: TSC not available\n");
96 	}
97 
98 	auxtrace_info->type = PERF_AUXTRACE_INTEL_BTS;
99 	auxtrace_info->priv[INTEL_BTS_PMU_TYPE] = intel_bts_pmu->type;
100 	auxtrace_info->priv[INTEL_BTS_TIME_SHIFT] = tc.time_shift;
101 	auxtrace_info->priv[INTEL_BTS_TIME_MULT] = tc.time_mult;
102 	auxtrace_info->priv[INTEL_BTS_TIME_ZERO] = tc.time_zero;
103 	auxtrace_info->priv[INTEL_BTS_CAP_USER_TIME_ZERO] = cap_user_time_zero;
104 	auxtrace_info->priv[INTEL_BTS_SNAPSHOT_MODE] = btsr->snapshot_mode;
105 
106 	return 0;
107 }
108 
109 static int intel_bts_recording_options(struct auxtrace_record *itr,
110 				       struct evlist *evlist,
111 				       struct record_opts *opts)
112 {
113 	struct intel_bts_recording *btsr =
114 			container_of(itr, struct intel_bts_recording, itr);
115 	struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu;
116 	struct evsel *evsel, *intel_bts_evsel = NULL;
117 	const struct perf_cpu_map *cpus = evlist->core.user_requested_cpus;
118 	bool privileged = perf_event_paranoid_check(-1);
119 
120 	if (opts->auxtrace_sample_mode) {
121 		pr_err("Intel BTS does not support AUX area sampling\n");
122 		return -EINVAL;
123 	}
124 
125 	btsr->evlist = evlist;
126 	btsr->snapshot_mode = opts->auxtrace_snapshot_mode;
127 
128 	evlist__for_each_entry(evlist, evsel) {
129 		if (evsel->core.attr.type == intel_bts_pmu->type) {
130 			if (intel_bts_evsel) {
131 				pr_err("There may be only one " INTEL_BTS_PMU_NAME " event\n");
132 				return -EINVAL;
133 			}
134 			evsel->core.attr.freq = 0;
135 			evsel->core.attr.sample_period = 1;
136 			evsel->needs_auxtrace_mmap = true;
137 			intel_bts_evsel = evsel;
138 			opts->full_auxtrace = true;
139 		}
140 	}
141 
142 	if (opts->auxtrace_snapshot_mode && !opts->full_auxtrace) {
143 		pr_err("Snapshot mode (-S option) requires " INTEL_BTS_PMU_NAME " PMU event (-e " INTEL_BTS_PMU_NAME ")\n");
144 		return -EINVAL;
145 	}
146 
147 	if (!opts->full_auxtrace)
148 		return 0;
149 
150 	if (opts->full_auxtrace && !perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
151 		pr_err(INTEL_BTS_PMU_NAME " does not support per-cpu recording\n");
152 		return -EINVAL;
153 	}
154 
155 	/* Set default sizes for snapshot mode */
156 	if (opts->auxtrace_snapshot_mode) {
157 		if (!opts->auxtrace_snapshot_size && !opts->auxtrace_mmap_pages) {
158 			if (privileged) {
159 				opts->auxtrace_mmap_pages = MiB(4) / page_size;
160 			} else {
161 				opts->auxtrace_mmap_pages = KiB(128) / page_size;
162 				if (opts->mmap_pages == UINT_MAX)
163 					opts->mmap_pages = KiB(256) / page_size;
164 			}
165 		} else if (!opts->auxtrace_mmap_pages && !privileged &&
166 			   opts->mmap_pages == UINT_MAX) {
167 			opts->mmap_pages = KiB(256) / page_size;
168 		}
169 		if (!opts->auxtrace_snapshot_size)
170 			opts->auxtrace_snapshot_size =
171 				opts->auxtrace_mmap_pages * (size_t)page_size;
172 		if (!opts->auxtrace_mmap_pages) {
173 			size_t sz = opts->auxtrace_snapshot_size;
174 
175 			sz = round_up(sz, page_size) / page_size;
176 			opts->auxtrace_mmap_pages = roundup_pow_of_two(sz);
177 		}
178 		if (opts->auxtrace_snapshot_size >
179 				opts->auxtrace_mmap_pages * (size_t)page_size) {
180 			pr_err("Snapshot size %zu must not be greater than AUX area tracing mmap size %zu\n",
181 			       opts->auxtrace_snapshot_size,
182 			       opts->auxtrace_mmap_pages * (size_t)page_size);
183 			return -EINVAL;
184 		}
185 		if (!opts->auxtrace_snapshot_size || !opts->auxtrace_mmap_pages) {
186 			pr_err("Failed to calculate default snapshot size and/or AUX area tracing mmap pages\n");
187 			return -EINVAL;
188 		}
189 		pr_debug2("Intel BTS snapshot size: %zu\n",
190 			  opts->auxtrace_snapshot_size);
191 	}
192 
193 	/* Set default sizes for full trace mode */
194 	if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
195 		if (privileged) {
196 			opts->auxtrace_mmap_pages = MiB(4) / page_size;
197 		} else {
198 			opts->auxtrace_mmap_pages = KiB(128) / page_size;
199 			if (opts->mmap_pages == UINT_MAX)
200 				opts->mmap_pages = KiB(256) / page_size;
201 		}
202 	}
203 
204 	/* Validate auxtrace_mmap_pages */
205 	if (opts->auxtrace_mmap_pages) {
206 		size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
207 		size_t min_sz;
208 
209 		if (opts->auxtrace_snapshot_mode)
210 			min_sz = KiB(4);
211 		else
212 			min_sz = KiB(8);
213 
214 		if (sz < min_sz || !is_power_of_2(sz)) {
215 			pr_err("Invalid mmap size for Intel BTS: must be at least %zuKiB and a power of 2\n",
216 			       min_sz / 1024);
217 			return -EINVAL;
218 		}
219 	}
220 
221 	if (intel_bts_evsel) {
222 		/*
223 		 * To obtain the auxtrace buffer file descriptor, the auxtrace event
224 		 * must come first.
225 		 */
226 		evlist__to_front(evlist, intel_bts_evsel);
227 		/*
228 		 * In the case of per-cpu mmaps, we need the CPU on the
229 		 * AUX event.
230 		 */
231 		if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
232 			evsel__set_sample_bit(intel_bts_evsel, CPU);
233 	}
234 
235 	/* Add dummy event to keep tracking */
236 	if (opts->full_auxtrace) {
237 		struct evsel *tracking_evsel;
238 		int err;
239 
240 		err = parse_event(evlist, "dummy:u");
241 		if (err)
242 			return err;
243 
244 		tracking_evsel = evlist__last(evlist);
245 
246 		evlist__set_tracking_event(evlist, tracking_evsel);
247 
248 		tracking_evsel->core.attr.freq = 0;
249 		tracking_evsel->core.attr.sample_period = 1;
250 	}
251 
252 	return 0;
253 }
254 
255 static int intel_bts_parse_snapshot_options(struct auxtrace_record *itr,
256 					    struct record_opts *opts,
257 					    const char *str)
258 {
259 	struct intel_bts_recording *btsr =
260 			container_of(itr, struct intel_bts_recording, itr);
261 	unsigned long long snapshot_size = 0;
262 	char *endptr;
263 
264 	if (str) {
265 		snapshot_size = strtoull(str, &endptr, 0);
266 		if (*endptr || snapshot_size > SIZE_MAX)
267 			return -1;
268 	}
269 
270 	opts->auxtrace_snapshot_mode = true;
271 	opts->auxtrace_snapshot_size = snapshot_size;
272 
273 	btsr->snapshot_size = snapshot_size;
274 
275 	return 0;
276 }
277 
278 static u64 intel_bts_reference(struct auxtrace_record *itr __maybe_unused)
279 {
280 	return rdtsc();
281 }
282 
283 static int intel_bts_alloc_snapshot_refs(struct intel_bts_recording *btsr,
284 					 int idx)
285 {
286 	const size_t sz = sizeof(struct intel_bts_snapshot_ref);
287 	int cnt = btsr->snapshot_ref_cnt, new_cnt = cnt * 2;
288 	struct intel_bts_snapshot_ref *refs;
289 
290 	if (!new_cnt)
291 		new_cnt = 16;
292 
293 	while (new_cnt <= idx)
294 		new_cnt *= 2;
295 
296 	refs = calloc(new_cnt, sz);
297 	if (!refs)
298 		return -ENOMEM;
299 
300 	memcpy(refs, btsr->snapshot_refs, cnt * sz);
301 
302 	btsr->snapshot_refs = refs;
303 	btsr->snapshot_ref_cnt = new_cnt;
304 
305 	return 0;
306 }
307 
308 static void intel_bts_free_snapshot_refs(struct intel_bts_recording *btsr)
309 {
310 	int i;
311 
312 	for (i = 0; i < btsr->snapshot_ref_cnt; i++)
313 		zfree(&btsr->snapshot_refs[i].ref_buf);
314 	zfree(&btsr->snapshot_refs);
315 }
316 
317 static void intel_bts_recording_free(struct auxtrace_record *itr)
318 {
319 	struct intel_bts_recording *btsr =
320 			container_of(itr, struct intel_bts_recording, itr);
321 
322 	intel_bts_free_snapshot_refs(btsr);
323 	free(btsr);
324 }
325 
326 static int intel_bts_snapshot_start(struct auxtrace_record *itr)
327 {
328 	struct intel_bts_recording *btsr =
329 			container_of(itr, struct intel_bts_recording, itr);
330 	struct evsel *evsel;
331 
332 	evlist__for_each_entry(btsr->evlist, evsel) {
333 		if (evsel->core.attr.type == btsr->intel_bts_pmu->type)
334 			return evsel__disable(evsel);
335 	}
336 	return -EINVAL;
337 }
338 
339 static int intel_bts_snapshot_finish(struct auxtrace_record *itr)
340 {
341 	struct intel_bts_recording *btsr =
342 			container_of(itr, struct intel_bts_recording, itr);
343 	struct evsel *evsel;
344 
345 	evlist__for_each_entry(btsr->evlist, evsel) {
346 		if (evsel->core.attr.type == btsr->intel_bts_pmu->type)
347 			return evsel__enable(evsel);
348 	}
349 	return -EINVAL;
350 }
351 
352 static bool intel_bts_first_wrap(u64 *data, size_t buf_size)
353 {
354 	int i, a, b;
355 
356 	b = buf_size >> 3;
357 	a = b - 512;
358 	if (a < 0)
359 		a = 0;
360 
361 	for (i = a; i < b; i++) {
362 		if (data[i])
363 			return true;
364 	}
365 
366 	return false;
367 }
368 
369 static int intel_bts_find_snapshot(struct auxtrace_record *itr, int idx,
370 				   struct auxtrace_mmap *mm, unsigned char *data,
371 				   u64 *head, u64 *old)
372 {
373 	struct intel_bts_recording *btsr =
374 			container_of(itr, struct intel_bts_recording, itr);
375 	bool wrapped;
376 	int err;
377 
378 	pr_debug3("%s: mmap index %d old head %zu new head %zu\n",
379 		  __func__, idx, (size_t)*old, (size_t)*head);
380 
381 	if (idx >= btsr->snapshot_ref_cnt) {
382 		err = intel_bts_alloc_snapshot_refs(btsr, idx);
383 		if (err)
384 			goto out_err;
385 	}
386 
387 	wrapped = btsr->snapshot_refs[idx].wrapped;
388 	if (!wrapped && intel_bts_first_wrap((u64 *)data, mm->len)) {
389 		btsr->snapshot_refs[idx].wrapped = true;
390 		wrapped = true;
391 	}
392 
393 	/*
394 	 * In full trace mode 'head' continually increases.  However in snapshot
395 	 * mode 'head' is an offset within the buffer.  Here 'old' and 'head'
396 	 * are adjusted to match the full trace case which expects that 'old' is
397 	 * always less than 'head'.
398 	 */
399 	if (wrapped) {
400 		*old = *head;
401 		*head += mm->len;
402 	} else {
403 		if (mm->mask)
404 			*old &= mm->mask;
405 		else
406 			*old %= mm->len;
407 		if (*old > *head)
408 			*head += mm->len;
409 	}
410 
411 	pr_debug3("%s: wrap-around %sdetected, adjusted old head %zu adjusted new head %zu\n",
412 		  __func__, wrapped ? "" : "not ", (size_t)*old, (size_t)*head);
413 
414 	return 0;
415 
416 out_err:
417 	pr_err("%s: failed, error %d\n", __func__, err);
418 	return err;
419 }
420 
421 struct auxtrace_record *intel_bts_recording_init(int *err)
422 {
423 	struct perf_pmu *intel_bts_pmu = perf_pmus__find(INTEL_BTS_PMU_NAME);
424 	struct intel_bts_recording *btsr;
425 
426 	if (!intel_bts_pmu)
427 		return NULL;
428 
429 	if (setenv("JITDUMP_USE_ARCH_TIMESTAMP", "1", 1)) {
430 		*err = -errno;
431 		return NULL;
432 	}
433 
434 	btsr = zalloc(sizeof(struct intel_bts_recording));
435 	if (!btsr) {
436 		*err = -ENOMEM;
437 		return NULL;
438 	}
439 
440 	btsr->intel_bts_pmu = intel_bts_pmu;
441 	btsr->itr.recording_options = intel_bts_recording_options;
442 	btsr->itr.info_priv_size = intel_bts_info_priv_size;
443 	btsr->itr.info_fill = intel_bts_info_fill;
444 	btsr->itr.free = intel_bts_recording_free;
445 	btsr->itr.snapshot_start = intel_bts_snapshot_start;
446 	btsr->itr.snapshot_finish = intel_bts_snapshot_finish;
447 	btsr->itr.find_snapshot = intel_bts_find_snapshot;
448 	btsr->itr.parse_snapshot_options = intel_bts_parse_snapshot_options;
449 	btsr->itr.reference = intel_bts_reference;
450 	btsr->itr.read_finish = auxtrace_record__read_finish;
451 	btsr->itr.alignment = sizeof(struct branch);
452 	return &btsr->itr;
453 }
454