diff options
author | Paul Mackerras <paulus@samba.org> | 2009-03-23 13:22:08 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-06 03:30:26 -0400 |
commit | 37d81828385f8ff823caaaf1a83e72d065b6cfa1 (patch) | |
tree | 972900a193a6a5ab1bdc14adcd7ab72bf0a51c13 /include/linux/perf_counter.h | |
parent | 96f6d4444302bb2ea2cf409529eef816462f6ce0 (diff) |
perf_counter: add an mmap method to allow userspace to read hardware counters
Impact: new feature giving performance improvement
This adds the ability for userspace to do an mmap on a hardware counter
fd and get access to a read-only page that contains the information
needed to translate a hardware counter value to the full 64-bit
counter value that would be returned by a read on the fd. This is
useful on architectures that allow user programs to read the hardware
counters, such as PowerPC.
The mmap will only succeed if the counter is a hardware counter
monitoring the current process.
On my quad 2.5GHz PowerPC 970MP machine, userspace can read a counter
and translate it to the full 64-bit value in about 30ns using the
mmapped page, compared to about 830ns for the read syscall on the
counter, so this does give a significant performance improvement.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Orig-LKML-Reference: <20090323172417.297057964@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/perf_counter.h')
-rw-r--r-- | include/linux/perf_counter.h | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 18dc17d0a61c..40b324e91bf6 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h | |||
@@ -143,6 +143,17 @@ struct perf_counter_hw_event { | |||
143 | #define PERF_COUNTER_IOC_ENABLE _IO('$', 0) | 143 | #define PERF_COUNTER_IOC_ENABLE _IO('$', 0) |
144 | #define PERF_COUNTER_IOC_DISABLE _IO('$', 1) | 144 | #define PERF_COUNTER_IOC_DISABLE _IO('$', 1) |
145 | 145 | ||
146 | /* | ||
147 | * Structure of the page that can be mapped via mmap | ||
148 | */ | ||
149 | struct perf_counter_mmap_page { | ||
150 | __u32 version; /* version number of this structure */ | ||
151 | __u32 compat_version; /* lowest version this is compat with */ | ||
152 | __u32 lock; /* seqlock for synchronization */ | ||
153 | __u32 index; /* hardware counter identifier */ | ||
154 | __s64 offset; /* add to hardware counter value */ | ||
155 | }; | ||
156 | |||
146 | #ifdef __KERNEL__ | 157 | #ifdef __KERNEL__ |
147 | /* | 158 | /* |
148 | * Kernel-internal data types and definitions: | 159 | * Kernel-internal data types and definitions: |
@@ -278,6 +289,9 @@ struct perf_counter { | |||
278 | int oncpu; | 289 | int oncpu; |
279 | int cpu; | 290 | int cpu; |
280 | 291 | ||
292 | /* pointer to page shared with userspace via mmap */ | ||
293 | unsigned long user_page; | ||
294 | |||
281 | /* read() / irq related data */ | 295 | /* read() / irq related data */ |
282 | wait_queue_head_t waitq; | 296 | wait_queue_head_t waitq; |
283 | /* optional: for NMIs */ | 297 | /* optional: for NMIs */ |
@@ -361,6 +375,7 @@ extern int perf_counter_task_enable(void); | |||
361 | extern int hw_perf_group_sched_in(struct perf_counter *group_leader, | 375 | extern int hw_perf_group_sched_in(struct perf_counter *group_leader, |
362 | struct perf_cpu_context *cpuctx, | 376 | struct perf_cpu_context *cpuctx, |
363 | struct perf_counter_context *ctx, int cpu); | 377 | struct perf_counter_context *ctx, int cpu); |
378 | extern void perf_counter_update_userpage(struct perf_counter *counter); | ||
364 | 379 | ||
365 | extern void perf_counter_output(struct perf_counter *counter, | 380 | extern void perf_counter_output(struct perf_counter *counter, |
366 | int nmi, struct pt_regs *regs); | 381 | int nmi, struct pt_regs *regs); |