Skip to content

Commit f4e2bd9

Browse files
Xu Yangwilldeacon
authored andcommitted
perf/imx_ddr: don't enable counter0 if none of 4 counters are used
In current driver, counter0 will be enabled after ddr_perf_pmu_enable() is called even though none of the 4 counters are used. This will cause counter0 continue to count until ddr_perf_pmu_disabled() is called. If pmu is not disabled all the time, the pmu interrupt will be asserted from time to time due to counter0 will overflow and irq handler will clear it. It's not an expected behavior. This patch will not enable counter0 if none of 4 counters are used. Fixes: 9a66d36 ("drivers/perf: imx_ddr: Add DDR performance counter support to perf") Signed-off-by: Xu Yang <xu.yang_2@nxp.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://lore.kernel.org/r/20230811015438.1999307-2-xu.yang_2@nxp.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent e89ecd8 commit f4e2bd9

File tree

1 file changed

+9
-15
lines changed

1 file changed

+9
-15
lines changed

drivers/perf/fsl_imx8_ddr_perf.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ struct ddr_pmu {
104104
const struct fsl_ddr_devtype_data *devtype_data;
105105
int irq;
106106
int id;
107+
int active_counter;
107108
};
108109

109110
static ssize_t ddr_perf_identifier_show(struct device *dev,
@@ -515,6 +516,10 @@ static void ddr_perf_event_start(struct perf_event *event, int flags)
515516

516517
ddr_perf_counter_enable(pmu, event->attr.config, counter, true);
517518

519+
if (!pmu->active_counter++)
520+
ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID,
521+
EVENT_CYCLES_COUNTER, true);
522+
518523
hwc->state = 0;
519524
}
520525

@@ -568,6 +573,10 @@ static void ddr_perf_event_stop(struct perf_event *event, int flags)
568573
ddr_perf_counter_enable(pmu, event->attr.config, counter, false);
569574
ddr_perf_event_update(event);
570575

576+
if (!--pmu->active_counter)
577+
ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID,
578+
EVENT_CYCLES_COUNTER, false);
579+
571580
hwc->state |= PERF_HES_STOPPED;
572581
}
573582

@@ -585,25 +594,10 @@ static void ddr_perf_event_del(struct perf_event *event, int flags)
585594

586595
static void ddr_perf_pmu_enable(struct pmu *pmu)
587596
{
588-
struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu);
589-
590-
/* enable cycle counter if cycle is not active event list */
591-
if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL)
592-
ddr_perf_counter_enable(ddr_pmu,
593-
EVENT_CYCLES_ID,
594-
EVENT_CYCLES_COUNTER,
595-
true);
596597
}
597598

598599
static void ddr_perf_pmu_disable(struct pmu *pmu)
599600
{
600-
struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu);
601-
602-
if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL)
603-
ddr_perf_counter_enable(ddr_pmu,
604-
EVENT_CYCLES_ID,
605-
EVENT_CYCLES_COUNTER,
606-
false);
607601
}
608602

609603
static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,

0 commit comments

Comments
 (0)