Skip to content

Commit 3d47083

Browse files
Ravi BangoriaPeter Zijlstra
authored andcommitted
perf/amd/ibs: Use interrupt regs ip for stack unwinding
IbsOpRip is recorded when IBS interrupt is triggered. But there is a skid from the time IBS interrupt gets triggered to the time the interrupt is presented to the core. Meanwhile processor would have moved ahead and thus IbsOpRip will be inconsistent with rsp and rbp recorded as part of the interrupt regs. This causes issues while unwinding stack using the ORC unwinder as it needs consistent rip, rsp and rbp. Fix this by using rip from interrupt regs instead of IbsOpRip for stack unwinding. Fixes: ee9f8fc ("x86/unwind: Add the ORC unwinder") Reported-by: Dmitry Monakhov <[email protected]> Suggested-by: Peter Zijlstra <[email protected]> Signed-off-by: Ravi Bangoria <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 7685665 commit 3d47083

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

arch/x86/events/amd/ibs.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,16 @@ static int perf_ibs_init(struct perf_event *event)
304304
hwc->config_base = perf_ibs->msr;
305305
hwc->config = config;
306306

307+
/*
308+
* rip recorded by IbsOpRip will not be consistent with rsp and rbp
309+
* recorded as part of interrupt regs. Thus we need to use rip from
310+
* interrupt regs while unwinding call stack. Setting _EARLY flag
311+
* makes sure we unwind call-stack before perf sample rip is set to
312+
* IbsOpRip.
313+
*/
314+
if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN)
315+
event->attr.sample_type |= __PERF_SAMPLE_CALLCHAIN_EARLY;
316+
307317
return 0;
308318
}
309319

@@ -687,6 +697,14 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
687697
data.raw = &raw;
688698
}
689699

700+
/*
701+
* rip recorded by IbsOpRip will not be consistent with rsp and rbp
702+
* recorded as part of interrupt regs. Thus we need to use rip from
703+
* interrupt regs while unwinding call stack.
704+
*/
705+
if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN)
706+
data.callchain = perf_callchain(event, iregs);
707+
690708
throttle = perf_event_overflow(event, &data, &regs);
691709
out:
692710
if (throttle) {

0 commit comments

Comments
 (0)