diff options
Diffstat (limited to 'drivers/oprofile/cpu_buffer.h')
-rw-r--r-- | drivers/oprofile/cpu_buffer.h | 72 |
1 files changed, 62 insertions, 10 deletions
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index d3cc26264db5..63f81c44846a 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h | |||
@@ -1,10 +1,11 @@ | |||
1 | /** | 1 | /** |
2 | * @file cpu_buffer.h | 2 | * @file cpu_buffer.h |
3 | * | 3 | * |
4 | * @remark Copyright 2002 OProfile authors | 4 | * @remark Copyright 2002-2009 OProfile authors |
5 | * @remark Read the file COPYING | 5 | * @remark Read the file COPYING |
6 | * | 6 | * |
7 | * @author John Levon <levon@movementarian.org> | 7 | * @author John Levon <levon@movementarian.org> |
8 | * @author Robert Richter <robert.richter@amd.com> | ||
8 | */ | 9 | */ |
9 | 10 | ||
10 | #ifndef OPROFILE_CPU_BUFFER_H | 11 | #ifndef OPROFILE_CPU_BUFFER_H |
@@ -15,6 +16,7 @@ | |||
15 | #include <linux/workqueue.h> | 16 | #include <linux/workqueue.h> |
16 | #include <linux/cache.h> | 17 | #include <linux/cache.h> |
17 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/ring_buffer.h> | ||
18 | 20 | ||
19 | struct task_struct; | 21 | struct task_struct; |
20 | 22 | ||
@@ -30,16 +32,16 @@ void end_cpu_work(void); | |||
30 | struct op_sample { | 32 | struct op_sample { |
31 | unsigned long eip; | 33 | unsigned long eip; |
32 | unsigned long event; | 34 | unsigned long event; |
35 | unsigned long data[0]; | ||
33 | }; | 36 | }; |
34 | 37 | ||
38 | struct op_entry; | ||
39 | |||
35 | struct oprofile_cpu_buffer { | 40 | struct oprofile_cpu_buffer { |
36 | volatile unsigned long head_pos; | ||
37 | volatile unsigned long tail_pos; | ||
38 | unsigned long buffer_size; | 41 | unsigned long buffer_size; |
39 | struct task_struct *last_task; | 42 | struct task_struct *last_task; |
40 | int last_is_kernel; | 43 | int last_is_kernel; |
41 | int tracing; | 44 | int tracing; |
42 | struct op_sample *buffer; | ||
43 | unsigned long sample_received; | 45 | unsigned long sample_received; |
44 | unsigned long sample_lost_overflow; | 46 | unsigned long sample_lost_overflow; |
45 | unsigned long backtrace_aborted; | 47 | unsigned long backtrace_aborted; |
@@ -50,12 +52,62 @@ struct oprofile_cpu_buffer { | |||
50 | 52 | ||
51 | DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer); | 53 | DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer); |
52 | 54 | ||
53 | void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf); | 55 | /* |
56 | * Resets the cpu buffer to a sane state. | ||
57 | * | ||
58 | * reset these to invalid values; the next sample collected will | ||
59 | * populate the buffer with proper values to initialize the buffer | ||
60 | */ | ||
61 | static inline void op_cpu_buffer_reset(int cpu) | ||
62 | { | ||
63 | struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu); | ||
64 | |||
65 | cpu_buf->last_is_kernel = -1; | ||
66 | cpu_buf->last_task = NULL; | ||
67 | } | ||
68 | |||
69 | struct op_sample | ||
70 | *op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size); | ||
71 | int op_cpu_buffer_write_commit(struct op_entry *entry); | ||
72 | struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu); | ||
73 | unsigned long op_cpu_buffer_entries(int cpu); | ||
74 | |||
75 | /* returns the remaining free size of data in the entry */ | ||
76 | static inline | ||
77 | int op_cpu_buffer_add_data(struct op_entry *entry, unsigned long val) | ||
78 | { | ||
79 | if (!entry->size) | ||
80 | return 0; | ||
81 | *entry->data = val; | ||
82 | entry->size--; | ||
83 | entry->data++; | ||
84 | return entry->size; | ||
85 | } | ||
86 | |||
87 | /* returns the size of data in the entry */ | ||
88 | static inline | ||
89 | int op_cpu_buffer_get_size(struct op_entry *entry) | ||
90 | { | ||
91 | return entry->size; | ||
92 | } | ||
93 | |||
94 | /* returns 0 if empty or the size of data including the current value */ | ||
95 | static inline | ||
96 | int op_cpu_buffer_get_data(struct op_entry *entry, unsigned long *val) | ||
97 | { | ||
98 | int size = entry->size; | ||
99 | if (!size) | ||
100 | return 0; | ||
101 | *val = *entry->data; | ||
102 | entry->size--; | ||
103 | entry->data++; | ||
104 | return size; | ||
105 | } | ||
54 | 106 | ||
55 | /* transient events for the CPU buffer -> event buffer */ | 107 | /* extra data flags */ |
56 | #define CPU_IS_KERNEL 1 | 108 | #define KERNEL_CTX_SWITCH (1UL << 0) |
57 | #define CPU_TRACE_BEGIN 2 | 109 | #define IS_KERNEL (1UL << 1) |
58 | #define IBS_FETCH_BEGIN 3 | 110 | #define TRACE_BEGIN (1UL << 2) |
59 | #define IBS_OP_BEGIN 4 | 111 | #define USER_CTX_SWITCH (1UL << 3) |
60 | 112 | ||
61 | #endif /* OPROFILE_CPU_BUFFER_H */ | 113 | #endif /* OPROFILE_CPU_BUFFER_H */ |