diff options
-rw-r--r-- | tools/perf/util/auxtrace.c | 136 | ||||
-rw-r--r-- | tools/perf/util/auxtrace.h | 43 | ||||
-rw-r--r-- | tools/perf/util/session.h | 2 |
3 files changed, 181 insertions, 0 deletions
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 2cafea2ec015..db40d6c6c010 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include "event.h" | 38 | #include "event.h" |
39 | #include "debug.h" | 39 | #include "debug.h" |
40 | #include "parse-options.h" | ||
40 | 41 | ||
41 | int auxtrace_mmap__mmap(struct auxtrace_mmap *mm, | 42 | int auxtrace_mmap__mmap(struct auxtrace_mmap *mm, |
42 | struct auxtrace_mmap_params *mp, | 43 | struct auxtrace_mmap_params *mp, |
@@ -200,6 +201,141 @@ out_free: | |||
200 | return err; | 201 | return err; |
201 | } | 202 | } |
202 | 203 | ||
204 | #define PERF_ITRACE_DEFAULT_PERIOD_TYPE PERF_ITRACE_PERIOD_NANOSECS | ||
205 | #define PERF_ITRACE_DEFAULT_PERIOD 100000 | ||
206 | #define PERF_ITRACE_DEFAULT_CALLCHAIN_SZ 16 | ||
207 | #define PERF_ITRACE_MAX_CALLCHAIN_SZ 1024 | ||
208 | |||
209 | void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts) | ||
210 | { | ||
211 | synth_opts->instructions = true; | ||
212 | synth_opts->branches = true; | ||
213 | synth_opts->errors = true; | ||
214 | synth_opts->period_type = PERF_ITRACE_DEFAULT_PERIOD_TYPE; | ||
215 | synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD; | ||
216 | synth_opts->callchain_sz = PERF_ITRACE_DEFAULT_CALLCHAIN_SZ; | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * Please check tools/perf/Documentation/perf-script.txt for information | ||
221 | * about the options parsed here, which is introduced after this cset, | ||
222 | * when support in 'perf script' for these options is introduced. | ||
223 | */ | ||
224 | int itrace_parse_synth_opts(const struct option *opt, const char *str, | ||
225 | int unset) | ||
226 | { | ||
227 | struct itrace_synth_opts *synth_opts = opt->value; | ||
228 | const char *p; | ||
229 | char *endptr; | ||
230 | |||
231 | synth_opts->set = true; | ||
232 | |||
233 | if (unset) { | ||
234 | synth_opts->dont_decode = true; | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | if (!str) { | ||
239 | itrace_synth_opts__set_default(synth_opts); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | for (p = str; *p;) { | ||
244 | switch (*p++) { | ||
245 | case 'i': | ||
246 | synth_opts->instructions = true; | ||
247 | while (*p == ' ' || *p == ',') | ||
248 | p += 1; | ||
249 | if (isdigit(*p)) { | ||
250 | synth_opts->period = strtoull(p, &endptr, 10); | ||
251 | p = endptr; | ||
252 | while (*p == ' ' || *p == ',') | ||
253 | p += 1; | ||
254 | switch (*p++) { | ||
255 | case 'i': | ||
256 | synth_opts->period_type = | ||
257 | PERF_ITRACE_PERIOD_INSTRUCTIONS; | ||
258 | break; | ||
259 | case 't': | ||
260 | synth_opts->period_type = | ||
261 | PERF_ITRACE_PERIOD_TICKS; | ||
262 | break; | ||
263 | case 'm': | ||
264 | synth_opts->period *= 1000; | ||
265 | /* Fall through */ | ||
266 | case 'u': | ||
267 | synth_opts->period *= 1000; | ||
268 | /* Fall through */ | ||
269 | case 'n': | ||
270 | if (*p++ != 's') | ||
271 | goto out_err; | ||
272 | synth_opts->period_type = | ||
273 | PERF_ITRACE_PERIOD_NANOSECS; | ||
274 | break; | ||
275 | case '\0': | ||
276 | goto out; | ||
277 | default: | ||
278 | goto out_err; | ||
279 | } | ||
280 | } | ||
281 | break; | ||
282 | case 'b': | ||
283 | synth_opts->branches = true; | ||
284 | break; | ||
285 | case 'e': | ||
286 | synth_opts->errors = true; | ||
287 | break; | ||
288 | case 'd': | ||
289 | synth_opts->log = true; | ||
290 | break; | ||
291 | case 'c': | ||
292 | synth_opts->branches = true; | ||
293 | synth_opts->calls = true; | ||
294 | break; | ||
295 | case 'r': | ||
296 | synth_opts->branches = true; | ||
297 | synth_opts->returns = true; | ||
298 | break; | ||
299 | case 'g': | ||
300 | synth_opts->instructions = true; | ||
301 | synth_opts->callchain = true; | ||
302 | synth_opts->callchain_sz = | ||
303 | PERF_ITRACE_DEFAULT_CALLCHAIN_SZ; | ||
304 | while (*p == ' ' || *p == ',') | ||
305 | p += 1; | ||
306 | if (isdigit(*p)) { | ||
307 | unsigned int val; | ||
308 | |||
309 | val = strtoul(p, &endptr, 10); | ||
310 | p = endptr; | ||
311 | if (!val || val > PERF_ITRACE_MAX_CALLCHAIN_SZ) | ||
312 | goto out_err; | ||
313 | synth_opts->callchain_sz = val; | ||
314 | } | ||
315 | break; | ||
316 | case ' ': | ||
317 | case ',': | ||
318 | break; | ||
319 | default: | ||
320 | goto out_err; | ||
321 | } | ||
322 | } | ||
323 | out: | ||
324 | if (synth_opts->instructions) { | ||
325 | if (!synth_opts->period_type) | ||
326 | synth_opts->period_type = | ||
327 | PERF_ITRACE_DEFAULT_PERIOD_TYPE; | ||
328 | if (!synth_opts->period) | ||
329 | synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD; | ||
330 | } | ||
331 | |||
332 | return 0; | ||
333 | |||
334 | out_err: | ||
335 | pr_err("Bad Instruction Tracing options '%s'\n", str); | ||
336 | return -EINVAL; | ||
337 | } | ||
338 | |||
203 | int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr, | 339 | int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr, |
204 | struct perf_tool *tool, process_auxtrace_t fn) | 340 | struct perf_tool *tool, process_auxtrace_t fn) |
205 | { | 341 | { |
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 199fc27b3954..6355315a91fb 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h | |||
@@ -29,9 +29,49 @@ union perf_event; | |||
29 | struct perf_session; | 29 | struct perf_session; |
30 | struct perf_evlist; | 30 | struct perf_evlist; |
31 | struct perf_tool; | 31 | struct perf_tool; |
32 | struct option; | ||
32 | struct record_opts; | 33 | struct record_opts; |
33 | struct auxtrace_info_event; | 34 | struct auxtrace_info_event; |
34 | 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 | |||
35 | /** | 75 | /** |
36 | * struct auxtrace - session callbacks to allow AUX area data decoding. | 76 | * struct auxtrace - session callbacks to allow AUX area data decoding. |
37 | * @process_event: lets the decoder see all session events | 77 | * @process_event: lets the decoder see all session events |
@@ -186,6 +226,9 @@ int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, | |||
186 | struct perf_tool *tool, | 226 | struct perf_tool *tool, |
187 | struct perf_session *session, | 227 | struct perf_session *session, |
188 | perf_event__handler_t process); | 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); | ||
189 | 232 | ||
190 | static inline int auxtrace__process_event(struct perf_session *session, | 233 | static inline int auxtrace__process_event(struct perf_session *session, |
191 | union perf_event *event, | 234 | union perf_event *event, |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 8a69d3bfafdf..9ed51353a3d7 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -16,12 +16,14 @@ struct ip_callchain; | |||
16 | struct thread; | 16 | struct thread; |
17 | 17 | ||
18 | struct auxtrace; | 18 | struct auxtrace; |
19 | struct itrace_synth_opts; | ||
19 | 20 | ||
20 | struct perf_session { | 21 | struct perf_session { |
21 | struct perf_header header; | 22 | struct perf_header header; |
22 | struct machines machines; | 23 | struct machines machines; |
23 | struct perf_evlist *evlist; | 24 | struct perf_evlist *evlist; |
24 | struct auxtrace *auxtrace; | 25 | struct auxtrace *auxtrace; |
26 | struct itrace_synth_opts *itrace_synth_opts; | ||
25 | struct trace_event tevent; | 27 | struct trace_event tevent; |
26 | bool repipe; | 28 | bool repipe; |
27 | bool one_mmap; | 29 | bool one_mmap; |