Commit 0bc3be5b authored by Sandipan Das's avatar Sandipan Das Committed by Peter Zijlstra

perf/x86/amd/lbr: Add LbrExtV2 branch speculation info support

Provide branch speculation information captured via AMD Last Branch Record
Extension Version 2 (LbrExtV2) by setting the speculation info in branch
records. The info is based on the "valid" and "spec" bits in the Branch To
registers.
Suggested-by: default avatarStephane Eranian <eranian@google.com>
Signed-off-by: default avatarSandipan Das <sandipan.das@amd.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/ddc02f6320464cad0e3ff5bdb2314531568a91bc.1660211399.git.sandipan.das@amd.com
parent 93315e46
...@@ -146,12 +146,19 @@ static void amd_pmu_lbr_filter(void) ...@@ -146,12 +146,19 @@ static void amd_pmu_lbr_filter(void)
} }
} }
static const int lbr_spec_map[PERF_BR_SPEC_MAX] = {
PERF_BR_SPEC_NA,
PERF_BR_SPEC_WRONG_PATH,
PERF_BR_NON_SPEC_CORRECT_PATH,
PERF_BR_SPEC_CORRECT_PATH,
};
void amd_pmu_lbr_read(void) void amd_pmu_lbr_read(void)
{ {
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct perf_branch_entry *br = cpuc->lbr_entries; struct perf_branch_entry *br = cpuc->lbr_entries;
struct branch_entry entry; struct branch_entry entry;
int out = 0, i; int out = 0, idx, i;
if (!cpuc->lbr_users) if (!cpuc->lbr_users)
return; return;
...@@ -160,8 +167,11 @@ void amd_pmu_lbr_read(void) ...@@ -160,8 +167,11 @@ void amd_pmu_lbr_read(void)
entry.from.full = amd_pmu_lbr_get_from(i); entry.from.full = amd_pmu_lbr_get_from(i);
entry.to.full = amd_pmu_lbr_get_to(i); entry.to.full = amd_pmu_lbr_get_to(i);
/* Check if a branch has been logged */ /*
if (!entry.to.split.valid) * Check if a branch has been logged; if valid = 0, spec = 0
* then no branch was recorded
*/
if (!entry.to.split.valid && !entry.to.split.spec)
continue; continue;
perf_clear_branch_entry_bitfields(br + out); perf_clear_branch_entry_bitfields(br + out);
...@@ -170,6 +180,25 @@ void amd_pmu_lbr_read(void) ...@@ -170,6 +180,25 @@ void amd_pmu_lbr_read(void)
br[out].to = sign_ext_branch_ip(entry.to.split.ip); br[out].to = sign_ext_branch_ip(entry.to.split.ip);
br[out].mispred = entry.from.split.mispredict; br[out].mispred = entry.from.split.mispredict;
br[out].predicted = !br[out].mispred; br[out].predicted = !br[out].mispred;
/*
* Set branch speculation information using the status of
* the valid and spec bits.
*
* When valid = 0, spec = 0, no branch was recorded and the
* entry is discarded as seen above.
*
* When valid = 0, spec = 1, the recorded branch was
* speculative but took the wrong path.
*
* When valid = 1, spec = 0, the recorded branch was
* non-speculative but took the correct path.
*
* When valid = 1, spec = 1, the recorded branch was
* speculative and took the correct path
*/
idx = (entry.to.split.valid << 1) | entry.to.split.spec;
br[out].spec = lbr_spec_map[idx];
out++; out++;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment