Index: head/sys/powerpc/include/platform.h =================================================================== --- head/sys/powerpc/include/platform.h +++ head/sys/powerpc/include/platform.h @@ -58,6 +58,7 @@ int platform_smp_start_cpu(struct pcpu *); void platform_smp_timebase_sync(u_long tb, int ap); void platform_smp_ap_init(void); +void platform_smp_probe_threads(void); const char *installed_platform(void); void platform_probe_and_attach(void); Index: head/sys/powerpc/powernv/platform_powernv.c =================================================================== --- head/sys/powerpc/powernv/platform_powernv.c +++ head/sys/powerpc/powernv/platform_powernv.c @@ -71,6 +71,7 @@ static void powernv_smp_ap_init(platform_t); #ifdef SMP static int powernv_smp_start_cpu(platform_t, struct pcpu *cpu); +static void powernv_smp_probe_threads(platform_t); static struct cpu_group *powernv_smp_topo(platform_t plat); #endif static void powernv_reset(platform_t); @@ -89,6 +90,7 @@ PLATFORMMETHOD(platform_smp_get_bsp, powernv_smp_get_bsp), #ifdef SMP PLATFORMMETHOD(platform_smp_start_cpu, powernv_smp_start_cpu), + PLATFORMMETHOD(platform_smp_probe_threads, powernv_smp_probe_threads), PLATFORMMETHOD(platform_smp_topo, powernv_smp_topo), #endif @@ -403,8 +405,8 @@ return (0); } -static struct cpu_group * -powernv_smp_topo(platform_t plat) +static void +powernv_smp_probe_threads(platform_t plat) { char buf[8]; phandle_t cpu, dev, root; @@ -436,21 +438,26 @@ } smp_threads_per_core = nthreads; + if (mp_ncpus % nthreads == 0) + mp_ncores = mp_ncpus / nthreads; +} - if (mp_ncpus % nthreads != 0) { +static struct cpu_group * +powernv_smp_topo(platform_t plat) +{ + if (mp_ncpus % smp_threads_per_core != 0) { printf("WARNING: Irregular SMP topology. Performance may be " "suboptimal (%d threads, %d on first core)\n", - mp_ncpus, nthreads); + mp_ncpus, smp_threads_per_core); return (smp_topo_none()); } - mp_ncores = mp_ncpus / nthreads; - /* Don't do anything fancier for non-threaded SMP */ - if (nthreads == 1) + if (smp_threads_per_core == 1) return (smp_topo_none()); - return (smp_topo_1level(CG_SHARE_L1, nthreads, CG_FLAG_SMT)); + return (smp_topo_1level(CG_SHARE_L1, smp_threads_per_core, + CG_FLAG_SMT)); } #endif Index: head/sys/powerpc/powerpc/mp_machdep.c =================================================================== --- head/sys/powerpc/powerpc/mp_machdep.c +++ head/sys/powerpc/powerpc/mp_machdep.c @@ -188,8 +188,7 @@ } #ifdef SMP - /* Probe mp_ncores and smp_threads_per_core as a side effect. */ - (void)cpu_topo(); + platform_smp_probe_threads(); #endif } Index: head/sys/powerpc/powerpc/platform.c =================================================================== --- head/sys/powerpc/powerpc/platform.c +++ head/sys/powerpc/powerpc/platform.c @@ -242,6 +242,12 @@ PLATFORM_SMP_AP_INIT(plat_obj); } +void +platform_smp_probe_threads(void) +{ + PLATFORM_SMP_PROBE_THREADS(plat_obj); +} + #ifdef SMP struct cpu_group * cpu_topo(void) Index: head/sys/powerpc/powerpc/platform_if.m =================================================================== --- head/sys/powerpc/powerpc/platform_if.m +++ head/sys/powerpc/powerpc/platform_if.m @@ -84,6 +84,10 @@ { return; } + static void platform_null_smp_probe_threads(void) + { + return; + } }; /** @@ -195,6 +199,13 @@ METHOD void smp_ap_init { platform_t _plat; } DEFAULT platform_null_smp_ap_init; + +/** + * @brief Probe mp_ncores and smp_threads_per_core for early MI code + */ +METHOD void smp_probe_threads { + platform_t _plat; +} DEFAULT platform_null_smp_probe_threads; /** * @brief Return SMP topology Index: head/sys/powerpc/ps3/platform_ps3.c =================================================================== --- head/sys/powerpc/ps3/platform_ps3.c +++ head/sys/powerpc/ps3/platform_ps3.c @@ -70,6 +70,7 @@ static int ps3_smp_next_cpu(platform_t, struct cpuref *cpuref); static int ps3_smp_get_bsp(platform_t, struct cpuref *cpuref); static int ps3_smp_start_cpu(platform_t, struct pcpu *cpu); +static void ps3_smp_probe_threads(platform_t); static struct cpu_group *ps3_smp_topo(platform_t); #endif static void ps3_reset(platform_t); @@ -87,6 +88,7 @@ PLATFORMMETHOD(platform_smp_next_cpu, ps3_smp_next_cpu), PLATFORMMETHOD(platform_smp_get_bsp, ps3_smp_get_bsp), PLATFORMMETHOD(platform_smp_start_cpu, ps3_smp_start_cpu), + PLATFORMMETHOD(platform_smp_probe_threads, ps3_smp_probe_threads), PLATFORMMETHOD(platform_smp_topo, ps3_smp_topo), #endif @@ -243,11 +245,16 @@ return ((pc->pc_awake) ? 0 : EBUSY); } -static struct cpu_group * -ps3_smp_topo(platform_t plat) +static void +ps3_smp_probe_threads(platform_t plat) { mp_ncores = 1; smp_threads_per_core = 2; +} + +static struct cpu_group * +ps3_smp_topo(platform_t plat) +{ return (smp_topo_1level(CG_SHARE_L1, 2, CG_FLAG_SMT)); } #endif Index: head/sys/powerpc/pseries/platform_chrp.c =================================================================== --- head/sys/powerpc/pseries/platform_chrp.c +++ head/sys/powerpc/pseries/platform_chrp.c @@ -78,6 +78,7 @@ static int chrp_cpuref_init(void); #ifdef SMP static int chrp_smp_start_cpu(platform_t, struct pcpu *cpu); +static void chrp_smp_probe_threads(platform_t plat); static struct cpu_group *chrp_smp_topo(platform_t plat); #endif static void chrp_reset(platform_t); @@ -103,6 +104,7 @@ PLATFORMMETHOD(platform_smp_get_bsp, chrp_smp_get_bsp), #ifdef SMP PLATFORMMETHOD(platform_smp_start_cpu, chrp_smp_start_cpu), + PLATFORMMETHOD(platform_smp_probe_threads, chrp_smp_probe_threads), PLATFORMMETHOD(platform_smp_topo, chrp_smp_topo), #endif @@ -499,13 +501,13 @@ return ((pc->pc_awake) ? 0 : EBUSY); } -static struct cpu_group * -chrp_smp_topo(platform_t plat) +static void +chrp_smp_probe_threads(platform_t plat) { struct pcpu *pc, *last_pc; - int i, ncores, ncpus; + int i, ncores; - ncores = ncpus = 0; + ncores = 0; last_pc = NULL; for (i = 0; i <= mp_maxid; i++) { pc = pcpu_find(i); @@ -514,23 +516,29 @@ if (last_pc == NULL || pc->pc_hwref != last_pc->pc_hwref) ncores++; last_pc = pc; - ncpus++; } mp_ncores = ncores; + if (mp_ncpus % ncores == 0) + smp_threads_per_core = mp_ncpus / ncores; +} - if (ncpus % ncores != 0) { +static struct cpu_group * +chrp_smp_topo(platform_t plat) +{ + + if (mp_ncpus % mp_ncores != 0) { printf("WARNING: Irregular SMP topology. Performance may be " - "suboptimal (%d CPUS, %d cores)\n", ncpus, ncores); + "suboptimal (%d CPUS, %d cores)\n", mp_ncpus, mp_ncores); return (smp_topo_none()); } /* Don't do anything fancier for non-threaded SMP */ - if (ncpus == ncores) + if (mp_ncpus == mp_ncores) return (smp_topo_none()); - smp_threads_per_core = ncpus / ncores; - return (smp_topo_1level(CG_SHARE_L1, ncpus / ncores, CG_FLAG_SMT)); + return (smp_topo_1level(CG_SHARE_L1, smp_threads_per_core, + CG_FLAG_SMT)); } #endif