OSDN Git Service

perf session: Add instruction tracing options
[uclinux-h8/linux.git] / tools / perf / util / auxtrace.h
1 /*
2  * auxtrace.h: AUX area trace support
3  * Copyright (c) 2013-2015, Intel Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  */
15
16 #ifndef __PERF_AUXTRACE_H
17 #define __PERF_AUXTRACE_H
18
19 #include <sys/types.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <linux/perf_event.h>
23 #include <linux/types.h>
24
25 #include "../perf.h"
26 #include "session.h"
27
28 union perf_event;
29 struct perf_session;
30 struct perf_evlist;
31 struct perf_tool;
32 struct option;
33 struct record_opts;
34 struct auxtrace_info_event;
35
36 enum itrace_period_type {
37         PERF_ITRACE_PERIOD_INSTRUCTIONS,
38         PERF_ITRACE_PERIOD_TICKS,
39         PERF_ITRACE_PERIOD_NANOSECS,
40 };
41
42 /**
43  * struct itrace_synth_opts - AUX area tracing synthesis options.
44  * @set: indicates whether or not options have been set
45  * @inject: indicates the event (not just the sample) must be fully synthesized
46  *          because 'perf inject' will write it out
47  * @instructions: whether to synthesize 'instructions' events
48  * @branches: whether to synthesize 'branches' events
49  * @errors: whether to synthesize decoder error events
50  * @dont_decode: whether to skip decoding entirely
51  * @log: write a decoding log
52  * @calls: limit branch samples to calls (can be combined with @returns)
53  * @returns: limit branch samples to returns (can be combined with @calls)
54  * @callchain: add callchain to 'instructions' events
55  * @callchain_sz: maximum callchain size
56  * @period: 'instructions' events period
57  * @period_type: 'instructions' events period type
58  */
59 struct itrace_synth_opts {
60         bool                    set;
61         bool                    inject;
62         bool                    instructions;
63         bool                    branches;
64         bool                    errors;
65         bool                    dont_decode;
66         bool                    log;
67         bool                    calls;
68         bool                    returns;
69         bool                    callchain;
70         unsigned int            callchain_sz;
71         unsigned long long      period;
72         enum itrace_period_type period_type;
73 };
74
75 /**
76  * struct auxtrace - session callbacks to allow AUX area data decoding.
77  * @process_event: lets the decoder see all session events
78  * @flush_events: process any remaining data
79  * @free_events: free resources associated with event processing
80  * @free: free resources associated with the session
81  */
82 struct auxtrace {
83         int (*process_event)(struct perf_session *session,
84                              union perf_event *event,
85                              struct perf_sample *sample,
86                              struct perf_tool *tool);
87         int (*flush_events)(struct perf_session *session,
88                             struct perf_tool *tool);
89         void (*free_events)(struct perf_session *session);
90         void (*free)(struct perf_session *session);
91 };
92
93 /**
94  * struct auxtrace_mmap - records an mmap of the auxtrace buffer.
95  * @base: address of mapped area
96  * @userpg: pointer to buffer's perf_event_mmap_page
97  * @mask: %0 if @len is not a power of two, otherwise (@len - %1)
98  * @len: size of mapped area
99  * @prev: previous aux_head
100  * @idx: index of this mmap
101  * @tid: tid for a per-thread mmap (also set if there is only 1 tid on a per-cpu
102  *       mmap) otherwise %0
103  * @cpu: cpu number for a per-cpu mmap otherwise %-1
104  */
105 struct auxtrace_mmap {
106         void            *base;
107         void            *userpg;
108         size_t          mask;
109         size_t          len;
110         u64             prev;
111         int             idx;
112         pid_t           tid;
113         int             cpu;
114 };
115
116 /**
117  * struct auxtrace_mmap_params - parameters to set up struct auxtrace_mmap.
118  * @mask: %0 if @len is not a power of two, otherwise (@len - %1)
119  * @offset: file offset of mapped area
120  * @len: size of mapped area
121  * @prot: mmap memory protection
122  * @idx: index of this mmap
123  * @tid: tid for a per-thread mmap (also set if there is only 1 tid on a per-cpu
124  *       mmap) otherwise %0
125  * @cpu: cpu number for a per-cpu mmap otherwise %-1
126  */
127 struct auxtrace_mmap_params {
128         size_t          mask;
129         off_t           offset;
130         size_t          len;
131         int             prot;
132         int             idx;
133         pid_t           tid;
134         int             cpu;
135 };
136
137 /**
138  * struct auxtrace_record - callbacks for recording AUX area data.
139  * @recording_options: validate and process recording options
140  * @info_priv_size: return the size of the private data in auxtrace_info_event
141  * @info_fill: fill-in the private data in auxtrace_info_event
142  * @free: free this auxtrace record structure
143  * @reference: provide a 64-bit reference number for auxtrace_event
144  * @read_finish: called after reading from an auxtrace mmap
145  */
146 struct auxtrace_record {
147         int (*recording_options)(struct auxtrace_record *itr,
148                                  struct perf_evlist *evlist,
149                                  struct record_opts *opts);
150         size_t (*info_priv_size)(struct auxtrace_record *itr);
151         int (*info_fill)(struct auxtrace_record *itr,
152                          struct perf_session *session,
153                          struct auxtrace_info_event *auxtrace_info,
154                          size_t priv_size);
155         void (*free)(struct auxtrace_record *itr);
156         u64 (*reference)(struct auxtrace_record *itr);
157         int (*read_finish)(struct auxtrace_record *itr, int idx);
158 };
159
160 static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
161 {
162         struct perf_event_mmap_page *pc = mm->userpg;
163 #if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)
164         u64 head = ACCESS_ONCE(pc->aux_head);
165 #else
166         u64 head = __sync_val_compare_and_swap(&pc->aux_head, 0, 0);
167 #endif
168
169         /* Ensure all reads are done after we read the head */
170         rmb();
171         return head;
172 }
173
174 static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
175 {
176         struct perf_event_mmap_page *pc = mm->userpg;
177 #if BITS_PER_LONG != 64 && defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)
178         u64 old_tail;
179 #endif
180
181         /* Ensure all reads are done before we write the tail out */
182         mb();
183 #if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)
184         pc->aux_tail = tail;
185 #else
186         do {
187                 old_tail = __sync_val_compare_and_swap(&pc->aux_tail, 0, 0);
188         } while (!__sync_bool_compare_and_swap(&pc->aux_tail, old_tail, tail));
189 #endif
190 }
191
192 int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
193                         struct auxtrace_mmap_params *mp,
194                         void *userpg, int fd);
195 void auxtrace_mmap__munmap(struct auxtrace_mmap *mm);
196 void auxtrace_mmap_params__init(struct auxtrace_mmap_params *mp,
197                                 off_t auxtrace_offset,
198                                 unsigned int auxtrace_pages,
199                                 bool auxtrace_overwrite);
200 void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp,
201                                    struct perf_evlist *evlist, int idx,
202                                    bool per_cpu);
203
204 typedef int (*process_auxtrace_t)(struct perf_tool *tool,
205                                   union perf_event *event, void *data1,
206                                   size_t len1, void *data2, size_t len2);
207
208 int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
209                         struct perf_tool *tool, process_auxtrace_t fn);
210
211 struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
212                                               int *err);
213
214 int auxtrace_record__options(struct auxtrace_record *itr,
215                              struct perf_evlist *evlist,
216                              struct record_opts *opts);
217 size_t auxtrace_record__info_priv_size(struct auxtrace_record *itr);
218 int auxtrace_record__info_fill(struct auxtrace_record *itr,
219                                struct perf_session *session,
220                                struct auxtrace_info_event *auxtrace_info,
221                                size_t priv_size);
222 void auxtrace_record__free(struct auxtrace_record *itr);
223 u64 auxtrace_record__reference(struct auxtrace_record *itr);
224
225 int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr,
226                                          struct perf_tool *tool,
227                                          struct perf_session *session,
228                                          perf_event__handler_t process);
229 int itrace_parse_synth_opts(const struct option *opt, const char *str,
230                             int unset);
231 void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts);
232
233 static inline int auxtrace__process_event(struct perf_session *session,
234                                           union perf_event *event,
235                                           struct perf_sample *sample,
236                                           struct perf_tool *tool)
237 {
238         if (!session->auxtrace)
239                 return 0;
240
241         return session->auxtrace->process_event(session, event, sample, tool);
242 }
243
244 static inline int auxtrace__flush_events(struct perf_session *session,
245                                          struct perf_tool *tool)
246 {
247         if (!session->auxtrace)
248                 return 0;
249
250         return session->auxtrace->flush_events(session, tool);
251 }
252
253 static inline void auxtrace__free_events(struct perf_session *session)
254 {
255         if (!session->auxtrace)
256                 return;
257
258         return session->auxtrace->free_events(session);
259 }
260
261 static inline void auxtrace__free(struct perf_session *session)
262 {
263         if (!session->auxtrace)
264                 return;
265
266         return session->auxtrace->free(session);
267 }
268
269 #endif