perf_counter: add an event_list
[platform/kernel/linux-starfive.git] / include / linux / perf_counter.h
1 /*
2  *  Performance counters:
3  *
4  *   Copyright(C) 2008, Thomas Gleixner <tglx@linutronix.de>
5  *   Copyright(C) 2008, Red Hat, Inc., Ingo Molnar
6  *
7  *  Data type definitions, declarations, prototypes.
8  *
9  *  Started by: Thomas Gleixner and Ingo Molnar
10  *
11  *  For licencing details see kernel-base/COPYING
12  */
13 #ifndef _LINUX_PERF_COUNTER_H
14 #define _LINUX_PERF_COUNTER_H
15
16 #include <linux/types.h>
17 #include <linux/ioctl.h>
18
19 /*
20  * User-space ABI bits:
21  */
22
23 /*
24  * Generalized performance counter event types, used by the hw_event.type
25  * parameter of the sys_perf_counter_open() syscall:
26  */
27 enum hw_event_types {
28         /*
29          * Common hardware events, generalized by the kernel:
30          */
31         PERF_COUNT_CPU_CYCLES           =  0,
32         PERF_COUNT_INSTRUCTIONS         =  1,
33         PERF_COUNT_CACHE_REFERENCES     =  2,
34         PERF_COUNT_CACHE_MISSES         =  3,
35         PERF_COUNT_BRANCH_INSTRUCTIONS  =  4,
36         PERF_COUNT_BRANCH_MISSES        =  5,
37         PERF_COUNT_BUS_CYCLES           =  6,
38
39         PERF_HW_EVENTS_MAX              =  7,
40
41         /*
42          * Special "software" counters provided by the kernel, even if
43          * the hardware does not support performance counters. These
44          * counters measure various physical and sw events of the
45          * kernel (and allow the profiling of them as well):
46          */
47         PERF_COUNT_CPU_CLOCK            = -1,
48         PERF_COUNT_TASK_CLOCK           = -2,
49         PERF_COUNT_PAGE_FAULTS          = -3,
50         PERF_COUNT_CONTEXT_SWITCHES     = -4,
51         PERF_COUNT_CPU_MIGRATIONS       = -5,
52         PERF_COUNT_PAGE_FAULTS_MIN      = -6,
53         PERF_COUNT_PAGE_FAULTS_MAJ      = -7,
54
55         PERF_SW_EVENTS_MIN              = -8,
56 };
57
58 /*
59  * IRQ-notification data record type:
60  */
61 enum perf_counter_record_type {
62         PERF_RECORD_SIMPLE              =  0,
63         PERF_RECORD_IRQ                 =  1,
64         PERF_RECORD_GROUP               =  2,
65 };
66
67 /*
68  * Hardware event to monitor via a performance monitoring counter:
69  */
70 struct perf_counter_hw_event {
71         __s64                   type;
72
73         __u64                   irq_period;
74         __u64                   record_type;
75         __u64                   read_format;
76
77         __u64                   disabled       :  1, /* off by default        */
78                                 nmi            :  1, /* NMI sampling          */
79                                 raw            :  1, /* raw event type        */
80                                 inherit        :  1, /* children inherit it   */
81                                 pinned         :  1, /* must always be on PMU */
82                                 exclusive      :  1, /* only group on PMU     */
83                                 exclude_user   :  1, /* don't count user      */
84                                 exclude_kernel :  1, /* ditto kernel          */
85                                 exclude_hv     :  1, /* ditto hypervisor      */
86                                 exclude_idle   :  1, /* don't count when idle */
87
88                                 __reserved_1   : 54;
89
90         __u32                   extra_config_len;
91         __u32                   __reserved_4;
92
93         __u64                   __reserved_2;
94         __u64                   __reserved_3;
95 };
96
97 /*
98  * Ioctls that can be done on a perf counter fd:
99  */
100 #define PERF_COUNTER_IOC_ENABLE         _IO('$', 0)
101 #define PERF_COUNTER_IOC_DISABLE        _IO('$', 1)
102
103 #ifdef __KERNEL__
104 /*
105  * Kernel-internal data types and definitions:
106  */
107
108 #ifdef CONFIG_PERF_COUNTERS
109 # include <asm/perf_counter.h>
110 #endif
111
112 #include <linux/list.h>
113 #include <linux/mutex.h>
114 #include <linux/rculist.h>
115 #include <linux/rcupdate.h>
116 #include <linux/spinlock.h>
117 #include <linux/hrtimer.h>
118 #include <asm/atomic.h>
119
120 struct task_struct;
121
122 /**
123  * struct hw_perf_counter - performance counter hardware details:
124  */
125 struct hw_perf_counter {
126 #ifdef CONFIG_PERF_COUNTERS
127         union {
128                 struct { /* hardware */
129                         u64                             config;
130                         unsigned long                   config_base;
131                         unsigned long                   counter_base;
132                         int                             nmi;
133                         unsigned int                    idx;
134                 };
135                 union { /* software */
136                         atomic64_t                      count;
137                         struct hrtimer                  hrtimer;
138                 };
139         };
140         atomic64_t                      prev_count;
141         u64                             irq_period;
142         atomic64_t                      period_left;
143 #endif
144 };
145
146 /*
147  * Hardcoded buffer length limit for now, for IRQ-fed events:
148  */
149 #define PERF_DATA_BUFLEN                2048
150
151 /**
152  * struct perf_data - performance counter IRQ data sampling ...
153  */
154 struct perf_data {
155         int                             len;
156         int                             rd_idx;
157         int                             overrun;
158         u8                              data[PERF_DATA_BUFLEN];
159 };
160
161 struct perf_counter;
162
163 /**
164  * struct hw_perf_counter_ops - performance counter hw ops
165  */
166 struct hw_perf_counter_ops {
167         int (*enable)                   (struct perf_counter *counter);
168         void (*disable)                 (struct perf_counter *counter);
169         void (*read)                    (struct perf_counter *counter);
170 };
171
172 /**
173  * enum perf_counter_active_state - the states of a counter
174  */
175 enum perf_counter_active_state {
176         PERF_COUNTER_STATE_ERROR        = -2,
177         PERF_COUNTER_STATE_OFF          = -1,
178         PERF_COUNTER_STATE_INACTIVE     =  0,
179         PERF_COUNTER_STATE_ACTIVE       =  1,
180 };
181
182 struct file;
183
184 /**
185  * struct perf_counter - performance counter kernel representation:
186  */
187 struct perf_counter {
188 #ifdef CONFIG_PERF_COUNTERS
189         struct list_head                list_entry;
190         struct list_head                event_entry;
191         struct list_head                sibling_list;
192         struct perf_counter             *group_leader;
193         const struct hw_perf_counter_ops *hw_ops;
194
195         enum perf_counter_active_state  state;
196         enum perf_counter_active_state  prev_state;
197         atomic64_t                      count;
198
199         struct perf_counter_hw_event    hw_event;
200         struct hw_perf_counter          hw;
201
202         struct perf_counter_context     *ctx;
203         struct task_struct              *task;
204         struct file                     *filp;
205
206         struct perf_counter             *parent;
207         struct list_head                child_list;
208
209         /*
210          * Protect attach/detach and child_list:
211          */
212         struct mutex                    mutex;
213
214         int                             oncpu;
215         int                             cpu;
216
217         /* read() / irq related data */
218         wait_queue_head_t               waitq;
219         /* optional: for NMIs */
220         int                             wakeup_pending;
221         struct perf_data                *irqdata;
222         struct perf_data                *usrdata;
223         struct perf_data                data[2];
224
225         struct rcu_head                 rcu_head;
226 #endif
227 };
228
229 /**
230  * struct perf_counter_context - counter context structure
231  *
232  * Used as a container for task counters and CPU counters as well:
233  */
234 struct perf_counter_context {
235 #ifdef CONFIG_PERF_COUNTERS
236         /*
237          * Protect the states of the counters in the list,
238          * nr_active, and the list:
239          */
240         spinlock_t              lock;
241         /*
242          * Protect the list of counters.  Locking either mutex or lock
243          * is sufficient to ensure the list doesn't change; to change
244          * the list you need to lock both the mutex and the spinlock.
245          */
246         struct mutex            mutex;
247
248         struct list_head        counter_list;
249         struct list_head        event_list;
250         int                     nr_counters;
251         int                     nr_active;
252         int                     is_active;
253         struct task_struct      *task;
254 #endif
255 };
256
257 /**
258  * struct perf_counter_cpu_context - per cpu counter context structure
259  */
260 struct perf_cpu_context {
261         struct perf_counter_context     ctx;
262         struct perf_counter_context     *task_ctx;
263         int                             active_oncpu;
264         int                             max_pertask;
265         int                             exclusive;
266 };
267
268 /*
269  * Set by architecture code:
270  */
271 extern int perf_max_counters;
272
273 #ifdef CONFIG_PERF_COUNTERS
274 extern const struct hw_perf_counter_ops *
275 hw_perf_counter_init(struct perf_counter *counter);
276
277 extern void perf_counter_task_sched_in(struct task_struct *task, int cpu);
278 extern void perf_counter_task_sched_out(struct task_struct *task, int cpu);
279 extern void perf_counter_task_tick(struct task_struct *task, int cpu);
280 extern void perf_counter_init_task(struct task_struct *child);
281 extern void perf_counter_exit_task(struct task_struct *child);
282 extern void perf_counter_notify(struct pt_regs *regs);
283 extern void perf_counter_print_debug(void);
284 extern void perf_counter_unthrottle(void);
285 extern u64 hw_perf_save_disable(void);
286 extern void hw_perf_restore(u64 ctrl);
287 extern int perf_counter_task_disable(void);
288 extern int perf_counter_task_enable(void);
289 extern int hw_perf_group_sched_in(struct perf_counter *group_leader,
290                struct perf_cpu_context *cpuctx,
291                struct perf_counter_context *ctx, int cpu);
292
293 /*
294  * Return 1 for a software counter, 0 for a hardware counter
295  */
296 static inline int is_software_counter(struct perf_counter *counter)
297 {
298         return !counter->hw_event.raw && counter->hw_event.type < 0;
299 }
300
301 extern void perf_swcounter_event(enum hw_event_types, u64, int, struct pt_regs *);
302
303 #else
304 static inline void
305 perf_counter_task_sched_in(struct task_struct *task, int cpu)           { }
306 static inline void
307 perf_counter_task_sched_out(struct task_struct *task, int cpu)          { }
308 static inline void
309 perf_counter_task_tick(struct task_struct *task, int cpu)               { }
310 static inline void perf_counter_init_task(struct task_struct *child)    { }
311 static inline void perf_counter_exit_task(struct task_struct *child)    { }
312 static inline void perf_counter_notify(struct pt_regs *regs)            { }
313 static inline void perf_counter_print_debug(void)                       { }
314 static inline void perf_counter_unthrottle(void)                        { }
315 static inline void hw_perf_restore(u64 ctrl)                            { }
316 static inline u64 hw_perf_save_disable(void)                  { return 0; }
317 static inline int perf_counter_task_disable(void)       { return -EINVAL; }
318 static inline int perf_counter_task_enable(void)        { return -EINVAL; }
319
320 static inline void perf_swcounter_event(enum hw_event_types event, u64 nr,
321                                         int nmi, struct pt_regs *regs)  { }
322 #endif
323
324 #endif /* __KERNEL__ */
325 #endif /* _LINUX_PERF_COUNTER_H */