Skip to content

Commit c71085f

Browse files
gclementtsbogend
authored andcommitted
MIPS: CPS: Improve mips_cps_first_online_in_cluster()
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 <[email protected]> Signed-off-by: Gregory CLEMENT <[email protected]> Signed-off-by: Thomas Bogendoerfer <[email protected]>
1 parent 07f8888 commit c71085f

File tree

4 files changed

+24
-33
lines changed

4 files changed

+24
-33
lines changed

arch/mips/include/asm/mips-cps.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,15 @@ static inline bool mips_cps_multicluster_cpus(void)
258258

259259
/**
260260
* mips_cps_first_online_in_cluster() - Detect if CPU is first online in cluster
261+
* @first_cpu: The first other online CPU in cluster, or nr_cpu_ids if
262+
* the function returns true.
261263
*
262264
* Determine whether the local CPU is the first to be brought online in its
263265
* cluster - that is, whether there are any other online CPUs in the local
264266
* cluster.
265267
*
266268
* Returns true if this CPU is first online, else false.
267269
*/
268-
extern unsigned int mips_cps_first_online_in_cluster(void);
270+
extern unsigned int mips_cps_first_online_in_cluster(int *first_cpu);
269271

270272
#endif /* __MIPS_ASM_MIPS_CPS_H__ */

arch/mips/include/asm/smp-cps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct core_boot_config {
2424

2525
struct cluster_boot_config {
2626
unsigned long *core_power;
27+
struct cpumask cpumask;
2728
struct core_boot_config *core_config;
2829
};
2930

arch/mips/kernel/mips-cm.c

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/spinlock.h>
1111

1212
#include <asm/mips-cps.h>
13+
#include <asm/smp-cps.h>
1314
#include <asm/mipsregs.h>
1415

1516
void __iomem *mips_gcr_base;
@@ -534,39 +535,23 @@ void mips_cm_error_report(void)
534535
write_gcr_error_cause(cm_error);
535536
}
536537

537-
unsigned int mips_cps_first_online_in_cluster(void)
538+
unsigned int mips_cps_first_online_in_cluster(int *first_cpu)
538539
{
539-
unsigned int local_cl;
540-
int i;
541-
542-
local_cl = cpu_cluster(&current_cpu_data);
540+
unsigned int local_cl = cpu_cluster(&current_cpu_data);
541+
struct cpumask *local_cl_mask;
543542

544543
/*
545-
* We rely upon knowledge that CPUs are numbered sequentially by
546-
* cluster - ie. CPUs 0..X will be in cluster 0, CPUs X+1..Y in cluster
547-
* 1, CPUs Y+1..Z in cluster 2 etc. This means that CPUs in the same
548-
* cluster will immediately precede or follow one another.
549-
*
550-
* First we scan backwards, until we find an online CPU in the cluster
551-
* or we move on to another cluster.
544+
* mips_cps_cluster_bootcfg is allocated in cps_prepare_cpus. If it is
545+
* not yet done, then we are so early that only one CPU is running, so
546+
* it is the first online CPU in the cluster.
552547
*/
553-
for (i = smp_processor_id() - 1; i >= 0; i--) {
554-
if (cpu_cluster(&cpu_data[i]) != local_cl)
555-
break;
556-
if (!cpu_online(i))
557-
continue;
558-
return false;
559-
}
560-
561-
/* Then do the same for higher numbered CPUs */
562-
for (i = smp_processor_id() + 1; i < nr_cpu_ids; i++) {
563-
if (cpu_cluster(&cpu_data[i]) != local_cl)
564-
break;
565-
if (!cpu_online(i))
566-
continue;
567-
return false;
568-
}
569-
570-
/* We found no online CPUs in the local cluster */
571-
return true;
548+
if (IS_ENABLED(CONFIG_MIPS_CPS) && mips_cps_cluster_bootcfg)
549+
local_cl_mask = &mips_cps_cluster_bootcfg[local_cl].cpumask;
550+
else
551+
return true;
552+
553+
*first_cpu = cpumask_any_and_but(local_cl_mask,
554+
cpu_online_mask,
555+
smp_processor_id());
556+
return (*first_cpu >= nr_cpu_ids);
572557
}

arch/mips/kernel/smp-cps.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ static void __init cps_smp_setup(void)
283283

284284
static void __init cps_prepare_cpus(unsigned int max_cpus)
285285
{
286-
unsigned int nclusters, ncores, core_vpes, c, cl, cca;
286+
unsigned int nclusters, ncores, core_vpes, nvpe = 0, c, cl, cca;
287287
bool cca_unsuitable, cores_limited;
288288
struct cluster_boot_config *cluster_bootcfg;
289289
struct core_boot_config *core_bootcfg;
@@ -356,10 +356,13 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
356356

357357
/* Allocate VPE boot configuration structs */
358358
for (c = 0; c < ncores; c++) {
359+
int v;
359360
core_vpes = core_vpe_count(cl, c);
360361
core_bootcfg[c].vpe_config = kcalloc(core_vpes,
361362
sizeof(*core_bootcfg[c].vpe_config),
362363
GFP_KERNEL);
364+
for (v = 0; v < core_vpes; v++)
365+
cpumask_set_cpu(nvpe++, &mips_cps_cluster_bootcfg[cl].cpumask);
363366
if (!core_bootcfg[c].vpe_config)
364367
goto err_out;
365368
}

0 commit comments

Comments
 (0)