aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-03-23 13:22:10 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-06 03:30:27 -0400
commit7b732a75047738e4f85438ed2f9cd34bf5f2a19a (patch)
treebae36de785ac819ceef6fa5e1b7884a4a421cc3c /include/linux
parentb09d2501ed3d294619cbfbcf828ad39324d0e548 (diff)
perf_counter: new output ABI - part 1
Impact: Rework the perfcounter output ABI use sys_read() only for instant data and provide mmap() output for all async overflow data. The first mmap() determines the size of the output buffer. The mmap() size must be a PAGE_SIZE multiple of 1+pages, where pages must be a power of 2 or 0. Further mmap()s of the same fd must have the same size. Once all maps are gone, you can again mmap() with a new size. In case of 0 extra pages there is no data output and the first page only contains meta data. When there are data pages, a poll() event will be generated for each full page of data. Furthermore, the output is circular. This means that although 1 page is a valid configuration, its useless, since we'll start overwriting it the instant we report a full page. Future work will focus on the output format (currently maintained) where we'll likey want each entry denoted by a header which includes a type and length. Further future work will allow to splice() the fd, also containing the async overflow data -- splice() would be mutually exclusive with mmap() of the data. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Orig-LKML-Reference: <20090323172417.470536358@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/perf_counter.h36
1 files changed, 15 insertions, 21 deletions
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index 40b324e91bf6..2b5e66d5ebdf 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -152,6 +152,8 @@ struct perf_counter_mmap_page {
152 __u32 lock; /* seqlock for synchronization */ 152 __u32 lock; /* seqlock for synchronization */
153 __u32 index; /* hardware counter identifier */ 153 __u32 index; /* hardware counter identifier */
154 __s64 offset; /* add to hardware counter value */ 154 __s64 offset; /* add to hardware counter value */
155
156 __u32 data_head; /* head in the data section */
155}; 157};
156 158
157#ifdef __KERNEL__ 159#ifdef __KERNEL__
@@ -218,21 +220,6 @@ struct hw_perf_counter {
218#endif 220#endif
219}; 221};
220 222
221/*
222 * Hardcoded buffer length limit for now, for IRQ-fed events:
223 */
224#define PERF_DATA_BUFLEN 2048
225
226/**
227 * struct perf_data - performance counter IRQ data sampling ...
228 */
229struct perf_data {
230 int len;
231 int rd_idx;
232 int overrun;
233 u8 data[PERF_DATA_BUFLEN];
234};
235
236struct perf_counter; 223struct perf_counter;
237 224
238/** 225/**
@@ -256,6 +243,14 @@ enum perf_counter_active_state {
256 243
257struct file; 244struct file;
258 245
246struct perf_mmap_data {
247 struct rcu_head rcu_head;
248 int nr_pages;
249 atomic_t head;
250 struct perf_counter_mmap_page *user_page;
251 void *data_pages[0];
252};
253
259/** 254/**
260 * struct perf_counter - performance counter kernel representation: 255 * struct perf_counter - performance counter kernel representation:
261 */ 256 */
@@ -289,16 +284,15 @@ struct perf_counter {
289 int oncpu; 284 int oncpu;
290 int cpu; 285 int cpu;
291 286
292 /* pointer to page shared with userspace via mmap */ 287 /* mmap bits */
293 unsigned long user_page; 288 struct mutex mmap_mutex;
289 atomic_t mmap_count;
290 struct perf_mmap_data *data;
294 291
295 /* read() / irq related data */ 292 /* poll related */
296 wait_queue_head_t waitq; 293 wait_queue_head_t waitq;
297 /* optional: for NMIs */ 294 /* optional: for NMIs */
298 int wakeup_pending; 295 int wakeup_pending;
299 struct perf_data *irqdata;
300 struct perf_data *usrdata;
301 struct perf_data data[2];
302 296
303 void (*destroy)(struct perf_counter *); 297 void (*destroy)(struct perf_counter *);
304 struct rcu_head rcu_head; 298 struct rcu_head rcu_head;