* [Patch v4 1/5] perf/x86: Disable LBR if x86_pmu.lbr_nr exceeds MAX_LBR_ENTRIES
2026-10-21 5:07 [Patch v4 0/5] perf/x86: Limit branch snapshots to valid entries Dapeng Mi
@ 2026-10-21 5:07 ` Dapeng Mi
2026-10-21 5:07 ` [Patch v4 2/5] perf/x86/amd/lbr: Limit branch snapshots to valid entries Dapeng Mi
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Dapeng Mi @ 2026-10-21 5:07 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane, Sandipan Das, Andrii Nakryiko,
Song Liu, Ravi Bangoria, Ananth Narayan
Cc: linux-kernel, linux-perf-users, bpf, Dapeng Mi, Zide Chen,
Falcon Thomas, Xudong Hao, Dapeng Mi
Disable LBR if x86_pmu.lbr_nr is larger than MAX_LBR_ENTRIES, preventing
out-of-bounds access in the cached LBR stack handling path.
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/events/core.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 4df792b139e0..002a04c149c2 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2645,6 +2645,12 @@ static int __init init_hw_perf_events(void)
if (!x86_pmu.config_mask)
x86_pmu.config_mask = X86_RAW_EVENT_MASK;
+ if (x86_pmu.lbr_nr > MAX_LBR_ENTRIES) {
+ pr_warn("LBR entries %d exceeds max %d, disable LBR.\n",
+ x86_pmu.lbr_nr, MAX_LBR_ENTRIES);
+ x86_pmu.lbr_nr = 0;
+ }
+
perf_events_lapic_init();
register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [Patch v4 2/5] perf/x86/amd/lbr: Limit branch snapshots to valid entries
2026-10-21 5:07 [Patch v4 0/5] perf/x86: Limit branch snapshots to valid entries Dapeng Mi
2026-10-21 5:07 ` [Patch v4 1/5] perf/x86: Disable LBR if x86_pmu.lbr_nr exceeds MAX_LBR_ENTRIES Dapeng Mi
@ 2026-10-21 5:07 ` Dapeng Mi
2026-10-21 5:07 ` [Patch v4 3/5] perf/x86/intel/lbr: Reset the cached LBR stack in intel_pmu_lbr_reset() Dapeng Mi
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Dapeng Mi @ 2026-10-21 5:07 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane, Sandipan Das, Andrii Nakryiko,
Song Liu, Ravi Bangoria, Ananth Narayan
Cc: linux-kernel, linux-perf-users, bpf, Dapeng Mi, Zide Chen,
Falcon Thomas, Xudong Hao, Sashiko, Dapeng Mi
From: Sandipan Das <sandipan.das@amd.com>
The branch snapshot callback used by bpf_get_branch_snapshot() copies
up to x86_pmu.lbr_nr entries from cpuc->lbr_entries[], even when the
last LBR read kept fewer branches. The entries past lbr_stack.nr are
invalid, but they end up reaching BPF programs.
Limit copying to lbr_stack.nr entries and also reset lbr_stack.nr when
amd_pmu_lbr_read() skips reading the registers, so that a stale count
is never reused.
Fixes: a4d18112e531 ("perf/x86/amd: Support capturing LBR from software events")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/sashiko-outbox-163130@kernel.org/
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/events/amd/core.c | 2 +-
arch/x86/events/amd/lbr.c | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
index 49b6b8fce566..bf631f60757c 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
@@ -944,7 +944,7 @@ static int amd_pmu_v2_snapshot_branch_stack(struct perf_branch_entry *entries, u
cpuc = this_cpu_ptr(&cpu_hw_events);
amd_pmu_lbr_read();
- cnt = min(cnt, x86_pmu.lbr_nr);
+ cnt = min(cnt, cpuc->lbr_stack.nr);
memcpy(entries, cpuc->lbr_entries, sizeof(struct perf_branch_entry) * cnt);
amd_pmu_v2_enable_all(0);
diff --git a/arch/x86/events/amd/lbr.c b/arch/x86/events/amd/lbr.c
index a55646fcb846..6c93b8042c73 100644
--- a/arch/x86/events/amd/lbr.c
+++ b/arch/x86/events/amd/lbr.c
@@ -168,8 +168,10 @@ void amd_pmu_lbr_read(void)
struct branch_entry entry;
int out = 0, idx, i;
- if (!cpuc->lbr_users)
+ if (!cpuc->lbr_users) {
+ cpuc->lbr_stack.nr = 0;
return;
+ }
for (i = 0; i < x86_pmu.lbr_nr; i++) {
entry.from.full = amd_pmu_lbr_get_from(i);
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [Patch v4 3/5] perf/x86/intel/lbr: Reset the cached LBR stack in intel_pmu_lbr_reset()
2026-10-21 5:07 [Patch v4 0/5] perf/x86: Limit branch snapshots to valid entries Dapeng Mi
2026-10-21 5:07 ` [Patch v4 1/5] perf/x86: Disable LBR if x86_pmu.lbr_nr exceeds MAX_LBR_ENTRIES Dapeng Mi
2026-10-21 5:07 ` [Patch v4 2/5] perf/x86/amd/lbr: Limit branch snapshots to valid entries Dapeng Mi
@ 2026-10-21 5:07 ` Dapeng Mi
2026-10-21 5:07 ` [Patch v4 4/5] perf/x86/intel/lbr: Limit branch snapshots to valid entries Dapeng Mi
2026-10-21 5:07 ` [Patch v4 5/5] pef/x86/intel: Always snapshot live hardware LBR state for BPF path Dapeng Mi
4 siblings, 0 replies; 7+ messages in thread
From: Dapeng Mi @ 2026-10-21 5:07 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane, Sandipan Das, Andrii Nakryiko,
Song Liu, Ravi Bangoria, Ananth Narayan
Cc: linux-kernel, linux-perf-users, bpf, Dapeng Mi, Zide Chen,
Falcon Thomas, Xudong Hao, Dapeng Mi
Reset the cached LBR stack in addition to the hardware LBR register file
when intel_pmu_lbr_reset() is called. This prevents stale LBR data from
being reused after a context switch or similar transition.
Also adjust intel_pmu_arch_lbr_read_xsave() to update the cached LBR
stack only when new hardware LBR data is present.
Fixes: c085fb877467 ("perf/x86/intel/lbr: Support XSAVES for arch LBR read")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/events/intel/lbr.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 0b446d8912e4..c7e295db9410 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -193,6 +193,8 @@ void intel_pmu_lbr_reset(void)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ cpuc->lbr_stack.nr = 0;
+
if (!x86_pmu.lbr_nr)
return;
@@ -1012,7 +1014,10 @@ static void intel_pmu_arch_lbr_read_xsave(struct cpu_hw_events *cpuc)
}
xsaves(&xsave->xsave, XFEATURE_MASK_LBR);
- intel_pmu_store_lbr(cpuc, xsave->lbr.entries);
+ if (xsave->header.xfeatures & XFEATURE_MASK_LBR)
+ intel_pmu_store_lbr(cpuc, xsave->lbr.entries);
+ else
+ cpuc->lbr_stack.nr = 0;
}
void intel_pmu_lbr_read(void)
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [Patch v4 4/5] perf/x86/intel/lbr: Limit branch snapshots to valid entries
2026-10-21 5:07 [Patch v4 0/5] perf/x86: Limit branch snapshots to valid entries Dapeng Mi
` (2 preceding siblings ...)
2026-10-21 5:07 ` [Patch v4 3/5] perf/x86/intel/lbr: Reset the cached LBR stack in intel_pmu_lbr_reset() Dapeng Mi
@ 2026-10-21 5:07 ` Dapeng Mi
2026-10-21 5:07 ` [Patch v4 5/5] pef/x86/intel: Always snapshot live hardware LBR state for BPF path Dapeng Mi
4 siblings, 0 replies; 7+ messages in thread
From: Dapeng Mi @ 2026-10-21 5:07 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane, Sandipan Das, Andrii Nakryiko,
Song Liu, Ravi Bangoria, Ananth Narayan
Cc: linux-kernel, linux-perf-users, bpf, Dapeng Mi, Zide Chen,
Falcon Thomas, Xudong Hao, Dapeng Mi, Sashiko
The branch snapshot callback used by bpf_get_branch_snapshot() always
copies x86_pmu.lbr_nr entries from cpuc->lbr_entries[], even when the
last LBR read kept fewer branches. The entries past lbr_stack.nr hold
invalid branches which end up reaching BPF programs.
Limit copying to lbr_stack.nr entries and also reset lbr_stack.nr when
no active LBR events or LBR hardware is owned by guest. So the stale or
guest LBR stack data can't be leaked.
For the case where all LBR events are PEBS events, hardware LBR reads are
currently skipped; that can leave stale LBR stack data from previous PEBS
sampling in place and may be inconsistent with the intended semantics of
bpf_get_branch_snapshot(). This will be addressed in a follow-up patch.
Fixes: c22ac2a3d4bd ("perf: Enable branch record for software events")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/sashiko-outbox-163130@kernel.org/
Co-developed-by: Sandipan Das <sandipan.das@amd.com>
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/events/intel/core.c | 2 +-
arch/x86/events/intel/lbr.c | 9 +++++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 0a34d674df59..5dfb9e9156e8 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2822,7 +2822,7 @@ __intel_pmu_snapshot_branch_stack(struct perf_branch_entry *entries,
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
intel_pmu_lbr_read();
- cnt = min_t(unsigned int, cnt, x86_pmu.lbr_nr);
+ cnt = min_t(unsigned int, cnt, cpuc->lbr_stack.nr);
memcpy(entries, cpuc->lbr_entries, sizeof(struct perf_branch_entry) * cnt);
intel_pmu_enable_all(0);
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index c7e295db9410..ac1759a71288 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1024,14 +1024,19 @@ void intel_pmu_lbr_read(void)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ if (!cpuc->lbr_users || vlbr_exclude_host()) {
+ /* Reset lbr_stack.nr to prevent stale data leakage. */
+ cpuc->lbr_stack.nr = 0;
+ 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 || vlbr_exclude_host() ||
- cpuc->lbr_users == cpuc->lbr_pebs_users)
+ if (cpuc->lbr_users == cpuc->lbr_pebs_users)
return;
x86_pmu.lbr_read(cpuc);
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [Patch v4 5/5] pef/x86/intel: Always snapshot live hardware LBR state for BPF path
2026-10-21 5:07 [Patch v4 0/5] perf/x86: Limit branch snapshots to valid entries Dapeng Mi
` (3 preceding siblings ...)
2026-10-21 5:07 ` [Patch v4 4/5] perf/x86/intel/lbr: Limit branch snapshots to valid entries Dapeng Mi
@ 2026-10-21 5:07 ` Dapeng Mi
2026-10-21 6:59 ` Mi, Dapeng
4 siblings, 1 reply; 7+ messages in thread
From: Dapeng Mi @ 2026-10-21 5:07 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane, Sandipan Das, Andrii Nakryiko,
Song Liu, Ravi Bangoria, Ananth Narayan
Cc: linux-kernel, linux-perf-users, bpf, Dapeng Mi, Zide Chen,
Falcon Thomas, Xudong Hao, Dapeng Mi
__intel_pmu_snapshot_branch_stack() is meant to snapshot the current
runtime LBR state from hardware for the BPF path. However, stale cached
PEBS LBR data can be snapshotted instead when a PEBS LBR user is active.
Fix this by always snapshotting the live hardware LBR state, regardless
of whether a PEBS LBR user is active. Reading the runtime LBR registers
can overwrite the cached PEBS LBR stack, so save and restore the cached
PEBS LBR state around the snapshot. This preserves the PEBS LBR data for
later output to userspace in the normal PEBS record path.
Fixes: c22ac2a3d4bd ("perf: Enable branch record for software events")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/events/intel/core.c | 43 ++++++++++++++++++++++++++++++++++--
arch/x86/events/intel/lbr.c | 9 --------
2 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 5dfb9e9156e8..07d1a8a7845b 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2815,16 +2815,50 @@ static void intel_pmu_enable_all(int added)
__intel_pmu_enable_all(added, false);
}
+struct lbr_snapshot {
+ struct perf_branch_stack stack;
+ struct perf_branch_entry entries[MAX_LBR_ENTRIES];
+ u64 counters[MAX_LBR_ENTRIES];
+};
+static DEFINE_PER_CPU(struct lbr_snapshot, lbr_snapshot);
+
static noinline int
__intel_pmu_snapshot_branch_stack(struct perf_branch_entry *entries,
unsigned int cnt, unsigned long flags)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct lbr_snapshot *snapshot = this_cpu_ptr(&lbr_snapshot);
+
+ /*
+ * This may be called from bpf_event_handler() in a PMI context. If
+ * a PEBS LBR user is active, the PEBS sample record has already updated
+ * cpuc->lbr_stack. Reading the LBR registers here would overwrite that
+ * cached PEBS LBR stack, so save it first and restore it afterward. This
+ * keeps the cached LBR data available for later output to userspace in
+ * the normal PEBS record path.
+ */
+ if (cpuc->lbr_pebs_users) {
+ memcpy(&snapshot->stack, &cpuc->lbr_stack,
+ sizeof(struct perf_branch_stack));
+ memcpy(snapshot->entries, cpuc->lbr_entries,
+ sizeof(struct perf_branch_entry) * cpuc->lbr_stack.nr);
+ memcpy(snapshot->counters, cpuc->lbr_counters,
+ sizeof(u64) * cpuc->lbr_stack.nr);
+ }
intel_pmu_lbr_read();
cnt = min_t(unsigned int, cnt, cpuc->lbr_stack.nr);
-
memcpy(entries, cpuc->lbr_entries, sizeof(struct perf_branch_entry) * cnt);
+
+ if (cpuc->lbr_pebs_users) {
+ memcpy(&cpuc->lbr_stack, &snapshot->stack,
+ sizeof(struct perf_branch_stack));
+ memcpy(cpuc->lbr_entries, snapshot->entries,
+ sizeof(struct perf_branch_entry) * cpuc->lbr_stack.nr);
+ memcpy(cpuc->lbr_counters, snapshot->counters,
+ sizeof(u64) * cpuc->lbr_stack.nr);
+ }
+
intel_pmu_enable_all(0);
local_irq_restore(flags);
return cnt;
@@ -4022,7 +4056,12 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
loops = 0;
again:
- intel_pmu_lbr_read();
+ /*
+ * 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();
intel_pmu_ack_status(status);
if (++loops > 100) {
static bool warned;
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index ac1759a71288..07b32255e48d 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1030,15 +1030,6 @@ void intel_pmu_lbr_read(void)
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);
intel_pmu_lbr_filter(cpuc);
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [Patch v4 5/5] pef/x86/intel: Always snapshot live hardware LBR state for BPF path
2026-10-21 5:07 ` [Patch v4 5/5] pef/x86/intel: Always snapshot live hardware LBR state for BPF path Dapeng Mi
@ 2026-10-21 6:59 ` Mi, Dapeng
0 siblings, 0 replies; 7+ messages in thread
From: Mi, Dapeng @ 2026-10-21 6:59 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane, Sandipan Das, Andrii Nakryiko,
Song Liu, Ravi Bangoria, Ananth Narayan
Cc: linux-kernel, linux-perf-users, bpf, Dapeng Mi, Zide Chen,
Falcon Thomas, Xudong Hao
Sashiko found several new long-standing LBR issues (not caused by the patch
series), https://lore.kernel.org/all/sashiko-outbox-179823@kernel.org/
Would post new patch series to fix the newly found issues. Thanks.
On 10/21/2026 1:07 PM, Dapeng Mi wrote:
> __intel_pmu_snapshot_branch_stack() is meant to snapshot the current
> runtime LBR state from hardware for the BPF path. However, stale cached
> PEBS LBR data can be snapshotted instead when a PEBS LBR user is active.
>
> Fix this by always snapshotting the live hardware LBR state, regardless
> of whether a PEBS LBR user is active. Reading the runtime LBR registers
> can overwrite the cached PEBS LBR stack, so save and restore the cached
> PEBS LBR state around the snapshot. This preserves the PEBS LBR data for
> later output to userspace in the normal PEBS record path.
>
> Fixes: c22ac2a3d4bd ("perf: Enable branch record for software events")
> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> ---
> arch/x86/events/intel/core.c | 43 ++++++++++++++++++++++++++++++++++--
> arch/x86/events/intel/lbr.c | 9 --------
> 2 files changed, 41 insertions(+), 11 deletions(-)
>
> diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
> index 5dfb9e9156e8..07d1a8a7845b 100644
> --- a/arch/x86/events/intel/core.c
> +++ b/arch/x86/events/intel/core.c
> @@ -2815,16 +2815,50 @@ static void intel_pmu_enable_all(int added)
> __intel_pmu_enable_all(added, false);
> }
>
> +struct lbr_snapshot {
> + struct perf_branch_stack stack;
> + struct perf_branch_entry entries[MAX_LBR_ENTRIES];
> + u64 counters[MAX_LBR_ENTRIES];
> +};
> +static DEFINE_PER_CPU(struct lbr_snapshot, lbr_snapshot);
> +
> static noinline int
> __intel_pmu_snapshot_branch_stack(struct perf_branch_entry *entries,
> unsigned int cnt, unsigned long flags)
> {
> struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
> + struct lbr_snapshot *snapshot = this_cpu_ptr(&lbr_snapshot);
> +
> + /*
> + * This may be called from bpf_event_handler() in a PMI context. If
> + * a PEBS LBR user is active, the PEBS sample record has already updated
> + * cpuc->lbr_stack. Reading the LBR registers here would overwrite that
> + * cached PEBS LBR stack, so save it first and restore it afterward. This
> + * keeps the cached LBR data available for later output to userspace in
> + * the normal PEBS record path.
> + */
> + if (cpuc->lbr_pebs_users) {
> + memcpy(&snapshot->stack, &cpuc->lbr_stack,
> + sizeof(struct perf_branch_stack));
> + memcpy(snapshot->entries, cpuc->lbr_entries,
> + sizeof(struct perf_branch_entry) * cpuc->lbr_stack.nr);
> + memcpy(snapshot->counters, cpuc->lbr_counters,
> + sizeof(u64) * cpuc->lbr_stack.nr);
> + }
>
> intel_pmu_lbr_read();
> cnt = min_t(unsigned int, cnt, cpuc->lbr_stack.nr);
> -
> memcpy(entries, cpuc->lbr_entries, sizeof(struct perf_branch_entry) * cnt);
> +
> + if (cpuc->lbr_pebs_users) {
> + memcpy(&cpuc->lbr_stack, &snapshot->stack,
> + sizeof(struct perf_branch_stack));
> + memcpy(cpuc->lbr_entries, snapshot->entries,
> + sizeof(struct perf_branch_entry) * cpuc->lbr_stack.nr);
> + memcpy(cpuc->lbr_counters, snapshot->counters,
> + sizeof(u64) * cpuc->lbr_stack.nr);
> + }
> +
> intel_pmu_enable_all(0);
> local_irq_restore(flags);
> return cnt;
> @@ -4022,7 +4056,12 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
>
> loops = 0;
> again:
> - intel_pmu_lbr_read();
> + /*
> + * 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();
> intel_pmu_ack_status(status);
> if (++loops > 100) {
> static bool warned;
> diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
> index ac1759a71288..07b32255e48d 100644
> --- a/arch/x86/events/intel/lbr.c
> +++ b/arch/x86/events/intel/lbr.c
> @@ -1030,15 +1030,6 @@ void intel_pmu_lbr_read(void)
> 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);
>
> intel_pmu_lbr_filter(cpuc);
^ permalink raw reply [flat|nested] 7+ messages in thread