[Patch v5 12/18] perf/x86/intel: Always snapshot live hardware LBR state for BPF

From: Dapeng Mi

Date: Thu Oct 29 2026 - 00:54:50 EST


__intel_pmu_snapshot_branch_stack() is intended to capture the current
live hardware LBR state for the BPF path. However, that snapshot is
currently skipped when all LBR users are PEBS events.

BPF LBR snapshotting now uses its own dedicated LBR stack, so there is
no longer a risk of clobbering the shared default LBR stack. As a
result, always snapshot the live hardware LBR state for the BPF path.

Fixes: c22ac2a3d4bd ("perf: Enable branch record for software events")
Signed-off-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
---
arch/x86/events/intel/core.c | 10 ++++++++--
arch/x86/events/intel/lbr.c | 9 ---------
2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 482a148916bf..110fff65bd50 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4069,8 +4069,14 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)

loops = 0;
again:
- intel_pmu_lbr_read(&cpuc->lbr_stack,
- cpuc->lbr_entries, cpuc->lbr_counters);
+ /*
+ * No need to read the LBR stack when all LBR users are PEBS events,
+ * since the PEBS handler updates it.
+ */
+ if (cpuc->lbr_users != cpuc->lbr_pebs_users) {
+ intel_pmu_lbr_read(&cpuc->lbr_stack,
+ cpuc->lbr_entries, cpuc->lbr_counters);
+ }

/*
* Do not clear the LBR frozen status here; keep LBR frozen
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 63f0504f9d2a..790580f96040 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1050,15 +1050,6 @@ void intel_pmu_lbr_read(struct perf_branch_stack *lbr_stack,
return;
}

- /*
- * Don't read when all LBRs users are using adaptive PEBS.
- *
- * This could be smarter and actually check the event,
- * but this simple approach seems to work for now.
- */
- if (cpuc->lbr_users == cpuc->lbr_pebs_users)
- return;
-
x86_pmu.lbr_read(cpuc, lbr_stack, lbr_entries);

intel_pmu_lbr_filter(cpuc, lbr_stack, lbr_entries, lbr_counters);
--
2.34.1