Re: [Patch v5 12/18] perf/x86/intel: Always snapshot live hardware LBR state for BPF
From: Peter Zijlstra
Date: Thu Oct 29 2026 - 06:56:41 EST
On Thu, Oct 29, 2026 at 12:39:08PM +0800, Dapeng Mi wrote:
> __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);
AFAICT AMD could be similarly modified, it currently unconditionally
reads the LBR stack, irrespective of lbr_users.