blob: 4cc3b54b2f73f20b4f689ebff91998685aa8d446 [file] [log] [blame]
Thomas Gleixner91007042019-05-29 07:12:25 -07001// SPDX-License-Identifier: GPL-2.0-only
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -03002/*
3 * Copyright (C) 2011-2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
4 *
5 * Parts came from evlist.c builtin-{top,stat,record}.c, see those files for further
6 * copyright notes.
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -03007 */
8
9#include <sys/mman.h>
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -030010#include <inttypes.h>
11#include <asm/bug.h>
Arnaldo Carvalho de Melo7f7c5362019-07-04 11:32:27 -030012#include <linux/zalloc.h>
Arnaldo Carvalho de Melof2a39fe2019-08-30 14:45:20 -030013#include <stdlib.h>
14#include <string.h>
Alexey Budankovc44a8b42019-01-22 20:48:54 +030015#ifdef HAVE_LIBNUMA_SUPPORT
16#include <numaif.h>
17#endif
Arnaldo Carvalho de Melof2a39fe2019-08-30 14:45:20 -030018#include "cpumap.h"
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -030019#include "debug.h"
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030020#include "event.h"
21#include "mmap.h"
Arnaldo Carvalho de Meloc1a604d2019-08-29 15:20:59 -030022#include "../perf.h"
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030023#include "util.h" /* page_size */
24
Jiri Olsaa5830532019-07-27 20:30:53 +020025size_t perf_mmap__mmap_len(struct mmap *map)
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030026{
Jiri Olsa4fd0cef2019-07-27 22:27:55 +020027 return map->core.mask + 1 + page_size;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030028}
29
30/* When check_messup is true, 'end' must points to a good entry */
Jiri Olsaa5830532019-07-27 20:30:53 +020031static union perf_event *perf_mmap__read(struct mmap *map,
Kan Liangb4b036b2018-01-18 13:26:21 -080032 u64 *startp, u64 end)
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030033{
Jiri Olsa547740f2019-07-27 22:07:44 +020034 unsigned char *data = map->core.base + page_size;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030035 union perf_event *event = NULL;
Kan Liangb4b036b2018-01-18 13:26:21 -080036 int diff = end - *startp;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030037
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030038 if (diff >= (int)sizeof(event->header)) {
39 size_t size;
40
Jiri Olsa4fd0cef2019-07-27 22:27:55 +020041 event = (union perf_event *)&data[*startp & map->core.mask];
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030042 size = event->header.size;
43
Kan Liangb4b036b2018-01-18 13:26:21 -080044 if (size < sizeof(event->header) || diff < (int)size)
45 return NULL;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030046
47 /*
48 * Event straddles the mmap boundary -- header should always
49 * be inside due to u64 alignment of output.
50 */
Jiri Olsa4fd0cef2019-07-27 22:27:55 +020051 if ((*startp & map->core.mask) + size != ((*startp + size) & map->core.mask)) {
Kan Liangb4b036b2018-01-18 13:26:21 -080052 unsigned int offset = *startp;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030053 unsigned int len = min(sizeof(*event), size), cpy;
Jiri Olsa4443e6d2019-07-27 22:47:58 +020054 void *dst = map->core.event_copy;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030055
56 do {
Jiri Olsa4fd0cef2019-07-27 22:27:55 +020057 cpy = min(map->core.mask + 1 - (offset & map->core.mask), len);
58 memcpy(dst, &data[offset & map->core.mask], cpy);
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030059 offset += cpy;
60 dst += cpy;
61 len -= cpy;
62 } while (len);
63
Jiri Olsa4443e6d2019-07-27 22:47:58 +020064 event = (union perf_event *)map->core.event_copy;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030065 }
66
Kan Liangb4b036b2018-01-18 13:26:21 -080067 *startp += size;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030068 }
69
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -030070 return event;
71}
72
Kan Liang3effc2f2018-01-18 13:26:25 -080073/*
Kan Liang7bb45972018-01-18 13:26:23 -080074 * Read event from ring buffer one by one.
75 * Return one event for each call.
76 *
77 * Usage:
78 * perf_mmap__read_init()
79 * while(event = perf_mmap__read_event()) {
80 * //process the event
81 * perf_mmap__consume()
82 * }
83 * perf_mmap__read_done()
84 */
Jiri Olsaa5830532019-07-27 20:30:53 +020085union perf_event *perf_mmap__read_event(struct mmap *map)
Kan Liang7bb45972018-01-18 13:26:23 -080086{
87 union perf_event *event;
88
89 /*
90 * Check if event was unmapped due to a POLLHUP/POLLERR.
91 */
Jiri Olsae03edfe2019-07-27 22:35:35 +020092 if (!refcount_read(&map->core.refcnt))
Kan Liang7bb45972018-01-18 13:26:23 -080093 return NULL;
94
Kan Liang7bb45972018-01-18 13:26:23 -080095 /* non-overwirte doesn't pause the ringbuffer */
Jiri Olsa8df7a862019-07-27 22:42:56 +020096 if (!map->core.overwrite)
Jiri Olsaebe4d722019-07-27 22:39:53 +020097 map->core.end = perf_mmap__read_head(map);
Kan Liang7bb45972018-01-18 13:26:23 -080098
Jiri Olsaebe4d722019-07-27 22:39:53 +020099 event = perf_mmap__read(map, &map->core.start, map->core.end);
Kan Liang7bb45972018-01-18 13:26:23 -0800100
Jiri Olsa8df7a862019-07-27 22:42:56 +0200101 if (!map->core.overwrite)
Jiri Olsaebe4d722019-07-27 22:39:53 +0200102 map->core.prev = map->core.start;
Kan Liang7bb45972018-01-18 13:26:23 -0800103
104 return event;
105}
106
Jiri Olsaa5830532019-07-27 20:30:53 +0200107static bool perf_mmap__empty(struct mmap *map)
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300108{
Jiri Olsaebe4d722019-07-27 22:39:53 +0200109 return perf_mmap__read_head(map) == map->core.prev && !map->auxtrace_mmap.base;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300110}
111
Jiri Olsaa5830532019-07-27 20:30:53 +0200112void perf_mmap__get(struct mmap *map)
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300113{
Jiri Olsae03edfe2019-07-27 22:35:35 +0200114 refcount_inc(&map->core.refcnt);
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300115}
116
Jiri Olsaa5830532019-07-27 20:30:53 +0200117void perf_mmap__put(struct mmap *map)
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300118{
Jiri Olsae03edfe2019-07-27 22:35:35 +0200119 BUG_ON(map->core.base && refcount_read(&map->core.refcnt) == 0);
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300120
Jiri Olsae03edfe2019-07-27 22:35:35 +0200121 if (refcount_dec_and_test(&map->core.refcnt))
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300122 perf_mmap__munmap(map);
123}
124
Jiri Olsaa5830532019-07-27 20:30:53 +0200125void perf_mmap__consume(struct mmap *map)
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300126{
Jiri Olsa8df7a862019-07-27 22:42:56 +0200127 if (!map->core.overwrite) {
Jiri Olsaebe4d722019-07-27 22:39:53 +0200128 u64 old = map->core.prev;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300129
130 perf_mmap__write_tail(map, old);
131 }
132
Jiri Olsae03edfe2019-07-27 22:35:35 +0200133 if (refcount_read(&map->core.refcnt) == 1 && perf_mmap__empty(map))
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300134 perf_mmap__put(map);
135}
136
137int __weak auxtrace_mmap__mmap(struct auxtrace_mmap *mm __maybe_unused,
138 struct auxtrace_mmap_params *mp __maybe_unused,
139 void *userpg __maybe_unused,
140 int fd __maybe_unused)
141{
142 return 0;
143}
144
145void __weak auxtrace_mmap__munmap(struct auxtrace_mmap *mm __maybe_unused)
146{
147}
148
149void __weak auxtrace_mmap_params__init(struct auxtrace_mmap_params *mp __maybe_unused,
150 off_t auxtrace_offset __maybe_unused,
151 unsigned int auxtrace_pages __maybe_unused,
152 bool auxtrace_overwrite __maybe_unused)
153{
154}
155
156void __weak auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp __maybe_unused,
Jiri Olsa63503db2019-07-21 13:23:52 +0200157 struct evlist *evlist __maybe_unused,
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300158 int idx __maybe_unused,
159 bool per_cpu __maybe_unused)
160{
161}
162
Alexey Budankov0b773832018-11-06 12:03:35 +0300163#ifdef HAVE_AIO_SUPPORT
Jiri Olsaa5830532019-07-27 20:30:53 +0200164static int perf_mmap__aio_enabled(struct mmap *map)
Alexey Budankov51255a82019-03-18 20:42:19 +0300165{
166 return map->aio.nr_cblocks > 0;
167}
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300168
169#ifdef HAVE_LIBNUMA_SUPPORT
Jiri Olsaa5830532019-07-27 20:30:53 +0200170static int perf_mmap__aio_alloc(struct mmap *map, int idx)
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300171{
172 map->aio.data[idx] = mmap(NULL, perf_mmap__mmap_len(map), PROT_READ|PROT_WRITE,
173 MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
174 if (map->aio.data[idx] == MAP_FAILED) {
175 map->aio.data[idx] = NULL;
176 return -1;
177 }
178
179 return 0;
180}
181
Jiri Olsaa5830532019-07-27 20:30:53 +0200182static void perf_mmap__aio_free(struct mmap *map, int idx)
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300183{
184 if (map->aio.data[idx]) {
185 munmap(map->aio.data[idx], perf_mmap__mmap_len(map));
186 map->aio.data[idx] = NULL;
187 }
188}
189
Jiri Olsaa5830532019-07-27 20:30:53 +0200190static int perf_mmap__aio_bind(struct mmap *map, int idx, int cpu, int affinity)
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300191{
192 void *data;
193 size_t mmap_len;
194 unsigned long node_mask;
195
196 if (affinity != PERF_AFFINITY_SYS && cpu__max_node() > 1) {
197 data = map->aio.data[idx];
198 mmap_len = perf_mmap__mmap_len(map);
199 node_mask = 1UL << cpu__get_node(cpu);
200 if (mbind(data, mmap_len, MPOL_BIND, &node_mask, 1, 0)) {
201 pr_err("Failed to bind [%p-%p] AIO buffer to node %d: error %m\n",
202 data, data + mmap_len, cpu__get_node(cpu));
203 return -1;
204 }
205 }
206
207 return 0;
208}
Alexey Budankov51255a82019-03-18 20:42:19 +0300209#else /* !HAVE_LIBNUMA_SUPPORT */
Jiri Olsaa5830532019-07-27 20:30:53 +0200210static int perf_mmap__aio_alloc(struct mmap *map, int idx)
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300211{
212 map->aio.data[idx] = malloc(perf_mmap__mmap_len(map));
213 if (map->aio.data[idx] == NULL)
214 return -1;
215
216 return 0;
217}
218
Jiri Olsaa5830532019-07-27 20:30:53 +0200219static void perf_mmap__aio_free(struct mmap *map, int idx)
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300220{
221 zfree(&(map->aio.data[idx]));
222}
223
Jiri Olsaa5830532019-07-27 20:30:53 +0200224static int perf_mmap__aio_bind(struct mmap *map __maybe_unused, int idx __maybe_unused,
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300225 int cpu __maybe_unused, int affinity __maybe_unused)
226{
227 return 0;
228}
229#endif
230
Jiri Olsaa5830532019-07-27 20:30:53 +0200231static int perf_mmap__aio_mmap(struct mmap *map, struct mmap_params *mp)
Alexey Budankov0b773832018-11-06 12:03:35 +0300232{
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300233 int delta_max, i, prio, ret;
Alexey Budankov0b773832018-11-06 12:03:35 +0300234
Alexey Budankovd3d1af62018-11-06 12:04:58 +0300235 map->aio.nr_cblocks = mp->nr_cblocks;
236 if (map->aio.nr_cblocks) {
Alexey Budankov93f20c02018-11-06 12:07:19 +0300237 map->aio.aiocb = calloc(map->aio.nr_cblocks, sizeof(struct aiocb *));
238 if (!map->aio.aiocb) {
239 pr_debug2("failed to allocate aiocb for data buffer, error %m\n");
240 return -1;
241 }
242 map->aio.cblocks = calloc(map->aio.nr_cblocks, sizeof(struct aiocb));
243 if (!map->aio.cblocks) {
244 pr_debug2("failed to allocate cblocks for data buffer, error %m\n");
245 return -1;
246 }
247 map->aio.data = calloc(map->aio.nr_cblocks, sizeof(void *));
Alexey Budankov0b773832018-11-06 12:03:35 +0300248 if (!map->aio.data) {
249 pr_debug2("failed to allocate data buffer, error %m\n");
250 return -1;
251 }
Alexey Budankov0b773832018-11-06 12:03:35 +0300252 delta_max = sysconf(_SC_AIO_PRIO_DELTA_MAX);
Alexey Budankov93f20c02018-11-06 12:07:19 +0300253 for (i = 0; i < map->aio.nr_cblocks; ++i) {
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300254 ret = perf_mmap__aio_alloc(map, i);
255 if (ret == -1) {
Alexey Budankov93f20c02018-11-06 12:07:19 +0300256 pr_debug2("failed to allocate data buffer area, error %m");
257 return -1;
258 }
Jiri Olsa56a94702019-07-27 22:33:20 +0200259 ret = perf_mmap__aio_bind(map, i, map->core.cpu, mp->affinity);
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300260 if (ret == -1)
261 return -1;
Alexey Budankov93f20c02018-11-06 12:07:19 +0300262 /*
263 * Use cblock.aio_fildes value different from -1
264 * to denote started aio write operation on the
265 * cblock so it requires explicit record__aio_sync()
266 * call prior the cblock may be reused again.
267 */
268 map->aio.cblocks[i].aio_fildes = -1;
269 /*
270 * Allocate cblocks with priority delta to have
271 * faster aio write system calls because queued requests
272 * are kept in separate per-prio queues and adding
273 * a new request will iterate thru shorter per-prio
274 * list. Blocks with numbers higher than
275 * _SC_AIO_PRIO_DELTA_MAX go with priority 0.
276 */
277 prio = delta_max - i;
278 map->aio.cblocks[i].aio_reqprio = prio >= 0 ? prio : 0;
279 }
Alexey Budankov0b773832018-11-06 12:03:35 +0300280 }
281
282 return 0;
283}
284
Jiri Olsaa5830532019-07-27 20:30:53 +0200285static void perf_mmap__aio_munmap(struct mmap *map)
Alexey Budankov0b773832018-11-06 12:03:35 +0300286{
Alexey Budankovc8dd6ee2018-12-05 20:19:41 +0300287 int i;
288
289 for (i = 0; i < map->aio.nr_cblocks; ++i)
Alexey Budankovc44a8b42019-01-22 20:48:54 +0300290 perf_mmap__aio_free(map, i);
Alexey Budankov0b773832018-11-06 12:03:35 +0300291 if (map->aio.data)
292 zfree(&map->aio.data);
Alexey Budankovc8dd6ee2018-12-05 20:19:41 +0300293 zfree(&map->aio.cblocks);
294 zfree(&map->aio.aiocb);
Alexey Budankov0b773832018-11-06 12:03:35 +0300295}
Alexey Budankov51255a82019-03-18 20:42:19 +0300296#else /* !HAVE_AIO_SUPPORT */
Jiri Olsaa5830532019-07-27 20:30:53 +0200297static int perf_mmap__aio_enabled(struct mmap *map __maybe_unused)
Alexey Budankov51255a82019-03-18 20:42:19 +0300298{
299 return 0;
300}
301
Jiri Olsaa5830532019-07-27 20:30:53 +0200302static int perf_mmap__aio_mmap(struct mmap *map __maybe_unused,
Alexey Budankov0b773832018-11-06 12:03:35 +0300303 struct mmap_params *mp __maybe_unused)
304{
305 return 0;
306}
307
Jiri Olsaa5830532019-07-27 20:30:53 +0200308static void perf_mmap__aio_munmap(struct mmap *map __maybe_unused)
Alexey Budankov0b773832018-11-06 12:03:35 +0300309{
310}
311#endif
312
Jiri Olsaa5830532019-07-27 20:30:53 +0200313void perf_mmap__munmap(struct mmap *map)
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300314{
Alexey Budankov0b773832018-11-06 12:03:35 +0300315 perf_mmap__aio_munmap(map);
Alexey Budankov51255a82019-03-18 20:42:19 +0300316 if (map->data != NULL) {
317 munmap(map->data, perf_mmap__mmap_len(map));
318 map->data = NULL;
319 }
Jiri Olsa547740f2019-07-27 22:07:44 +0200320 if (map->core.base != NULL) {
321 munmap(map->core.base, perf_mmap__mmap_len(map));
322 map->core.base = NULL;
Jiri Olsa2cf07b22019-07-27 22:31:17 +0200323 map->core.fd = -1;
Jiri Olsae03edfe2019-07-27 22:35:35 +0200324 refcount_set(&map->core.refcnt, 0);
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300325 }
326 auxtrace_mmap__munmap(&map->auxtrace_mmap);
327}
328
Alexey Budankovf13de662019-01-22 20:50:57 +0300329static void build_node_mask(int node, cpu_set_t *mask)
330{
331 int c, cpu, nr_cpus;
Jiri Olsaf8548392019-07-21 13:23:49 +0200332 const struct perf_cpu_map *cpu_map = NULL;
Alexey Budankovf13de662019-01-22 20:50:57 +0300333
334 cpu_map = cpu_map__online();
335 if (!cpu_map)
336 return;
337
Jiri Olsa6549cd82019-08-22 13:11:38 +0200338 nr_cpus = perf_cpu_map__nr(cpu_map);
Alexey Budankovf13de662019-01-22 20:50:57 +0300339 for (c = 0; c < nr_cpus; c++) {
340 cpu = cpu_map->map[c]; /* map c index to online cpu index */
341 if (cpu__get_node(cpu) == node)
342 CPU_SET(cpu, mask);
343 }
344}
345
Jiri Olsaa5830532019-07-27 20:30:53 +0200346static void perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params *mp)
Alexey Budankovf13de662019-01-22 20:50:57 +0300347{
348 CPU_ZERO(&map->affinity_mask);
349 if (mp->affinity == PERF_AFFINITY_NODE && cpu__max_node() > 1)
Jiri Olsa56a94702019-07-27 22:33:20 +0200350 build_node_mask(cpu__get_node(map->core.cpu), &map->affinity_mask);
Alexey Budankovf13de662019-01-22 20:50:57 +0300351 else if (mp->affinity == PERF_AFFINITY_CPU)
Jiri Olsa56a94702019-07-27 22:33:20 +0200352 CPU_SET(map->core.cpu, &map->affinity_mask);
Alexey Budankovf13de662019-01-22 20:50:57 +0300353}
354
Jiri Olsaa5830532019-07-27 20:30:53 +0200355int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu)
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300356{
357 /*
Kan Liang6afad542018-03-01 18:09:11 -0500358 * The last one will be done at perf_mmap__consume(), so that we
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300359 * make sure we don't prevent tools from consuming every last event in
360 * the ring buffer.
361 *
362 * I.e. we can get the POLLHUP meaning that the fd doesn't exist
363 * anymore, but the last events for it are still in the ring buffer,
364 * waiting to be consumed.
365 *
366 * Tools can chose to ignore this at their own discretion, but the
367 * evlist layer can't just drop it when filtering events in
368 * perf_evlist__filter_pollfd().
369 */
Jiri Olsae03edfe2019-07-27 22:35:35 +0200370 refcount_set(&map->core.refcnt, 2);
Jiri Olsaebe4d722019-07-27 22:39:53 +0200371 map->core.prev = 0;
Jiri Olsa4fd0cef2019-07-27 22:27:55 +0200372 map->core.mask = mp->mask;
Jiri Olsa547740f2019-07-27 22:07:44 +0200373 map->core.base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot,
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300374 MAP_SHARED, fd, 0);
Jiri Olsa547740f2019-07-27 22:07:44 +0200375 if (map->core.base == MAP_FAILED) {
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300376 pr_debug2("failed to mmap perf event ring buffer, error %d\n",
377 errno);
Jiri Olsa547740f2019-07-27 22:07:44 +0200378 map->core.base = NULL;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300379 return -1;
380 }
Jiri Olsa2cf07b22019-07-27 22:31:17 +0200381 map->core.fd = fd;
Jiri Olsa56a94702019-07-27 22:33:20 +0200382 map->core.cpu = cpu;
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300383
Alexey Budankovf13de662019-01-22 20:50:57 +0300384 perf_mmap__setup_affinity_mask(map, mp);
Alexey Budankov9d2ed642019-01-22 20:47:43 +0300385
Jiri Olsa65aa2e62019-08-27 16:05:18 +0200386 map->core.flush = mp->flush;
Alexey Budankov470530b2019-03-18 20:40:26 +0300387
Alexey Budankov51255a82019-03-18 20:42:19 +0300388 map->comp_level = mp->comp_level;
389
390 if (map->comp_level && !perf_mmap__aio_enabled(map)) {
391 map->data = mmap(NULL, perf_mmap__mmap_len(map), PROT_READ|PROT_WRITE,
392 MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
393 if (map->data == MAP_FAILED) {
394 pr_debug2("failed to mmap data buffer, error %d\n",
395 errno);
396 map->data = NULL;
397 return -1;
398 }
399 }
400
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300401 if (auxtrace_mmap__mmap(&map->auxtrace_mmap,
Jiri Olsa547740f2019-07-27 22:07:44 +0200402 &mp->auxtrace_mp, map->core.base, fd))
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300403 return -1;
404
Alexey Budankov0b773832018-11-06 12:03:35 +0300405 return perf_mmap__aio_mmap(map, mp);
Arnaldo Carvalho de Melo16958492017-10-06 10:31:47 -0300406}
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300407
Yisheng Xie699db112018-03-13 20:31:13 +0800408static int overwrite_rb_find_range(void *buf, int mask, u64 *start, u64 *end)
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300409{
410 struct perf_event_header *pheader;
Yisheng Xie699db112018-03-13 20:31:13 +0800411 u64 evt_head = *start;
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300412 int size = mask + 1;
413
Yisheng Xie699db112018-03-13 20:31:13 +0800414 pr_debug2("%s: buf=%p, start=%"PRIx64"\n", __func__, buf, *start);
415 pheader = (struct perf_event_header *)(buf + (*start & mask));
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300416 while (true) {
Yisheng Xie699db112018-03-13 20:31:13 +0800417 if (evt_head - *start >= (unsigned int)size) {
Wang Nan0b72d692017-12-04 16:51:07 +0000418 pr_debug("Finished reading overwrite ring buffer: rewind\n");
Yisheng Xie699db112018-03-13 20:31:13 +0800419 if (evt_head - *start > (unsigned int)size)
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300420 evt_head -= pheader->size;
421 *end = evt_head;
422 return 0;
423 }
424
425 pheader = (struct perf_event_header *)(buf + (evt_head & mask));
426
427 if (pheader->size == 0) {
Wang Nan0b72d692017-12-04 16:51:07 +0000428 pr_debug("Finished reading overwrite ring buffer: get start\n");
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300429 *end = evt_head;
430 return 0;
431 }
432
433 evt_head += pheader->size;
434 pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
435 }
436 WARN_ONCE(1, "Shouldn't get here\n");
437 return -1;
438}
439
Kan Liang88724812018-01-18 13:26:19 -0800440/*
441 * Report the start and end of the available data in ringbuffer
442 */
Jiri Olsaa5830532019-07-27 20:30:53 +0200443static int __perf_mmap__read_init(struct mmap *md)
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300444{
445 u64 head = perf_mmap__read_head(md);
Jiri Olsaebe4d722019-07-27 22:39:53 +0200446 u64 old = md->core.prev;
Jiri Olsa547740f2019-07-27 22:07:44 +0200447 unsigned char *data = md->core.base + page_size;
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300448 unsigned long size;
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300449
Jiri Olsa8df7a862019-07-27 22:42:56 +0200450 md->core.start = md->core.overwrite ? head : old;
451 md->core.end = md->core.overwrite ? old : head;
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300452
Jiri Olsa65aa2e62019-08-27 16:05:18 +0200453 if ((md->core.end - md->core.start) < md->core.flush)
Kan Liang189f2cc2018-01-18 13:26:20 -0800454 return -EAGAIN;
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300455
Jiri Olsaebe4d722019-07-27 22:39:53 +0200456 size = md->core.end - md->core.start;
Jiri Olsa4fd0cef2019-07-27 22:27:55 +0200457 if (size > (unsigned long)(md->core.mask) + 1) {
Jiri Olsa8df7a862019-07-27 22:42:56 +0200458 if (!md->core.overwrite) {
Wang Nan7fb4b402017-12-04 16:51:06 +0000459 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300460
Jiri Olsaebe4d722019-07-27 22:39:53 +0200461 md->core.prev = head;
Kan Liangd6ace3d2018-03-06 10:36:05 -0500462 perf_mmap__consume(md);
Kan Liang189f2cc2018-01-18 13:26:20 -0800463 return -EAGAIN;
Wang Nan7fb4b402017-12-04 16:51:06 +0000464 }
465
466 /*
467 * Backward ring buffer is full. We still have a chance to read
468 * most of data from it.
469 */
Jiri Olsaebe4d722019-07-27 22:39:53 +0200470 if (overwrite_rb_find_range(data, md->core.mask, &md->core.start, &md->core.end))
Kan Liang189f2cc2018-01-18 13:26:20 -0800471 return -EINVAL;
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300472 }
473
Kan Liang189f2cc2018-01-18 13:26:20 -0800474 return 0;
Kan Liang88724812018-01-18 13:26:19 -0800475}
476
Jiri Olsaa5830532019-07-27 20:30:53 +0200477int perf_mmap__read_init(struct mmap *map)
Arnaldo Carvalho de Melo895e3b02018-03-26 11:42:15 -0300478{
479 /*
480 * Check if event was unmapped due to a POLLHUP/POLLERR.
481 */
Jiri Olsae03edfe2019-07-27 22:35:35 +0200482 if (!refcount_read(&map->core.refcnt))
Arnaldo Carvalho de Melo895e3b02018-03-26 11:42:15 -0300483 return -ENOENT;
484
485 return __perf_mmap__read_init(map);
486}
487
Jiri Olsaa5830532019-07-27 20:30:53 +0200488int perf_mmap__push(struct mmap *md, void *to,
489 int push(struct mmap *map, void *to, void *buf, size_t size))
Kan Liang88724812018-01-18 13:26:19 -0800490{
491 u64 head = perf_mmap__read_head(md);
Jiri Olsa547740f2019-07-27 22:07:44 +0200492 unsigned char *data = md->core.base + page_size;
Kan Liang88724812018-01-18 13:26:19 -0800493 unsigned long size;
494 void *buf;
495 int rc = 0;
496
Kan Liangb9bae2c2018-03-06 10:36:07 -0500497 rc = perf_mmap__read_init(md);
Kan Liang189f2cc2018-01-18 13:26:20 -0800498 if (rc < 0)
Alexey Budankovef781122019-03-18 20:44:12 +0300499 return (rc == -EAGAIN) ? 1 : -1;
Kan Liang88724812018-01-18 13:26:19 -0800500
Jiri Olsaebe4d722019-07-27 22:39:53 +0200501 size = md->core.end - md->core.start;
Kan Liangdc6c35c2018-01-18 13:26:17 -0800502
Jiri Olsaebe4d722019-07-27 22:39:53 +0200503 if ((md->core.start & md->core.mask) + size != (md->core.end & md->core.mask)) {
504 buf = &data[md->core.start & md->core.mask];
505 size = md->core.mask + 1 - (md->core.start & md->core.mask);
506 md->core.start += size;
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300507
Jiri Olsaded2b8f2018-09-13 14:54:06 +0200508 if (push(md, to, buf, size) < 0) {
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300509 rc = -1;
510 goto out;
511 }
512 }
513
Jiri Olsaebe4d722019-07-27 22:39:53 +0200514 buf = &data[md->core.start & md->core.mask];
515 size = md->core.end - md->core.start;
516 md->core.start += size;
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300517
Jiri Olsaded2b8f2018-09-13 14:54:06 +0200518 if (push(md, to, buf, size) < 0) {
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300519 rc = -1;
520 goto out;
521 }
522
Jiri Olsaebe4d722019-07-27 22:39:53 +0200523 md->core.prev = head;
Kan Liangd6ace3d2018-03-06 10:36:05 -0500524 perf_mmap__consume(md);
Arnaldo Carvalho de Melo73c17d82017-10-06 10:46:01 -0300525out:
526 return rc;
527}
Kan Liangee023de2018-01-18 13:26:22 -0800528
529/*
530 * Mandatory for overwrite mode
531 * The direction of overwrite mode is backward.
Jiri Olsaebe4d722019-07-27 22:39:53 +0200532 * The last perf_mmap__read() will set tail to map->core.prev.
533 * Need to correct the map->core.prev to head which is the end of next read.
Kan Liangee023de2018-01-18 13:26:22 -0800534 */
Jiri Olsaa5830532019-07-27 20:30:53 +0200535void perf_mmap__read_done(struct mmap *map)
Kan Liangee023de2018-01-18 13:26:22 -0800536{
Kan Liangf58385f2018-03-26 09:42:09 -0400537 /*
538 * Check if event was unmapped due to a POLLHUP/POLLERR.
539 */
Jiri Olsae03edfe2019-07-27 22:35:35 +0200540 if (!refcount_read(&map->core.refcnt))
Kan Liangf58385f2018-03-26 09:42:09 -0400541 return;
542
Jiri Olsaebe4d722019-07-27 22:39:53 +0200543 map->core.prev = perf_mmap__read_head(map);
Kan Liangee023de2018-01-18 13:26:22 -0800544}