* [PATCH v4 1/2] MIPS: CPS: Improve mips_cps_first_online_in_cluster()
2025-07-11 9:54 [PATCH v4 0/2] MIPS: CPS: Optimise delay CPU calibration and cluster helper function Gregory CLEMENT
@ 2025-07-11 9:54 ` Gregory CLEMENT
2025-07-11 9:54 ` [PATCH v4 2/2] MIPS: CPS: Optimise delay CPU calibration for SMP Gregory CLEMENT
2025-07-16 18:06 ` [PATCH v4 0/2] MIPS: CPS: Optimise delay CPU calibration and cluster helper function Thomas Bogendoerfer
2 siblings, 0 replies; 4+ messages in thread
From: Gregory CLEMENT @ 2025-07-11 9:54 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Jiaxun Yang, Vladimir Kondratiev, Théo Lebrun, Tawfik Bayouk,
Thomas Petazzoni, linux-mips, linux-kernel, Gregory CLEMENT
The initial implementation of this function goes through all the CPUs
in a cluster to determine if the current CPU is the only one
running. This process occurs every time the function is called.
However, during boot, we already perform this task, so let's take
advantage of this opportunity to create and fill a CPU bitmask that
can be easily and efficiently used later.
This patch modifies the function to allow providing the first
available online CPU when one already exists, which is necessary for
delay CPU calibration optimization.
Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
arch/mips/include/asm/mips-cps.h | 4 +++-
arch/mips/include/asm/smp-cps.h | 1 +
arch/mips/kernel/mips-cm.c | 47 ++++++++++++++--------------------------
arch/mips/kernel/smp-cps.c | 5 ++++-
4 files changed, 24 insertions(+), 33 deletions(-)
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 917009b80e6951dc7e2b308ad7fb42cd9fbbf7d7..1fffd47a4564fb891d3c1e3ae3895b34d6700e5e 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -258,6 +258,8 @@ static inline bool mips_cps_multicluster_cpus(void)
/**
* mips_cps_first_online_in_cluster() - Detect if CPU is first online in cluster
+ * @first_cpu: The first other online CPU in cluster, or nr_cpu_ids if
+ * the function returns true.
*
* Determine whether the local CPU is the first to be brought online in its
* cluster - that is, whether there are any other online CPUs in the local
@@ -265,6 +267,6 @@ static inline bool mips_cps_multicluster_cpus(void)
*
* Returns true if this CPU is first online, else false.
*/
-extern unsigned int mips_cps_first_online_in_cluster(void);
+extern unsigned int mips_cps_first_online_in_cluster(int *first_cpu);
#endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/include/asm/smp-cps.h b/arch/mips/include/asm/smp-cps.h
index 10d3ebd890cb2f3ac2b1db5a541cfe9e7f1a0c99..88cfae5d22c83e44451200ad3daae12fced03303 100644
--- a/arch/mips/include/asm/smp-cps.h
+++ b/arch/mips/include/asm/smp-cps.h
@@ -24,6 +24,7 @@ struct core_boot_config {
struct cluster_boot_config {
unsigned long *core_power;
+ struct cpumask cpumask;
struct core_boot_config *core_config;
};
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 43cb1e20baed3648ff83bb5d3bbe6a726072e063..8c559ad60d92a24a52f314925534fc7e7f6ba290 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -10,6 +10,7 @@
#include <linux/spinlock.h>
#include <asm/mips-cps.h>
+#include <asm/smp-cps.h>
#include <asm/mipsregs.h>
void __iomem *mips_gcr_base;
@@ -529,39 +530,23 @@ void mips_cm_error_report(void)
write_gcr_error_cause(cm_error);
}
-unsigned int mips_cps_first_online_in_cluster(void)
+unsigned int mips_cps_first_online_in_cluster(int *first_cpu)
{
- unsigned int local_cl;
- int i;
-
- local_cl = cpu_cluster(¤t_cpu_data);
+ unsigned int local_cl = cpu_cluster(¤t_cpu_data);
+ struct cpumask *local_cl_mask;
/*
- * We rely upon knowledge that CPUs are numbered sequentially by
- * cluster - ie. CPUs 0..X will be in cluster 0, CPUs X+1..Y in cluster
- * 1, CPUs Y+1..Z in cluster 2 etc. This means that CPUs in the same
- * cluster will immediately precede or follow one another.
- *
- * First we scan backwards, until we find an online CPU in the cluster
- * or we move on to another cluster.
+ * mips_cps_cluster_bootcfg is allocated in cps_prepare_cpus. If it is
+ * not yet done, then we are so early that only one CPU is running, so
+ * it is the first online CPU in the cluster.
*/
- for (i = smp_processor_id() - 1; i >= 0; i--) {
- if (cpu_cluster(&cpu_data[i]) != local_cl)
- break;
- if (!cpu_online(i))
- continue;
- return false;
- }
-
- /* Then do the same for higher numbered CPUs */
- for (i = smp_processor_id() + 1; i < nr_cpu_ids; i++) {
- if (cpu_cluster(&cpu_data[i]) != local_cl)
- break;
- if (!cpu_online(i))
- continue;
- return false;
- }
-
- /* We found no online CPUs in the local cluster */
- return true;
+ if (IS_ENABLED(CONFIG_MIPS_CPS) && mips_cps_cluster_bootcfg)
+ local_cl_mask = &mips_cps_cluster_bootcfg[local_cl].cpumask;
+ else
+ return true;
+
+ *first_cpu = cpumask_any_and_but(local_cl_mask,
+ cpu_online_mask,
+ smp_processor_id());
+ return (*first_cpu >= nr_cpu_ids);
}
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 7b0e69af4097025196b93115139a5e89c1d71fcc..6c5f15293a8e58a701601b242f43ba19a6814f06 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -283,7 +283,7 @@ static void __init cps_smp_setup(void)
static void __init cps_prepare_cpus(unsigned int max_cpus)
{
- unsigned int nclusters, ncores, core_vpes, c, cl, cca;
+ unsigned int nclusters, ncores, core_vpes, nvpe = 0, c, cl, cca;
bool cca_unsuitable, cores_limited;
struct cluster_boot_config *cluster_bootcfg;
struct core_boot_config *core_bootcfg;
@@ -356,10 +356,13 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
/* Allocate VPE boot configuration structs */
for (c = 0; c < ncores; c++) {
+ int v;
core_vpes = core_vpe_count(cl, c);
core_bootcfg[c].vpe_config = kcalloc(core_vpes,
sizeof(*core_bootcfg[c].vpe_config),
GFP_KERNEL);
+ for (v = 0; v < core_vpes; v++)
+ cpumask_set_cpu(nvpe++, &mips_cps_cluster_bootcfg[cl].cpumask);
if (!core_bootcfg[c].vpe_config)
goto err_out;
}
--
2.47.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v4 2/2] MIPS: CPS: Optimise delay CPU calibration for SMP
2025-07-11 9:54 [PATCH v4 0/2] MIPS: CPS: Optimise delay CPU calibration and cluster helper function Gregory CLEMENT
2025-07-11 9:54 ` [PATCH v4 1/2] MIPS: CPS: Improve mips_cps_first_online_in_cluster() Gregory CLEMENT
@ 2025-07-11 9:54 ` Gregory CLEMENT
2025-07-16 18:06 ` [PATCH v4 0/2] MIPS: CPS: Optimise delay CPU calibration and cluster helper function Thomas Bogendoerfer
2 siblings, 0 replies; 4+ messages in thread
From: Gregory CLEMENT @ 2025-07-11 9:54 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Jiaxun Yang, Vladimir Kondratiev, Théo Lebrun, Tawfik Bayouk,
Thomas Petazzoni, linux-mips, linux-kernel, Gregory CLEMENT
On MIPS architecture with CPS-based SMP support, all CPU cores in the
same cluster run at the same frequency since they share the same L2
cache, requiring a fixed CPU/L2 cache ratio.
This allows to implement calibrate_delay_is_known(), which will return
0 (triggering calibration) only for the primary CPU of each
cluster. For other CPUs, we can simply reuse the value from their
cluster's primary CPU core.
With the introduction of this patch, a configuration running 32 cores
spread across two clusters sees a significant reduction in boot time
by approximately 600 milliseconds.
Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
arch/mips/kernel/smp-cps.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 6c5f15293a8e58a701601b242f43ba19a6814f06..22d4f9ff3ae2671b07da5bb149154c686e07b209 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -281,6 +281,17 @@ static void __init cps_smp_setup(void)
#endif /* CONFIG_MIPS_MT_FPAFF */
}
+unsigned long calibrate_delay_is_known(void)
+{
+ int first_cpu_cluster = 0;
+
+ /* The calibration has to be done on the primary CPU of the cluster */
+ if (mips_cps_first_online_in_cluster(&first_cpu_cluster))
+ return 0;
+
+ return cpu_data[first_cpu_cluster].udelay_val;
+}
+
static void __init cps_prepare_cpus(unsigned int max_cpus)
{
unsigned int nclusters, ncores, core_vpes, nvpe = 0, c, cl, cca;
--
2.47.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v4 0/2] MIPS: CPS: Optimise delay CPU calibration and cluster helper function
2025-07-11 9:54 [PATCH v4 0/2] MIPS: CPS: Optimise delay CPU calibration and cluster helper function Gregory CLEMENT
2025-07-11 9:54 ` [PATCH v4 1/2] MIPS: CPS: Improve mips_cps_first_online_in_cluster() Gregory CLEMENT
2025-07-11 9:54 ` [PATCH v4 2/2] MIPS: CPS: Optimise delay CPU calibration for SMP Gregory CLEMENT
@ 2025-07-16 18:06 ` Thomas Bogendoerfer
2 siblings, 0 replies; 4+ messages in thread
From: Thomas Bogendoerfer @ 2025-07-16 18:06 UTC (permalink / raw)
To: Gregory CLEMENT
Cc: Jiaxun Yang, Vladimir Kondratiev, Théo Lebrun, Tawfik Bayouk,
Thomas Petazzoni, linux-mips, linux-kernel
On Fri, Jul 11, 2025 at 11:54:19AM +0200, Gregory CLEMENT wrote:
> This series allow booting faster by reusing the delay calibration
> across the CPU belonging of the same cluster. While doing it we now
> reuse the mips_cps_first_online_in_cluster() that we improve also.
>
> This series enables faster booting by reusing delay calibration across
> CPUs within the same cluster. During this process, we reuse the
> improved mips_cps_first_online_in_cluster function.
>
> With the introduction of this series, a configuration running 32 cores
> spread across two clusters sees a significant reduction in boot time
> by approximately 600 milliseconds.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
> ---
> Changes in v4:
> - Fix build issue reported by kernel test robot <lkp@intel.com>
> at https://lore.kernel.org/all/aG3AJ2XnH2JKOjzY@rli9-mobl/#t
> - Add reviewed-by tags from Jiaxun
> - Link to v3: https://lore.kernel.org/r/20250708-smp_calib-v3-0-6dabf01a7d9f@bootlin.com
>
> Changes in v3:
> - Do not depend anymore of a Kconfig entry (suggested by Jiaxun).
> - cpumask for cluster filled now later in cps_prepare_cpus().
> - Patch 2 of the v2 has been removed.
> - Link to v2: https://lore.kernel.org/r/20250704-smp_calib-v2-0-bade7e9c0463@bootlin.com
>
> Changes in v2:
> - Add a patch improving mips_cps_first_online_in_cluster()
> - Use mips_cps_first_online_in_cluster() in calibrate_delay_is_known()
> as suggested by Jiaxun
> - Link to v1: https://lore.kernel.org/r/20250520-smp_calib-v1-1-cd04f0a78648@bootlin.com
>
> ---
> Gregory CLEMENT (2):
> MIPS: CPS: Improve mips_cps_first_online_in_cluster()
> MIPS: CPS: Optimise delay CPU calibration for SMP
>
> arch/mips/include/asm/mips-cps.h | 4 +++-
> arch/mips/include/asm/smp-cps.h | 1 +
> arch/mips/kernel/mips-cm.c | 47 ++++++++++++++--------------------------
> arch/mips/kernel/smp-cps.c | 16 +++++++++++++-
> 4 files changed, 35 insertions(+), 33 deletions(-)
series applied to mips-next.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 4+ messages in thread