Skip to content

Commit 3f9a1b3

Browse files
Stephane EranianPeter Zijlstra
authored andcommitted
perf/x86/amd/lbr: Adjust LBR regardless of filtering
In case of fused compare and taken branch instructions, the AMD LBR points to the compare instruction instead of the branch. Users of LBR usually expects the from address to point to a branch instruction. The kernel has code to adjust the from address via get_branch_type_fused(). However this correction is only applied when a branch filter is applied. That means that if no filter is present, the quality of the data is lower. Fix the problem by applying the adjustment regardless of the filter setting, bringing the AMD LBR to the same level as other LBR implementations. Fixes: 245268c ("perf/x86/amd/lbr: Use fusion-aware branch classifier") Signed-off-by: Stephane Eranian <eranian@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Sandipan Das <sandipan.das@amd.com> Link: https://lore.kernel.org/r/20220928184043.408364-3-eranian@google.com
1 parent 117ceeb commit 3f9a1b3

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

arch/x86/events/amd/lbr.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,13 @@ static void amd_pmu_lbr_filter(void)
9999
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
100100
int br_sel = cpuc->br_sel, offset, type, i, j;
101101
bool compress = false;
102+
bool fused_only = false;
102103
u64 from, to;
103104

104105
/* If sampling all branches, there is nothing to filter */
105106
if (((br_sel & X86_BR_ALL) == X86_BR_ALL) &&
106107
((br_sel & X86_BR_TYPE_SAVE) != X86_BR_TYPE_SAVE))
107-
return;
108+
fused_only = true;
108109

109110
for (i = 0; i < cpuc->lbr_stack.nr; i++) {
110111
from = cpuc->lbr_entries[i].from;
@@ -116,8 +117,11 @@ static void amd_pmu_lbr_filter(void)
116117
* fusion where it points to an instruction preceding the
117118
* actual branch
118119
*/
119-
if (offset)
120+
if (offset) {
120121
cpuc->lbr_entries[i].from += offset;
122+
if (fused_only)
123+
continue;
124+
}
121125

122126
/* If type does not correspond, then discard */
123127
if (type == X86_BR_NONE || (br_sel & type) != type) {

0 commit comments

Comments
 (0)