Index: sys/powerpc/powernv/platform_powernv.c =================================================================== --- sys/powerpc/powernv/platform_powernv.c +++ sys/powerpc/powernv/platform_powernv.c @@ -483,16 +483,36 @@ static struct cpu_group * powernv_smp_topo(platform_t plat) { + cpuset_t dom; + int corespdom, i, j; + 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, smp_threads_per_core); + printf("%s: irregular SMP topology (%d threads, %d per core)\n", + __func__, mp_ncpus, smp_threads_per_core); return (smp_topo_none()); } - /* Don't do anything fancier for non-threaded SMP */ - if (smp_threads_per_core == 1) - return (smp_topo_none()); + corespdom = mp_ncpus / vm_ndomains; + if (mp_ncpus % vm_ndomains != 0 || + corespdom % smp_threads_per_core != 0) { + printf("%s: irregular NUMA topology\n", __func__); + } else if (vm_ndomains > 1) { + for (i = 0; i < vm_ndomains; i++) { + CPU_ZERO(&dom); + for (j = 0; j < corespdom; j++) + CPU_SET(i * corespdom + j, &dom); + if (CPU_CMP(&dom, &cpuset_domain[i]) != 0) { + printf("%s: non-contiguous NUMA domains\n", + __func__); + break; + } + } + if (i == vm_ndomains) { + return (smp_topo_2level(CG_SHARE_L3, + corespdom / smp_threads_per_core, CG_SHARE_L1, + smp_threads_per_core, CG_FLAG_SMT)); + } + } return (smp_topo_1level(CG_SHARE_L1, smp_threads_per_core, CG_FLAG_SMT));