Re: [Patch v2] perf/x86/intel: Prevent drain_pebs() reentry
From: Mi, Dapeng
Date: Wed Sep 09 2026 - 20:08:15 EST
On 9/9/2026 9:03 PM, Peter Zijlstra wrote:
> On Wed, Sep 09, 2026 at 07:09:11PM +0800, Mi, Dapeng wrote:
>> Hi Peter,
>>
>> Could you please review and queue this patch if it's good enough? This
>> version addresses your comments. Thanks.
>>
>>
>> On 8/13/2026 2:43 PM, Dapeng Mi wrote:
>>> The PEBS buffer is shared by all events on a CPU, so drain_pebs() must
>>> not be reentered. If so, one instance may observe stale buffer state and
>>> potentially access out-of-bound memory.
>>>
>>> Most invocations happen in NMI context, which naturally prevents reentry.
>>> However, drain_pebs() is also reachable from process context via
>>> intel_pmu_drain_pebs_buffer().
>>>
>>> In those paths, the PMU is often already disabled, but not guaranteed.
>>> For example, __intel_pmu_pebs_disable() only disables the target counter,
>>> so other active counters can still raise a PMI and interrupt an in-flight
>>> drain_pebs(). Here is an example,
>>>
>>> __perf_addr_filters_adjust()
>>> perf_event_stop()
>>> __perf_event_stop()
>>> x86_pmu_stop() (event->pmu->stop)
>>> intel_pmu_disable_event()
>>> intel_pmu_pebs_disable()
>>> __intel_pmu_pebs_disable()
>>> intel_pmu_drain_large_pebs()
>>> intel_pmu_drain_pebs_buffer()
>>>
>>> Introduce __intel_pmu_quiesce() and __intel_pmu_resume() helpers and
>>> use them in intel_pmu_drain_large_pebs() to disable the full PMU
>>> around the intel_pmu_drain_pebs_buffer() call, preventing reentry.
>>>
>>> Also add a warning in intel_pmu_drain_pebs_buffer() when the full PMU is
>>> not disabled.
>>>
>>> Signed-off-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
> Ah yes. Can you get me a Fixes tag to go with this?
Sure. Here it is. Thanks.
Fixes: b752ea0c28e3 ("perf/x86/intel/ds: Flush PEBS DS when changing
PEBS_DATA_CFG")