Skip to content

Commit 76c43eb

Browse files
gclementtsbogend
authored andcommitted
MIPS: SMP: Implement parallel CPU bring up for EyeQ
Added support for starting CPUs in parallel on EyeQ to speed up boot time. On EyeQ5, booting 8 CPUs is now ~90ms faster. On EyeQ6, booting 32 CPUs is now ~650ms faster. Signed-off-by: Gregory CLEMENT <[email protected]> Signed-off-by: Thomas Bogendoerfer <[email protected]>
1 parent 0f4ae7c commit 76c43eb

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

arch/mips/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ config EYEQ
617617
select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
618618
select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
619619
select USE_OF
620+
select HOTPLUG_PARALLEL if SMP
620621
help
621622
Select this to build a kernel supporting EyeQ SoC from Mobileye.
622623

@@ -2287,6 +2288,7 @@ config MIPS_CPS
22872288
select MIPS_CM
22882289
select MIPS_CPS_PM if HOTPLUG_CPU
22892290
select SMP
2291+
select HOTPLUG_SMT if HOTPLUG_PARALLEL
22902292
select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
22912293
select SYNC_R4K if (CEVT_R4K || CSRC_R4K)
22922294
select SYS_SUPPORTS_HOTPLUG_CPU

arch/mips/include/asm/topology.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#define topology_core_id(cpu) (cpu_core(&cpu_data[cpu]))
1717
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
1818
#define topology_sibling_cpumask(cpu) (&cpu_sibling_map[cpu])
19+
20+
extern struct cpumask __cpu_primary_thread_mask;
21+
#define cpu_primary_thread_mask ((const struct cpumask *)&__cpu_primary_thread_mask)
1922
#endif
2023

2124
#endif /* __ASM_TOPOLOGY_H */

arch/mips/kernel/smp-cps.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ static void __init cps_smp_setup(void)
236236
/* Use the number of VPEs in cluster 0 core 0 for smp_num_siblings */
237237
if (!cl && !c)
238238
smp_num_siblings = core_vpes;
239+
cpumask_set_cpu(nvpes, &__cpu_primary_thread_mask);
239240

240241
for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
241242
cpu_set_cluster(&cpu_data[nvpes + v], cl);
@@ -364,6 +365,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
364365
cl = cpu_cluster(&current_cpu_data);
365366
c = cpu_core(&current_cpu_data);
366367
cluster_bootcfg = &mips_cps_cluster_bootcfg[cl];
368+
cpu_smt_set_num_threads(core_vpes, core_vpes);
367369
core_bootcfg = &cluster_bootcfg->core_config[c];
368370
bitmap_set(cluster_bootcfg->core_power, cpu_core(&current_cpu_data), 1);
369371
atomic_set(&core_bootcfg->vpe_mask, 1 << cpu_vpe_id(&current_cpu_data));

arch/mips/kernel/smp.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ EXPORT_SYMBOL(cpu_sibling_map);
5656
cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
5757
EXPORT_SYMBOL(cpu_core_map);
5858

59+
#ifndef CONFIG_HOTPLUG_PARALLEL
5960
static DECLARE_COMPLETION(cpu_starting);
6061
static DECLARE_COMPLETION(cpu_running);
62+
#endif
6163

6264
/*
6365
* A logical cpu mask containing only one VPE per core to
@@ -74,6 +76,8 @@ static cpumask_t cpu_core_setup_map;
7476

7577
cpumask_t cpu_coherent_mask;
7678

79+
struct cpumask __cpu_primary_thread_mask __read_mostly;
80+
7781
unsigned int smp_max_threads __initdata = UINT_MAX;
7882

7983
static int __init early_nosmt(char *s)
@@ -374,10 +378,15 @@ asmlinkage void start_secondary(void)
374378
set_cpu_core_map(cpu);
375379

376380
cpumask_set_cpu(cpu, &cpu_coherent_mask);
381+
#ifdef CONFIG_HOTPLUG_PARALLEL
382+
cpuhp_ap_sync_alive();
383+
#endif
377384
notify_cpu_starting(cpu);
378385

386+
#ifndef CONFIG_HOTPLUG_PARALLEL
379387
/* Notify boot CPU that we're starting & ready to sync counters */
380388
complete(&cpu_starting);
389+
#endif
381390

382391
synchronise_count_slave(cpu);
383392

@@ -386,11 +395,13 @@ asmlinkage void start_secondary(void)
386395

387396
calculate_cpu_foreign_map();
388397

398+
#ifndef CONFIG_HOTPLUG_PARALLEL
389399
/*
390400
* Notify boot CPU that we're up & online and it can safely return
391401
* from __cpu_up
392402
*/
393403
complete(&cpu_running);
404+
#endif
394405

395406
/*
396407
* irq will be enabled in ->smp_finish(), enabling it too early
@@ -447,6 +458,12 @@ void __init smp_prepare_boot_cpu(void)
447458
set_cpu_online(0, true);
448459
}
449460

461+
#ifdef CONFIG_HOTPLUG_PARALLEL
462+
int arch_cpuhp_kick_ap_alive(unsigned int cpu, struct task_struct *tidle)
463+
{
464+
return mp_ops->boot_secondary(cpu, tidle);
465+
}
466+
#else
450467
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
451468
{
452469
int err;
@@ -466,6 +483,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
466483
wait_for_completion(&cpu_running);
467484
return 0;
468485
}
486+
#endif
469487

470488
#ifdef CONFIG_PROFILING
471489
/* Not really SMP stuff ... */

0 commit comments

Comments
 (0)