aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/perf_event.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/perf_event.h')
-rw-r--r--include/linux/perf_event.h90
1 files changed, 80 insertions, 10 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index bd9f55a5958d..ddbb6a901f65 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -299,18 +299,31 @@ struct perf_event_mmap_page {
299 /* 299 /*
300 * Bits needed to read the hw events in user-space. 300 * Bits needed to read the hw events in user-space.
301 * 301 *
302 * u32 seq; 302 * u32 seq, time_mult, time_shift, idx, width;
303 * s64 count; 303 * u64 count, enabled, running;
304 * u64 cyc, time_offset;
305 * s64 pmc = 0;
304 * 306 *
305 * do { 307 * do {
306 * seq = pc->lock; 308 * seq = pc->lock;
307 *
308 * barrier() 309 * barrier()
309 * if (pc->index) { 310 *
310 * count = pmc_read(pc->index - 1); 311 * enabled = pc->time_enabled;
311 * count += pc->offset; 312 * running = pc->time_running;
312 * } else 313 *
313 * goto regular_read; 314 * if (pc->cap_usr_time && enabled != running) {
315 * cyc = rdtsc();
316 * time_offset = pc->time_offset;
317 * time_mult = pc->time_mult;
318 * time_shift = pc->time_shift;
319 * }
320 *
321 * idx = pc->index;
322 * count = pc->offset;
323 * if (pc->cap_usr_rdpmc && idx) {
324 * width = pc->pmc_width;
325 * pmc = rdpmc(idx - 1);
326 * }
314 * 327 *
315 * barrier(); 328 * barrier();
316 * } while (pc->lock != seq); 329 * } while (pc->lock != seq);
@@ -323,14 +336,57 @@ struct perf_event_mmap_page {
323 __s64 offset; /* add to hardware event value */ 336 __s64 offset; /* add to hardware event value */
324 __u64 time_enabled; /* time event active */ 337 __u64 time_enabled; /* time event active */
325 __u64 time_running; /* time event on cpu */ 338 __u64 time_running; /* time event on cpu */
326 __u32 time_mult, time_shift; 339 union {
340 __u64 capabilities;
341 __u64 cap_usr_time : 1,
342 cap_usr_rdpmc : 1,
343 cap_____res : 62;
344 };
345
346 /*
347 * If cap_usr_rdpmc this field provides the bit-width of the value
348 * read using the rdpmc() or equivalent instruction. This can be used
349 * to sign extend the result like:
350 *
351 * pmc <<= 64 - width;
352 * pmc >>= 64 - width; // signed shift right
353 * count += pmc;
354 */
355 __u16 pmc_width;
356
357 /*
358 * If cap_usr_time the below fields can be used to compute the time
359 * delta since time_enabled (in ns) using rdtsc or similar.
360 *
361 * u64 quot, rem;
362 * u64 delta;
363 *
364 * quot = (cyc >> time_shift);
365 * rem = cyc & ((1 << time_shift) - 1);
366 * delta = time_offset + quot * time_mult +
367 * ((rem * time_mult) >> time_shift);
368 *
369 * Where time_offset,time_mult,time_shift and cyc are read in the
370 * seqcount loop described above. This delta can then be added to
371 * enabled and possible running (if idx), improving the scaling:
372 *
373 * enabled += delta;
374 * if (idx)
375 * running += delta;
376 *
377 * quot = count / running;
378 * rem = count % running;
379 * count = quot * enabled + (rem * enabled) / running;
380 */
381 __u16 time_shift;
382 __u32 time_mult;
327 __u64 time_offset; 383 __u64 time_offset;
328 384
329 /* 385 /*
330 * Hole for extension of the self monitor capabilities 386 * Hole for extension of the self monitor capabilities
331 */ 387 */
332 388
333 __u64 __reserved[121]; /* align to 1k */ 389 __u64 __reserved[120]; /* align to 1k */
334 390
335 /* 391 /*
336 * Control data for the mmap() data buffer. 392 * Control data for the mmap() data buffer.
@@ -550,6 +606,7 @@ struct perf_guest_info_callbacks {
550#include <linux/irq_work.h> 606#include <linux/irq_work.h>
551#include <linux/static_key.h> 607#include <linux/static_key.h>
552#include <linux/atomic.h> 608#include <linux/atomic.h>
609#include <linux/sysfs.h>
553#include <asm/local.h> 610#include <asm/local.h>
554 611
555#define PERF_MAX_STACK_DEPTH 255 612#define PERF_MAX_STACK_DEPTH 255
@@ -1291,5 +1348,18 @@ do { \
1291 register_cpu_notifier(&fn##_nb); \ 1348 register_cpu_notifier(&fn##_nb); \
1292} while (0) 1349} while (0)
1293 1350
1351
1352#define PMU_FORMAT_ATTR(_name, _format) \
1353static ssize_t \
1354_name##_show(struct device *dev, \
1355 struct device_attribute *attr, \
1356 char *page) \
1357{ \
1358 BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
1359 return sprintf(page, _format "\n"); \
1360} \
1361 \
1362static struct device_attribute format_attr_##_name = __ATTR_RO(_name)
1363
1294#endif /* __KERNEL__ */ 1364#endif /* __KERNEL__ */
1295#endif /* _LINUX_PERF_EVENT_H */ 1365#endif /* _LINUX_PERF_EVENT_H */