mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Aleksandar Rikalo <arikalo@gmail.com>
To: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Aleksandar Rikalo <arikalo@gmail.com>,
	Chao-ying Fu <cfu@wavecomp.com>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Greg Ungerer <gerg@kernel.org>, Hauke Mehrtens <hauke@hauke-m.de>,
	Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>,
	Jiaxun Yang <jiaxun.yang@flygoat.com>,
	linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org,
	Marc Zyngier <maz@kernel.org>,
	Paul Burton <paulburton@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Serge Semin <fancer.lancer@gmail.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Tiezhu Yang <yangtiezhu@loongson.cn>,
	Gregory CLEMENT <gregory.clement@bootlin.com>
Subject: [PATCH v7 05/12] clocksource: mips-gic-timer: Always use cluster 0 counter as clocksource
Date: Sat, 19 Oct 2024 09:10:30 +0200	[thread overview]
Message-ID: <20241019071037.145314-6-arikalo@gmail.com> (raw)
In-Reply-To: <20241019071037.145314-1-arikalo@gmail.com>

From: Paul Burton <paulburton@kernel.org>

In a multi-cluster MIPS system, there are multiple GICs - one in each
cluster - each of which has its independent counter. The counters in
each GIC are not synchronized in any way, so they can drift relative
to one another through the lifetime of the system. This is problematic
for a clock source which ought to be global.

Avoid problems by always accessing cluster 0's counter, using
cross-cluster register access. This adds overhead so it is applied only
on multi-cluster systems.

Signed-off-by: Paul Burton <paulburton@kernel.org>
Signed-off-by: Chao-ying Fu <cfu@wavecomp.com>
Signed-off-by: Dragan Mladjenovic <dragan.mladjenovic@syrmia.com>
Signed-off-by: Aleksandar Rikalo <arikalo@gmail.com>
Tested-by: Serge Semin <fancer.lancer@gmail.com>
---
 drivers/clocksource/mips-gic-timer.c | 39 +++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 110347707ff9..7907b740497a 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -166,6 +166,37 @@ static u64 gic_hpt_read(struct clocksource *cs)
 	return gic_read_count();
 }
 
