diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2010-03-03 07:12:23 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-03-10 07:23:32 -0500 |
commit | ef21f683a045a79b6aa86ad81e5fdfc0d5ddd250 (patch) | |
tree | ccf39f5051608c1eccac9171259c2d7bc381cc96 /arch/x86/include/asm/perf_event.h | |
parent | caff2befffe899e63df5cc760b7ed01cfd902685 (diff) |
perf, x86: use LBR for PEBS IP+1 fixup
Use the LBR to fix up the PEBS IP+1 issue.
As said, PEBS reports the next instruction, here we use the LBR to find
the last branch and from that construct the actual IP. If the IP matches
the LBR-TO, we use LBR-FROM, otherwise we use the LBR-TO address as the
beginning of the last basic block and decode forward.
Once we find a match to the current IP, we use the previous location.
This patch introduces a new ABI element: PERF_RECORD_MISC_EXACT, which
conveys that the reported IP (PERF_SAMPLE_IP) is the exact instruction
that caused the event (barring CPU errata).
The fixup can fail due to various reasons:
1) LBR contains invalid data (quite possible)
2) part of the basic block got paged out
3) the reported IP isn't part of the basic block (see 1)
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: "Zhang, Yanmin" <yanmin_zhang@linux.intel.com>
Cc: paulus@samba.org
Cc: eranian@google.com
Cc: robert.richter@amd.com
Cc: fweisbec@gmail.com
LKML-Reference: <20100304140100.619375431@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/include/asm/perf_event.h')
-rw-r--r-- | arch/x86/include/asm/perf_event.h | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index db6109a885a7..a9038c951619 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h | |||
@@ -136,6 +136,25 @@ extern void perf_events_lapic_init(void); | |||
136 | 136 | ||
137 | #define PERF_EVENT_INDEX_OFFSET 0 | 137 | #define PERF_EVENT_INDEX_OFFSET 0 |
138 | 138 | ||
139 | /* | ||
140 | * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups. | ||
141 | * This flag is otherwise unused and ABI specified to be 0, so nobody should | ||
142 | * care what we do with it. | ||
143 | */ | ||
144 | #define PERF_EFLAGS_EXACT (1UL << 3) | ||
145 | |||
146 | #define perf_misc_flags(regs) \ | ||
147 | ({ int misc = 0; \ | ||
148 | if (user_mode(regs)) \ | ||
149 | misc |= PERF_RECORD_MISC_USER; \ | ||
150 | else \ | ||
151 | misc |= PERF_RECORD_MISC_KERNEL; \ | ||
152 | if (regs->flags & PERF_EFLAGS_EXACT) \ | ||
153 | misc |= PERF_RECORD_MISC_EXACT; \ | ||
154 | misc; }) | ||
155 | |||
156 | #define perf_instruction_pointer(regs) ((regs)->ip) | ||
157 | |||
139 | #else | 158 | #else |
140 | static inline void init_hw_perf_events(void) { } | 159 | static inline void init_hw_perf_events(void) { } |
141 | static inline void perf_events_lapic_init(void) { } | 160 | static inline void perf_events_lapic_init(void) { } |