AUX data can be used to annotate perf events such as performance counters or tracepoints/breakpoints by including it in sample records when PERF_SAMPLE_AUX flag is set. Such samples would be instrumental in debugging and profiling by providing, for example, a history of instruction flow leading up to the event's overflow. The implementation makes use of grouping an AUX event with all the events that wish to take samples of the AUX data, such that the former is the group leader. The samplees should also specify the desired size of the AUX sample via attr.aux_sample_size. AUX capable PMUs need to explicitly add support for sampling, because it relies on a new callback to take a snapshot of the buffer without touching the event states.
Showing the changes to include/linux (1 of 5 files). Show all
Unified · Split
| @@ -249,6 +249,8 @@ struct perf_event; · 248 unmodified lines | |||
| 249 | #define PERF_PMU_CAP_NO_EXCLUDE 0x80 | 249 | #define PERF_PMU_CAP_NO_EXCLUDE 0x80 |
| 250 | #define PERF_PMU_CAP_AUX_OUTPUT 0x100 | 250 | #define PERF_PMU_CAP_AUX_OUTPUT 0x100 |
| 251 | 251 | ||
| 252 | struct perf_output_handle; | ||
| 253 | |||
| 252 | /** | 254 | /** |
| 253 | * struct pmu - generic performance monitoring unit | 255 | * struct pmu - generic performance monitoring unit |
| 254 | */ | 256 | */ |
| @@ -432,6 +434,19 @@ struct pmu { · 177 unmodified lines | |||
| 432 | */ | 434 | */ |
| 433 | void (*free_aux) (void *aux); /* optional */ | 435 | void (*free_aux) (void *aux); /* optional */ |
| 434 | 436 | ||
| 437 | /* | ||
| 438 | * Take a snapshot of the AUX buffer without touching the event | ||
| 439 | * state, so that preempting ->start()/->stop() callbacks does | ||
| 440 | * not interfere with their logic. Called in PMI context. | ||
| 441 | * | ||
| 442 | * Returns the size of AUX data copied to the output handle. | ||
| 443 | * | ||
| 444 | * Optional. | ||
| 445 | */ | ||
| 446 | long (*snapshot_aux) (struct perf_event *event, | ||
| 447 | struct perf_output_handle *handle, | ||
| 448 | unsigned long size); | ||
| 449 | |||
| 435 | /* | 450 | /* |
| 436 | * Validate address range filters: make sure the HW supports the | 451 | * Validate address range filters: make sure the HW supports the |
| 437 | * requested configuration and number of filters; return 0 if the | 452 | * requested configuration and number of filters; return 0 if the |
| @@ -973,6 +988,7 @@ struct perf_sample_data { · 535 unmodified lines | |||
| 973 | u32 reserved; | 988 | u32 reserved; |
| 974 | } cpu_entry; | 989 | } cpu_entry; |
| 975 | struct perf_callchain_entry *callchain; | 990 | struct perf_callchain_entry *callchain; |
| 991 | u64 aux_size; | ||
| 976 | 992 | ||
| 977 | /* | 993 | /* |
| 978 | * regs_user may point to task_pt_regs or to regs_user_copy, depending | 994 | * regs_user may point to task_pt_regs or to regs_user_copy, depending |
| @@ -1362,6 +1378,9 @@ extern unsigned int perf_output_copy(struct perf_output_handle *handle, · 383 unmodified lines | |||
| 1362 | const void *buf, unsigned int len); | 1378 | const void *buf, unsigned int len); |
| 1363 | extern unsigned int perf_output_skip(struct perf_output_handle *handle, | 1379 | extern unsigned int perf_output_skip(struct perf_output_handle *handle, |
| 1364 | unsigned int len); | 1380 | unsigned int len); |
| 1381 | extern long perf_output_copy_aux(struct perf_output_handle *aux_handle, | ||
| 1382 | struct perf_output_handle *handle, | ||
| 1383 | unsigned long from, unsigned long to); | ||
| 1365 | extern int perf_swevent_get_recursion_context(void); | 1384 | extern int perf_swevent_get_recursion_context(void); |
| 1366 | extern void perf_swevent_put_recursion_context(int rctx); | 1385 | extern void perf_swevent_put_recursion_context(int rctx); |
| 1367 | extern u64 perf_swevent_set_period(struct perf_event *event); | 1386 | extern u64 perf_swevent_set_period(struct perf_event *event); |