Re: [PATCH v2 2/9] perf/cxl: Clear stale event fields before reprogramming a counter
Dave Jiang <[email protected]> Thu, 30 Jul 2026 08:45:05 -0700
| Newsgroups | org.kernel.vger.linux-cxl,org.kernel.vger.linux-perf-users |
|---|---|
| Message-ID | <[email protected]> |
On 7/29/26 3:25 PM, Jonathan Cameron wrote: > On Wed, 29 Jul 2026 07:55:48 -0700 > Dave Jiang <[email protected]> wrote: > >> cxl_pmu_event_start() ORs the event group id, event mask, edge and invert >> selections into a configurable counter's config register without clearing >> those fields first, and cxl_pmu_event_stop() leaves them set. Reusing a >> counter for another event therefore ORs the new selection onto the old, >> counting the wrong events with stale edge/invert behaviour. >> >> Clear EVENT_GRP_ID_IDX, EVENTS, EDGE and INVERT before applying the new >> values. > > Maybe use FIELD_MODIFY() instead of mask then fill? Will do DJ > > Otherwise LGTM. > >> >> Fixes: 5d7107c72796 ("perf: CXL Performance Monitoring Unit driver") >> Reported-by: [email protected] >> Closes: https://sashiko.dev/#/patchset/[email protected]?part=1 >> Assisted-by: Claude:claude-opus-4-8 >> Signed-off-by: Dave Jiang <[email protected]> >> --- >> drivers/perf/cxl_pmu.c | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c >> index e77c0650a7eb..3138514157cd 100644 >> --- a/drivers/perf/cxl_pmu.c >> +++ b/drivers/perf/cxl_pmu.c >> @@ -641,6 +641,7 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags) >> } >> >> cfg = readq(base + CXL_PMU_COUNTER_CFG_REG(hwc->idx)); >> + cfg &= ~(CXL_PMU_COUNTER_CFG_EDGE | CXL_PMU_COUNTER_CFG_INVERT); >> cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_INT_ON_OVRFLW, 1); >> cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_FREEZE_ON_OVRFLW, 1); >> cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_ENABLE, 1); >> @@ -651,6 +652,8 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags) >> >> /* Fixed purpose counters have next two fields RO */ >> if (test_bit(hwc->idx, info->conf_counter_bm)) { >> + cfg &= ~(CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK | >> + CXL_PMU_COUNTER_CFG_EVENTS_MSK); >> cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK, >> hwc->event_base); >> cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_EVENTS_MSK, >