devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  reply	other threads:[~2026-11-12 13:02 UTC|newest]

Thread overview: 9+ 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:29 ` [PATCH v2 3/6] MIPS: CM: export the symbols needed to access the GCRs from a module Vladimir Kondratiev
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: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

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).