diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/ftrace_event.h | 2 | ||||
-rw-r--r-- | include/linux/kernel.h | 15 | ||||
-rw-r--r-- | include/linux/perf_event.h | 90 | ||||
-rw-r--r-- | include/linux/ring_buffer.h | 3 |
4 files changed, 94 insertions, 16 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index dd478fc8f9f5..5f3f3be5af09 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -144,12 +144,14 @@ struct event_filter; | |||
144 | enum trace_reg { | 144 | enum trace_reg { |
145 | TRACE_REG_REGISTER, | 145 | TRACE_REG_REGISTER, |
146 | TRACE_REG_UNREGISTER, | 146 | TRACE_REG_UNREGISTER, |
147 | #ifdef CONFIG_PERF_EVENTS | ||
147 | TRACE_REG_PERF_REGISTER, | 148 | TRACE_REG_PERF_REGISTER, |
148 | TRACE_REG_PERF_UNREGISTER, | 149 | TRACE_REG_PERF_UNREGISTER, |
149 | TRACE_REG_PERF_OPEN, | 150 | TRACE_REG_PERF_OPEN, |
150 | TRACE_REG_PERF_CLOSE, | 151 | TRACE_REG_PERF_CLOSE, |
151 | TRACE_REG_PERF_ADD, | 152 | TRACE_REG_PERF_ADD, |
152 | TRACE_REG_PERF_DEL, | 153 | TRACE_REG_PERF_DEL, |
154 | #endif | ||
153 | }; | 155 | }; |
154 | 156 | ||
155 | struct ftrace_event_call; | 157 | struct ftrace_event_call; |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index a5375e7f3fea..645231c373c8 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -430,16 +430,10 @@ extern int __must_check hex2bin(u8 *dst, const char *src, size_t count); | |||
430 | * Most likely, you want to use tracing_on/tracing_off. | 430 | * Most likely, you want to use tracing_on/tracing_off. |
431 | */ | 431 | */ |
432 | #ifdef CONFIG_RING_BUFFER | 432 | #ifdef CONFIG_RING_BUFFER |
433 | void tracing_on(void); | ||
434 | void tracing_off(void); | ||
435 | /* trace_off_permanent stops recording with no way to bring it back */ | 433 | /* trace_off_permanent stops recording with no way to bring it back */ |
436 | void tracing_off_permanent(void); | 434 | void tracing_off_permanent(void); |
437 | int tracing_is_on(void); | ||
438 | #else | 435 | #else |
439 | static inline void tracing_on(void) { } | ||
440 | static inline void tracing_off(void) { } | ||
441 | static inline void tracing_off_permanent(void) { } | 436 | static inline void tracing_off_permanent(void) { } |
442 | static inline int tracing_is_on(void) { return 0; } | ||
443 | #endif | 437 | #endif |
444 | 438 | ||
445 | enum ftrace_dump_mode { | 439 | enum ftrace_dump_mode { |
@@ -449,6 +443,10 @@ enum ftrace_dump_mode { | |||
449 | }; | 443 | }; |
450 | 444 | ||
451 | #ifdef CONFIG_TRACING | 445 | #ifdef CONFIG_TRACING |
446 | void tracing_on(void); | ||
447 | void tracing_off(void); | ||
448 | int tracing_is_on(void); | ||
449 | |||
452 | extern void tracing_start(void); | 450 | extern void tracing_start(void); |
453 | extern void tracing_stop(void); | 451 | extern void tracing_stop(void); |
454 | extern void ftrace_off_permanent(void); | 452 | extern void ftrace_off_permanent(void); |
@@ -533,6 +531,11 @@ static inline void tracing_start(void) { } | |||
533 | static inline void tracing_stop(void) { } | 531 | static inline void tracing_stop(void) { } |
534 | static inline void ftrace_off_permanent(void) { } | 532 | static inline void ftrace_off_permanent(void) { } |
535 | static inline void trace_dump_stack(void) { } | 533 | static inline void trace_dump_stack(void) { } |
534 | |||
535 | static inline void tracing_on(void) { } | ||
536 | static inline void tracing_off(void) { } | ||
537 | static inline int tracing_is_on(void) { return 0; } | ||
538 | |||
536 | static inline int | 539 | static inline int |
537 | trace_printk(const char *fmt, ...) | 540 | trace_printk(const char *fmt, ...) |
538 | { | 541 | { |
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) \ | ||
1353 | static 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 | \ | ||
1362 | static 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 */ |
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 67be0376d8e3..7be2e88f23fd 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h | |||
@@ -151,6 +151,9 @@ int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu); | |||
151 | 151 | ||
152 | void ring_buffer_record_disable(struct ring_buffer *buffer); | 152 | void ring_buffer_record_disable(struct ring_buffer *buffer); |
153 | void ring_buffer_record_enable(struct ring_buffer *buffer); | 153 | void ring_buffer_record_enable(struct ring_buffer *buffer); |
154 | void ring_buffer_record_off(struct ring_buffer *buffer); | ||
155 | void ring_buffer_record_on(struct ring_buffer *buffer); | ||
156 | int ring_buffer_record_is_on(struct ring_buffer *buffer); | ||
154 | void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); | 157 | void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); |
155 | void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); | 158 | void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); |
156 | 159 | ||