From: sashiko-bot@kernel.org
To: "Vladimir Kondratiev" <vladimir.kondratiev@mobileye.com>
Cc: linux-rt-devel@lists.linux.dev, devicetree@vger.kernel.org,
linux-perf-users@vger.kernel.org, robh@kernel.org,
conor+dt@kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 5/6] perf: add MIPS Coherence Manager 3 (CM3) PMU driver
Date: Thu, 12 Nov 2026 13:02:13 +0000 [thread overview]
Message-ID: <sashiko-outbox-211133@kernel.org> (raw)
In-Reply-To: <20261112-i6500-cm3-pmu-v2-5-cd2569571819@mobileye.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] perf: mips_cm3_pmu: counter overflow double-counting in
cm3_pmu_update()
- [Low] perf: mips_cm3_pmu: broken !MIPS_CPS / !SMP configuration
--
commit 272d1a9241643c479b7f4cabbd1c40edccbe1b16
Author: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
perf: add MIPS Coherence Manager 3 (CM3) PMU driver
This commit adds an uncore PMU driver and documentation for the MIPS
Coherence Manager 3 (CM3) performance and cycle counters.
> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
> index 245e7bb763b99..2dbed2fc7b030 100644
> --- a/drivers/perf/Kconfig
> +++ b/drivers/perf/Kconfig
> @@ -75,6 +75,18 @@ config ARM_XSCALE_PMU
> depends on ARM_PMU && CPU_XSCALE
> def_bool y
>
> +config MIPS_CM3_PMU
> + tristate "MIPS Coherence Manager 3 (CM3) PMU"
> + depends on MIPS_CM
[Severity: Low]
Should MIPS_CM3_PMU depend on MIPS_CPS rather than MIPS_CM?
MIPS_GIC selects MIPS_CM even when CONFIG_MIPS_CPS=n and CONFIG_SMP=n.
On a !CONFIG_SMP build, irq_set_affinity() is a stub returning -EINVAL, so
cm3_pmu_online_cpu() unconditionally triggers WARN_ON() when an overflow
IRQ is present; without CONFIG_MIPS_CPS, cps_smp_setup() also never
populates the cluster ID in cpu_data[].globalnumber.
> diff --git a/drivers/perf/mips_cm3_pmu.c b/drivers/perf/mips_cm3_pmu.c
> new file mode 100644
> index 0000000000000..6d53535473b96
> --- /dev/null
> +++ b/drivers/perf/mips_cm3_pmu.c
[ ... ]
> +static void cm3_pmu_update(struct perf_event *event)
> +{
> + struct cm3_pmu *cm3_pmu = to_cm3_pmu(event->pmu);
> + struct hw_perf_event *hwc = &event->hw;
> + u32 ov_bit = cm3_pmu_overflow_bit(hwc->idx);
> + u64 delta, prev, new;
> + bool overflowed = false;
> +
> + /* Counts were harvested when the cluster went down, nothing since */
> + if (READ_ONCE(cm3_pmu->paused))
> + return;
> +
> + /*
> + * When polling, the counter cannot wrap twice between two reads and
> + * the 32-bit difference tells the whole story. With the overflow
> + * interrupt the counter is only read on demand and may have made a
> + * full turn since the last read, which the overflow status tells.
> + * It is read and cleared before the counter so that a wrap seen
> + * here is also reflected in the counter value; a wrap happening in
> + * between is accounted by the next update, which the interrupt it
> + * raises makes sure happens. In interrupt mode every access to the
> + * event runs on cm3_pmu->on_cpu with interrupts disabled, so the
> + * status and the counter are read consistently.
> + */
> + if (cm3_pmu->irq > 0) {
> + overflowed = CM3_PMU_READ(cm3_pmu, pc_ov) & ov_bit;
> + if (overflowed)
> + CM3_PMU_WRITE(cm3_pmu, pc_ov, ov_bit);
> + }
> +
> + do {
> + prev = local64_read(&hwc->prev_count);
> + new = cm3_pmu_read_counter(cm3_pmu, hwc->idx);
> + } while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev);
> +
> + /*
> + * If the counter wrapped and now shows a value not below the
> + * previous one, it made a full turn on top of the 32-bit difference.
> + */
> + delta = (new - prev) & CM3_PMU_COUNTER_MASK;
> + if (overflowed && new >= prev)
> + delta += CM3_PMU_COUNTER_MASK + 1;
> +
> + local64_add(delta, &event->count);
> +}
[Severity: Medium]
Can cm3_pmu_update() double-count a counter wrap in interrupt mode and
inflate event->count by 2^32?
If hwc->prev_count holds a non-zero value prev and the counter wraps to a
small value (new < prev) between reading pc_ov and reading the counter,
the first cm3_pmu_update() sees overflowed == false, updates prev_count to
new, and already accounts for the wrap in (new - prev) &
CM3_PMU_COUNTER_MASK while leaving ov_bit set in pc_ov. When the pending
overflow interrupt then runs cm3_pmu_update(), it sees overflowed == true
with the counter >= the new prev_count and adds CM3_PMU_COUNTER_MASK + 1 a
second time.
Similarly, because the hardware sets ov_bit when the counter reaches
0xffffffff rather than when it wraps to 0, handling the interrupt or
reading the event while the counter is still at 0xffffffff satisfies
overflowed && new >= prev, adding 2^32 before the wrap to 0 adds 1 on the
next update.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112-i6500-cm3-pmu-v2-0-cd2569571819@mobileye.com?part=5
next prev parent reply other threads:[~2026-11-12 13:02 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 12:28 [PATCH v2 0/6] perf: add PMU driver for the MIPS Coherence Manager 3 performance counters Vladimir Kondratiev
2026-11-12 12:28 ` [PATCH v2 1/6] MIPS: CM: Make cm_core_lock raw spinlocks Vladimir Kondratiev
2026-11-12 12:39 ` sashiko-bot
2026-11-12 12:28 ` [PATCH v2 2/6] MIPS: CM: add CM3 performance counter GCR definitions Vladimir Kondratiev
2026-11-12 12:33 ` sashiko-bot
2026-11-12 12:29 ` [PATCH v2 3/6] MIPS: CM: export the symbols needed to access the GCRs from a module Vladimir Kondratiev
2026-11-12 12:31 ` sashiko-bot
2026-11-12 12:29 ` [PATCH v2 4/6] dt-bindings: mips: mti,mips-cm: add performance counter interrupt Vladimir Kondratiev
2026-11-12 12:32 ` sashiko-bot
2026-11-12 12:29 ` [PATCH v2 5/6] perf: add MIPS Coherence Manager 3 (CM3) PMU driver Vladimir Kondratiev
2026-11-12 13:02 ` sashiko-bot [this message]
2026-11-12 12:29 ` [PATCH v2 6/6] MIPS: eyeq6_defconfig: enable the CM3 PMU Vladimir Kondratiev
2026-11-12 12:35 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-211133@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vladimir.kondratiev@mobileye.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.