aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/perf_event.h
diff options
context:
space:
mode:
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>2015-01-14 07:18:16 -0500
committerIngo Molnar <mingo@kernel.org>2015-04-02 11:14:13 -0400
commitfdc2670666f40ab3e03143f04d1ebf4a05e2c24a (patch)
tree6631370dbbb9a95fe3b8cd4bd62fda2e9b082daa /include/linux/perf_event.h
parent68db7e98c3a6ebe7284b6cf14906ed7c55f3f7f0 (diff)
perf: Add API for PMUs to write to the AUX area
For pmus that wish to write data to ring buffer's AUX area, provide perf_aux_output_{begin,end}() calls to initiate/commit data writes, similarly to perf_output_{begin,end}. These also use the same output handle structure. Also, similarly to software counterparts, these will direct inherited events' output to parents' ring buffers. After the perf_aux_output_begin() returns successfully, handle->size is set to the maximum amount of data that can be written wrt aux_tail pointer, so that no data that the user hasn't seen will be overwritten, therefore this should always be called before hardware writing is enabled. On success, this will return the pointer to pmu driver's private structure allocated for this aux area by pmu::setup_aux. Same pointer can also be retrieved using perf_get_aux() while hardware writing is enabled. PMU driver should pass the actual amount of data written as a parameter to perf_aux_output_end(). All hardware writes should be completed and visible before this one is called. Additionally, perf_aux_output_skip() will adjust output handle and aux_head in case some part of the buffer has to be skipped over to maintain hardware's alignment constraints. Nested writers are forbidden and guards are in place to catch such attempts. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Kaixu Xia <kaixu.xia@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Robert Richter <rric@kernel.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: acme@infradead.org Cc: adrian.hunter@intel.com Cc: kan.liang@intel.com Cc: markus.t.metzger@intel.com Cc: mathieu.poirier@linaro.org Link: http://lkml.kernel.org/r/1421237903-181015-8-git-send-email-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/perf_event.h')
-rw-r--r--include/linux/perf_event.h24
1 files changed, 23 insertions, 1 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f936a1e51f29..45c5873ad9b3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -573,7 +573,10 @@ struct perf_output_handle {
573 struct ring_buffer *rb; 573 struct ring_buffer *rb;
574 unsigned long wakeup; 574 unsigned long wakeup;
575 unsigned long size; 575 unsigned long size;
576 void *addr; 576 union {
577 void *addr;
578 unsigned long head;
579 };
577 int page; 580 int page;
578}; 581};
579 582
@@ -608,6 +611,14 @@ perf_cgroup_from_task(struct task_struct *task)
608 611
609#ifdef CONFIG_PERF_EVENTS 612#ifdef CONFIG_PERF_EVENTS
610 613
614extern void *perf_aux_output_begin(struct perf_output_handle *handle,
615 struct perf_event *event);
616extern void perf_aux_output_end(struct perf_output_handle *handle,
617 unsigned long size, bool truncated);
618extern int perf_aux_output_skip(struct perf_output_handle *handle,
619 unsigned long size);
620extern void *perf_get_aux(struct perf_output_handle *handle);
621
611extern int perf_pmu_register(struct pmu *pmu, const char *name, int type); 622extern int perf_pmu_register(struct pmu *pmu, const char *name, int type);
612extern void perf_pmu_unregister(struct pmu *pmu); 623extern void perf_pmu_unregister(struct pmu *pmu);
613 624
@@ -898,6 +909,17 @@ extern void perf_event_disable(struct perf_event *event);
898extern int __perf_event_disable(void *info); 909extern int __perf_event_disable(void *info);
899extern void perf_event_task_tick(void); 910extern void perf_event_task_tick(void);
900#else /* !CONFIG_PERF_EVENTS: */ 911#else /* !CONFIG_PERF_EVENTS: */
912static inline void *
913perf_aux_output_begin(struct perf_output_handle *handle,
914 struct perf_event *event) { return NULL; }
915static inline void
916perf_aux_output_end(struct perf_output_handle *handle, unsigned long size,
917 bool truncated) { }
918static inline int
919perf_aux_output_skip(struct perf_output_handle *handle,
920 unsigned long size) { return -EINVAL; }
921static inline void *
922perf_get_aux(struct perf_output_handle *handle) { return NULL; }
901static inline void 923static inline void
902perf_event_task_sched_in(struct task_struct *prev, 924perf_event_task_sched_in(struct task_struct *prev,
903 struct task_struct *task) { } 925 struct task_struct *task) { }