Re: [PATCH 1/2] perf/x86/intel: Don't clear perf metrics overflow bit unconditionally

From: Liang, Kan
Date: Tue Apr 15 2025 - 14:48:07 EST




On 2025-04-15 6:41 a.m., Dapeng Mi wrote:
> The below code would always unconditionally clear other status bits like
> perf metrics overflow bit once PEBS buffer overflows.
>
> status &= intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI;
>
> This is incorrect. Perf metrics overflow bit should be cleared only when
> fixed counter 3 in PEBS counter group. Otherwise perf metrics overflow
> could be missed to handle.
>
> Closes: https://lore.kernel.org/all/20250225110012.GK31462@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/
> Fixes: 7b2c05a15d29 ("perf/x86/intel: Generic support for hardware TopDown metrics")
> Signed-off-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>

For the two patches,

Reviewed-by: Kan Liang <kan.liang@xxxxxxxxxxxxxxx>

Thanks,
Kan

> ---
> arch/x86/events/intel/core.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
> index 0ceaa1b07019..c6f69ce3b2b3 100644
> --- a/arch/x86/events/intel/core.c
> +++ b/arch/x86/events/intel/core.c
> @@ -3140,7 +3140,6 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
> struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
> int bit;
> int handled = 0;
> - u64 intel_ctrl = hybrid(cpuc->pmu, intel_ctrl);
>
> inc_irq_stat(apic_perf_irqs);
>
> @@ -3184,7 +3183,6 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
> handled++;
> x86_pmu_handle_guest_pebs(regs, &data);
> static_call(x86_pmu_drain_pebs)(regs, &data);
> - status &= intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI;
>
> /*
> * PMI throttle may be triggered, which stops the PEBS event.
> @@ -3195,6 +3193,15 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
> */
> if (pebs_enabled != cpuc->pebs_enabled)
> wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
> +
> + /*
> + * Above PEBS handler (PEBS counters snapshotting) has updated fixed
> + * counter 3 and perf metrics counts if they are in counter group,
> + * unnecessary to update again.
> + */
> + if (cpuc->events[INTEL_PMC_IDX_FIXED_SLOTS] &&
> + is_pebs_counter_event_group(cpuc->events[INTEL_PMC_IDX_FIXED_SLOTS]))
> + status &= ~GLOBAL_STATUS_PERF_METRICS_OVF_BIT;
> }
>
> /*
> @@ -3214,6 +3221,8 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
> static_call(intel_pmu_update_topdown_event)(NULL, NULL);
> }
>
> + status &= hybrid(cpuc->pmu, intel_ctrl);
> +
> /*
> * Checkpointed counters can lead to 'spurious' PMIs because the
> * rollback caused by the PMI will have cleared the overflow status
>
> base-commit: 5c3627b6f0595f1ec27e6f5df903bd072e9b9136