Re: [PATCH v2 2/9] perf/cxl: Clear stale event fields before reprogramming a counter
Jonathan Cameron <[email protected]> Wed, 29 Jul 2026 23:25:29 +0100
| Newsgroups | org.kernel.vger.linux-cxl,org.kernel.vger.linux-perf-users |
|---|---|
| Message-ID | <20260729232529.27d08ff4@jic23-huawei> |
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? 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,