diff options
Diffstat (limited to 'include/linux/perf_event.h')
-rw-r--r-- | include/linux/perf_event.h | 71 |
1 files changed, 67 insertions, 4 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 64426b71381f..5fc494f4a094 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -129,11 +129,40 @@ enum perf_event_sample_format { | |||
129 | PERF_SAMPLE_PERIOD = 1U << 8, | 129 | PERF_SAMPLE_PERIOD = 1U << 8, |
130 | PERF_SAMPLE_STREAM_ID = 1U << 9, | 130 | PERF_SAMPLE_STREAM_ID = 1U << 9, |
131 | PERF_SAMPLE_RAW = 1U << 10, | 131 | PERF_SAMPLE_RAW = 1U << 10, |
132 | PERF_SAMPLE_BRANCH_STACK = 1U << 11, | ||
132 | 133 | ||
133 | PERF_SAMPLE_MAX = 1U << 11, /* non-ABI */ | 134 | PERF_SAMPLE_MAX = 1U << 12, /* non-ABI */ |
134 | }; | 135 | }; |
135 | 136 | ||
136 | /* | 137 | /* |
138 | * values to program into branch_sample_type when PERF_SAMPLE_BRANCH is set | ||
139 | * | ||
140 | * If the user does not pass priv level information via branch_sample_type, | ||
141 | * the kernel uses the event's priv level. Branch and event priv levels do | ||
142 | * not have to match. Branch priv level is checked for permissions. | ||
143 | * | ||
144 | * The branch types can be combined, however BRANCH_ANY covers all types | ||
145 | * of branches and therefore it supersedes all the other types. | ||
146 | */ | ||
147 | enum perf_branch_sample_type { | ||
148 | PERF_SAMPLE_BRANCH_USER = 1U << 0, /* user branches */ | ||
149 | PERF_SAMPLE_BRANCH_KERNEL = 1U << 1, /* kernel branches */ | ||
150 | PERF_SAMPLE_BRANCH_HV = 1U << 2, /* hypervisor branches */ | ||
151 | |||
152 | PERF_SAMPLE_BRANCH_ANY = 1U << 3, /* any branch types */ | ||
153 | PERF_SAMPLE_BRANCH_ANY_CALL = 1U << 4, /* any call branch */ | ||
154 | PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << 5, /* any return branch */ | ||
155 | PERF_SAMPLE_BRANCH_IND_CALL = 1U << 6, /* indirect calls */ | ||
156 | |||
157 | PERF_SAMPLE_BRANCH_MAX = 1U << 7, /* non-ABI */ | ||
158 | }; | ||
159 | |||
160 | #define PERF_SAMPLE_BRANCH_PLM_ALL \ | ||
161 | (PERF_SAMPLE_BRANCH_USER|\ | ||
162 | PERF_SAMPLE_BRANCH_KERNEL|\ | ||
163 | PERF_SAMPLE_BRANCH_HV) | ||
164 | |||
165 | /* | ||
137 | * The format of the data returned by read() on a perf event fd, | 166 | * The format of the data returned by read() on a perf event fd, |
138 | * as specified by attr.read_format: | 167 | * as specified by attr.read_format: |
139 | * | 168 | * |
@@ -240,6 +269,7 @@ struct perf_event_attr { | |||
240 | __u64 bp_len; | 269 | __u64 bp_len; |
241 | __u64 config2; /* extension of config1 */ | 270 | __u64 config2; /* extension of config1 */ |
242 | }; | 271 | }; |
272 | __u64 branch_sample_type; /* enum branch_sample_type */ | ||
243 | }; | 273 | }; |
244 | 274 | ||
245 | /* | 275 | /* |
@@ -458,6 +488,8 @@ enum perf_event_type { | |||
458 | * | 488 | * |
459 | * { u32 size; | 489 | * { u32 size; |
460 | * char data[size];}&& PERF_SAMPLE_RAW | 490 | * char data[size];}&& PERF_SAMPLE_RAW |
491 | * | ||
492 | * { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK | ||
461 | * }; | 493 | * }; |
462 | */ | 494 | */ |
463 | PERF_RECORD_SAMPLE = 9, | 495 | PERF_RECORD_SAMPLE = 9, |
@@ -530,12 +562,34 @@ struct perf_raw_record { | |||
530 | void *data; | 562 | void *data; |
531 | }; | 563 | }; |
532 | 564 | ||
565 | /* | ||
566 | * single taken branch record layout: | ||
567 | * | ||
568 | * from: source instruction (may not always be a branch insn) | ||
569 | * to: branch target | ||
570 | * mispred: branch target was mispredicted | ||
571 | * predicted: branch target was predicted | ||
572 | * | ||
573 | * support for mispred, predicted is optional. In case it | ||
574 | * is not supported mispred = predicted = 0. | ||
575 | */ | ||
533 | struct perf_branch_entry { | 576 | struct perf_branch_entry { |
534 | __u64 from; | 577 | __u64 from; |
535 | __u64 to; | 578 | __u64 to; |
536 | __u64 flags; | 579 | __u64 mispred:1, /* target mispredicted */ |
580 | predicted:1,/* target predicted */ | ||
581 | reserved:62; | ||
537 | }; | 582 | }; |
538 | 583 | ||
584 | /* | ||
585 | * branch stack layout: | ||
586 | * nr: number of taken branches stored in entries[] | ||
587 | * | ||
588 | * Note that nr can vary from sample to sample | ||
589 | * branches (to, from) are stored from most recent | ||
590 | * to least recent, i.e., entries[0] contains the most | ||
591 | * recent branch. | ||
592 | */ | ||
539 | struct perf_branch_stack { | 593 | struct perf_branch_stack { |
540 | __u64 nr; | 594 | __u64 nr; |
541 | struct perf_branch_entry entries[0]; | 595 | struct perf_branch_entry entries[0]; |
@@ -566,7 +620,9 @@ struct hw_perf_event { | |||
566 | unsigned long event_base; | 620 | unsigned long event_base; |
567 | int idx; | 621 | int idx; |
568 | int last_cpu; | 622 | int last_cpu; |
623 | |||
569 | struct hw_perf_event_extra extra_reg; | 624 | struct hw_perf_event_extra extra_reg; |
625 | struct hw_perf_event_extra branch_reg; | ||
570 | }; | 626 | }; |
571 | struct { /* software */ | 627 | struct { /* software */ |
572 | struct hrtimer hrtimer; | 628 | struct hrtimer hrtimer; |
@@ -1007,12 +1063,14 @@ struct perf_sample_data { | |||
1007 | u64 period; | 1063 | u64 period; |
1008 | struct perf_callchain_entry *callchain; | 1064 | struct perf_callchain_entry *callchain; |
1009 | struct perf_raw_record *raw; | 1065 | struct perf_raw_record *raw; |
1066 | struct perf_branch_stack *br_stack; | ||
1010 | }; | 1067 | }; |
1011 | 1068 | ||
1012 | static inline void perf_sample_data_init(struct perf_sample_data *data, u64 addr) | 1069 | static inline void perf_sample_data_init(struct perf_sample_data *data, u64 addr) |
1013 | { | 1070 | { |
1014 | data->addr = addr; | 1071 | data->addr = addr; |
1015 | data->raw = NULL; | 1072 | data->raw = NULL; |
1073 | data->br_stack = NULL; | ||
1016 | } | 1074 | } |
1017 | 1075 | ||
1018 | extern void perf_output_sample(struct perf_output_handle *handle, | 1076 | extern void perf_output_sample(struct perf_output_handle *handle, |
@@ -1151,6 +1209,11 @@ extern void perf_bp_event(struct perf_event *event, void *data); | |||
1151 | # define perf_instruction_pointer(regs) instruction_pointer(regs) | 1209 | # define perf_instruction_pointer(regs) instruction_pointer(regs) |
1152 | #endif | 1210 | #endif |
1153 | 1211 | ||
1212 | static inline bool has_branch_stack(struct perf_event *event) | ||
1213 | { | ||
1214 | return event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK; | ||
1215 | } | ||
1216 | |||
1154 | extern int perf_output_begin(struct perf_output_handle *handle, | 1217 | extern int perf_output_begin(struct perf_output_handle *handle, |
1155 | struct perf_event *event, unsigned int size); | 1218 | struct perf_event *event, unsigned int size); |
1156 | extern void perf_output_end(struct perf_output_handle *handle); | 1219 | extern void perf_output_end(struct perf_output_handle *handle); |