1 // SPDX-License-Identifier: GPL-2.0 2 #include <sys/mman.h> 3 #include <inttypes.h> 4 #include <asm/bug.h> 5 #include <errno.h> 6 #include <string.h> 7 #include <linux/ring_buffer.h> 8 #include <linux/perf_event.h> 9 #include <perf/mmap.h> 10 #include <perf/event.h> 11 #include <internal/mmap.h> 12 #include <internal/lib.h> 13 #include <linux/kernel.h> 14 #include "internal.h" 15 16 void perf_mmap__init(struct perf_mmap *map, struct perf_mmap *prev, 17 bool overwrite, libperf_unmap_cb_t unmap_cb) 18 { 19 map->fd = -1; 20 map->overwrite = overwrite; 21 map->unmap_cb = unmap_cb; 22 refcount_set(&map->refcnt, 0); 23 if (prev) 24 prev->next = map; 25 } 26 27 size_t perf_mmap__mmap_len(struct perf_mmap *map) 28 { 29 return map->mask + 1 + page_size; 30 } 31 32 int perf_mmap__mmap(struct perf_mmap *map, struct perf_mmap_param *mp, 33 int fd, int cpu) 34 { 35 map->prev = 0; 36 map->mask = mp->mask; 37 map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot, 38 MAP_SHARED, fd, 0); 39 if (map->base == MAP_FAILED) { 40 map->base = NULL; 41 return -1; 42 } 43 44 map->fd = fd; 45 map->cpu = cpu; 46 return 0; 47 } 48 49 void perf_mmap__munmap(struct perf_mmap *map) 50 { 51 if (map && map->base != NULL) { 52 munmap(map->base, perf_mmap__mmap_len(map)); 53 map->base = NULL; 54 map->fd = -1; 55 refcount_set(&map->refcnt, 0); 56 } 57 if (map && map->unmap_cb) 58 map->unmap_cb(map); 59 } 60 61 void perf_mmap__get(struct perf_mmap *map) 62 { 63 refcount_inc(&map->refcnt); 64 } 65 66 void perf_mmap__put(struct perf_mmap *map) 67 { 68 BUG_ON(map->base && refcount_read(&map->refcnt) == 0); 69 70 if (refcount_dec_and_test(&map->refcnt)) 71 perf_mmap__munmap(map); 72 } 73 74 static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) 75 { 76 ring_buffer_write_tail(md->base, tail); 77 } 78 79 u64 perf_mmap__read_head(struct perf_mmap *map) 80 { 81 return ring_buffer_read_head(map->base); 82 } 83 84 static bool perf_mmap__empty(struct perf_mmap *map) 85 { 86 struct perf_event_mmap_page *pc = map->base; 87 88 return perf_mmap__read_head(map) == map->prev && !pc->aux_size; 89 } 90 91 void perf_mmap__consume(struct perf_mmap *map) 92 { 93 if (!map->overwrite) { 94 u64 old = map->prev; 95 96 perf_mmap__write_tail(map, old); 97 } 98 99 if (refcount_read(&map->refcnt) == 1 && perf_mmap__empty(map)) 100 perf_mmap__put(map); 101 } 102 103 static int overwrite_rb_find_range(void *buf, int mask, u64 *start, u64 *end) 104 { 105 struct perf_event_header *pheader; 106 u64 evt_head = *start; 107 int size = mask + 1; 108 109 pr_debug2("%s: buf=%p, start=%"PRIx64"\n", __func__, buf, *start); 110 pheader = (struct perf_event_header *)(buf + (*start & mask)); 111 while (true) { 112 if (evt_head - *start >= (unsigned int)size) { 113 pr_debug("Finished reading overwrite ring buffer: rewind\n"); 114 if (evt_head - *start > (unsigned int)size) 115 evt_head -= pheader->size; 116 *end = evt_head; 117 return 0; 118 } 119 120 pheader = (struct perf_event_header *)(buf + (evt_head & mask)); 121 122 if (pheader->size == 0) { 123 pr_debug("Finished reading overwrite ring buffer: get start\n"); 124 *end = evt_head; 125 return 0; 126 } 127 128 evt_head += pheader->size; 129 pr_debug3("move evt_head: %"PRIx64"\n", evt_head); 130 } 131 WARN_ONCE(1, "Shouldn't get here\n"); 132 return -1; 133 } 134 135 /* 136 * Report the start and end of the available data in ringbuffer 137 */ 138 static int __perf_mmap__read_init(struct perf_mmap *md) 139 { 140 u64 head = perf_mmap__read_head(md); 141 u64 old = md->prev; 142 unsigned char *data = md->base + page_size; 143 unsigned long size; 144 145 md->start = md->overwrite ? head : old; 146 md->end = md->overwrite ? old : head; 147 148 if ((md->end - md->start) < md->flush) 149 return -EAGAIN; 150 151 size = md->end - md->start; 152 if (size > (unsigned long)(md->mask) + 1) { 153 if (!md->overwrite) { 154 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); 155 156 md->prev = head; 157 perf_mmap__consume(md); 158 return -EAGAIN; 159 } 160 161 /* 162 * Backward ring buffer is full. We still have a chance to read 163 * most of data from it. 164 */ 165 if (overwrite_rb_find_range(data, md->mask, &md->start, &md->end)) 166 return -EINVAL; 167 } 168 169 return 0; 170 } 171 172 int perf_mmap__read_init(struct perf_mmap *map) 173 { 174 /* 175 * Check if event was unmapped due to a POLLHUP/POLLERR. 176 */ 177 if (!refcount_read(&map->refcnt)) 178 return -ENOENT; 179 180 return __perf_mmap__read_init(map); 181 } 182 183 /* 184 * Mandatory for overwrite mode 185 * The direction of overwrite mode is backward. 186 * The last perf_mmap__read() will set tail to map->core.prev. 187 * Need to correct the map->core.prev to head which is the end of next read. 188 */ 189 void perf_mmap__read_done(struct perf_mmap *map) 190 { 191 /* 192 * Check if event was unmapped due to a POLLHUP/POLLERR. 193 */ 194 if (!refcount_read(&map->refcnt)) 195 return; 196 197 map->prev = perf_mmap__read_head(map); 198 } 199 200 /* When check_messup is true, 'end' must points to a good entry */ 201 static union perf_event *perf_mmap__read(struct perf_mmap *map, 202 u64 *startp, u64 end) 203 { 204 unsigned char *data = map->base + page_size; 205 union perf_event *event = NULL; 206 int diff = end - *startp; 207 208 if (diff >= (int)sizeof(event->header)) { 209 size_t size; 210 211 event = (union perf_event *)&data[*startp & map->mask]; 212 size = event->header.size; 213 214 if (size < sizeof(event->header) || diff < (int)size) 215 return NULL; 216 217 /* 218 * Event straddles the mmap boundary -- header should always 219 * be inside due to u64 alignment of output. 220 */ 221 if ((*startp & map->mask) + size != ((*startp + size) & map->mask)) { 222 unsigned int offset = *startp; 223 unsigned int len = min(sizeof(*event), size), cpy; 224 void *dst = map->event_copy; 225 226 do { 227 cpy = min(map->mask + 1 - (offset & map->mask), len); 228 memcpy(dst, &data[offset & map->mask], cpy); 229 offset += cpy; 230 dst += cpy; 231 len -= cpy; 232 } while (len); 233 234 event = (union perf_event *)map->event_copy; 235 } 236 237 *startp += size; 238 } 239 240 return event; 241 } 242 243 /* 244 * Read event from ring buffer one by one. 245 * Return one event for each call. 246 * 247 * Usage: 248 * perf_mmap__read_init() 249 * while(event = perf_mmap__read_event()) { 250 * //process the event 251 * perf_mmap__consume() 252 * } 253 * perf_mmap__read_done() 254 */ 255 union perf_event *perf_mmap__read_event(struct perf_mmap *map) 256 { 257 union perf_event *event; 258 259 /* 260 * Check if event was unmapped due to a POLLHUP/POLLERR. 261 */ 262 if (!refcount_read(&map->refcnt)) 263 return NULL; 264 265 /* non-overwirte doesn't pause the ringbuffer */ 266 if (!map->overwrite) 267 map->end = perf_mmap__read_head(map); 268 269 event = perf_mmap__read(map, &map->start, map->end); 270 271 if (!map->overwrite) 272 map->prev = map->start; 273 274 return event; 275 } 276