+static u64 gic_hpt_read_multicluster(struct clocksource *cs)
+{
+	unsigned int hi, hi2, lo;
+	u64 count;
+
+	mips_cm_lock_other(0, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL);
+
+	if (mips_cm_is64) {
+		count = read_gic_redir_counter();
+		goto out;
+	}
+
+	hi = read_gic_redir_counter_32h();
+	while (true) {
+		lo = read_gic_redir_counter_32l();
+
+		/* If hi didn't change then lo didn't wrap & we're done */
+		hi2 = read_gic_redir_counter_32h();
+		if (hi2 == hi)
+			break;
+
+		/* Otherwise, repeat with the latest hi value */
+		hi = hi2;
+	}
+
+	count = (((u64)hi) << 32) + lo;
+out:
+	mips_cm_unlock_other();
+	return count;
+}
+
 static struct clocksource gic_clocksource = {
 	.name			= "GIC",
 	.read			= gic_hpt_read,
@@ -203,6 +234,11 @@ static int __init __gic_clocksource_init(void)
 		gic_clocksource.rating = 200;
 	gic_clocksource.rating += clamp(gic_frequency / 10000000, 0, 99);
 
+	if (mips_cps_multicluster_cpus()) {
+		gic_clocksource.read = &gic_hpt_read_multicluster;
+		gic_clocksource.vdso_clock_mode = VDSO_CLOCKMODE_NONE;
+	}
+
 	ret = clocksource_register_hz(&gic_clocksource, gic_frequency);
 	if (ret < 0)
 		pr_warn("Unable to register clocksource\n");
@@ -261,7 +297,8 @@ static int __init gic_clocksource_of_init(struct device_node *node)
 	 * stable CPU frequency or on the platforms with CM3 and CPU frequency
 	 * change performed by the CPC core clocks divider.
 	 */
-	if (mips_cm_revision() >= CM_REV_CM3 || !IS_ENABLED(CONFIG_CPU_FREQ)) {
+	if ((mips_cm_revision() >= CM_REV_CM3 || !IS_ENABLED(CONFIG_CPU_FREQ)) &&
+	     !mips_cps_multicluster_cpus()) {
 		sched_clock_register(mips_cm_is64 ?
 				     gic_read_count_64 : gic_read_count_2x32,
 				     gic_count_width, gic_frequency);
-- 
2.25.1


  parent reply	other threads:[~2024-10-19  7:10 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-19  7:10 [PATCH v7 00/12] MIPS: Support I6500 multi-cluster configuration Aleksandar Rikalo
2024-10-19  7:10 ` [PATCH v7 01/12] irqchip/mips-gic: Introduce for_each_online_cpu_gic() Aleksandar Rikalo
2024-10-19  7:10 ` [PATCH v7 02/12] irqchip/mips-gic: Support multi-cluster in for_each_online_cpu_gic() Aleksandar Rikalo
2024-10-25 22:17   ` Thomas Gleixner
2024-10-19  7:10 ` [PATCH v7 03/12] irqchip/mips-gic: Setup defaults in each cluster Aleksandar Rikalo
2024-10-19  7:10 ` [PATCH v7 04/12] irqchip/mips-gic: Multi-cluster support Aleksandar Rikalo
2024-10-19  7:10 ` Aleksandar Rikalo [this message]
2024-10-28 14:54   ` [PATCH v7 05/12] clocksource: mips-gic-timer: Always use cluster 0 counter as clocksource Daniel Lezcano
2024-10-28 15:15     ` Thomas Bogendoerfer
2024-10-28 15:22       ` Daniel Lezcano
2024-10-28 15:47         ` Thomas Bogendoerfer
2024-10-28 16:09   ` Daniel Lezcano
2024-11-13 20:20   ` [tip: timers/core] clocksource/drivers/mips-gic-timer: " tip-bot2 for Paul Burton
2024-10-19  7:10 ` [PATCH v7 06/12] clocksource: mips-gic-timer: Enable counter when CPUs start Aleksandar Rikalo
2024-10-19  7:10 ` [PATCH v7 07/12] MIPS: pm-cps: Use per-CPU variables as per-CPU, not per-core Aleksandar Rikalo
2024-10-19  7:10 ` [PATCH v7 08/12] MIPS: CPS: Introduce struct cluster_boot_config Aleksandar Rikalo
2024-10-19  7:10 ` [PATCH v7 09/12] MIPS: CPS: Boot CPUs in secondary clusters Aleksandar Rikalo
2024-10-19  7:10 ` [PATCH v7 10/12] dt-bindings: mips: cpu: Add property for broken HCI information Aleksandar Rikalo
2024-10-21  6:10   ` Krzysztof Kozlowski
2024-10-19  7:10 ` [PATCH v7 11/12] MIPS: CPS: Support broken HCI for multicluster Aleksandar Rikalo
2024-10-19  7:10 ` [PATCH v7 12/12] MIPS: mobileye: dts: eyeq6h: Enable cluster support Aleksandar Rikalo
2024-10-25 15:07 ` [PATCH v7 00/12] MIPS: Support I6500 multi-cluster configuration Gregory CLEMENT
2024-10-25 15:58   ` Gregory CLEMENT
     [not found]   ` <CAGQJe6pywUi8dnhxFopkMfP2U1PceHjTPX-CysT0bajSk_AKKg@mail.gmail.com>
2024-10-28 13:39     ` Gregory CLEMENT

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=20241019071037.145314-6-arikalo@gmail.com \
    --to=arikalo@gmail.com \
    --cc=cfu@wavecomp.com \
    --cc=daniel.lezcano@linaro.org \
    --cc=fancer.lancer@gmail.com \
    --cc=geert@linux-m68k.org \
    --cc=gerg@kernel.org \
    --cc=gregory.clement@bootlin.com \
    --cc=hauke@hauke-m.de \
    --cc=ilya.lipnitskiy@gmail.com \
    --cc=jiaxun.yang@flygoat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=paulburton@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=tsbogend@alpha.franken.de \
    --cc=yangtiezhu@loongson.cn \
    /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

all inboxes | Powered by JetHome®