Index: share/man/man4/smp.4 =================================================================== --- share/man/man4/smp.4 +++ share/man/man4/smp.4 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 6, 2018 +.Dd November 23, 2018 .Dt SMP 4 .Os .Sh NAME @@ -35,27 +35,6 @@ The .Nm kernel implements symmetric multi-processor support. -.Sh COMPATIBILITY -Support for multi-processor systems is present for all Tier-1 -architectures on -.Fx . -Currently, this includes amd64, i386 and sparc64. -Support is enabled using -.Cd options SMP . -It is permissible to use the SMP kernel configuration on non-SMP equipped -motherboards. -.Sh I386 NOTES -For i386 systems, the -.Nm -kernel supports motherboards that follow the Intel MP specification, -version 1.4. -In addition to -.Cd options SMP , -i386 also requires -.Cd device apic . -The -.Xr mptable 1 -command may be used to view the status of multi-processor support. .Pp .Nm support can be disabled by setting the loader tunable @@ -66,6 +45,13 @@ the read-only sysctl variable .Va hw.ncpu . .Pp +The number of threads per CPU core detected by the system is available in the +read-only sysctl variable +.Va kern.smp.smt_threads_online . +The number of physical CPU cores detected by the system is available in the +read-only sysctl variable +.Va hw.physicalcpu . +.Pp .Fx allows specific CPUs on a multi-processor system to be disabled. This can be done using the @@ -74,6 +60,12 @@ Setting this tunable to 1 will result in the corresponding CPU being disabled. .Pp +.Fx +supports hyperthreading on the i386 and AMD64 platforms. +On these platforms, the logical CPUs can be disabled by setting the +.Va machdep.hyperthreading_allowed +tunable to zero. +.Pp The .Xr sched_ule 4 scheduler implements CPU topology detection and adjusts the scheduling @@ -122,13 +114,27 @@ .Pp This information is used internally by the kernel to schedule related tasks on CPUs that are closely grouped together. -.Pp -.Fx -supports hyperthreading on Intel CPU's on the i386 and AMD64 platforms. -Because using logical CPUs can cause performance penalties under certain loads, -the logical CPUs can be disabled by setting the -.Va machdep.hyperthreading_allowed -tunable to zero. +.Sh COMPATIBILITY +Support for multi-processor systems is present for all Tier-1 +architectures on +.Fx . +Currently, this includes amd64, i386 and sparc64. +Support is enabled using +.Cd options SMP . +It is permissible to use the SMP kernel configuration on non-SMP equipped +motherboards. +.Sh I386 NOTES +For i386 systems, the +.Nm +kernel supports motherboards that follow the Intel MP specification, +version 1.4. +In addition to +.Cd options SMP , +i386 also requires +.Cd device apic . +The +.Xr mptable 1 +command may be used to view the status of multi-processor support. .Sh SEE ALSO .Xr cpuset 1 , .Xr mptable 1 , @@ -166,3 +172,20 @@ also introduced support for SMP on the sparc64 architecture. .Sh AUTHORS .An Steve Passe Aq Mt fsmp@FreeBSD.org +.Sh CAVEATS +The +.Va kern.smp.smt_threads_online +and +.Va hw.physicalcpu +sysctl variables are provided as a best-effort guess. +If an architecture adds SMT and +.Fx +has not yet implemented detection, the reported values may be inaccurate. +In this case, +.Va kern.smp.smt_threads_online +will report +.Dv 1 +and +.Va hw.physicalcpu +will report the same value as +.Va hw.ncpu . Index: sys/kern/subr_smp.c =================================================================== --- sys/kern/subr_smp.c +++ sys/kern/subr_smp.c @@ -56,6 +56,9 @@ #ifdef SMP MALLOC_DEFINE(M_TOPO, "toponodes", "SMP topology data"); +int cpu_topo_probed = 0; +struct topo_node topo_root = TOPO_NODE_INITIALIZER(topo_root); + volatile cpuset_t stopped_cpus; volatile cpuset_t started_cpus; volatile cpuset_t suspended_cpus; @@ -98,6 +101,14 @@ SYSCTL_INT(_kern_smp, OID_AUTO, cpus, CTLFLAG_RD|CTLFLAG_CAPRD, &smp_cpus, 0, "Number of CPUs online"); +int smp_smt_threads_online = 1; /* how many SMT threads are running per core */ +SYSCTL_INT(_kern_smp, OID_AUTO, smt_threads_online, CTLFLAG_RD|CTLFLAG_CAPRD, + &smp_smt_threads_online, 0, "Number of SMT threads online per core"); + +int smp_cores = 1; /* how many physical cores running */ +SYSCTL_S32(_hw, OID_AUTO, physicalcpu, CTLFLAG_RD|CTLFLAG_CAPRD, &smp_cores, 0, + "Number of physical CPU cores online"); + int smp_topology = 0; /* Which topology we're using. */ SYSCTL_INT(_kern_smp, OID_AUTO, topology, CTLFLAG_RDTUN, &smp_topology, 0, "Topology override setting; 0 is default provided by hardware."); @@ -149,6 +160,7 @@ static void mp_start(void *dummy) { + struct topo_analysis topology; mtx_init(&smp_ipi_mtx, "smp rendezvous", NULL, MTX_SPIN); @@ -162,7 +174,26 @@ cpu_mp_start(); printf("FreeBSD/SMP: Multiprocessor System Detected: %d CPUs\n", mp_ncpus); + + /* + * Best guess, for lack of better information on any given arch. Allow + * archs to, e.g., override with known information in + * cpu_mp_announce(), without implementing full topology probing. + */ + smp_cores = mp_ncpus; + cpu_mp_announce(); + + /* Not all arch support probing this MI topology structure yet */ + if (cpu_topo_probed == 0) + return; + if (topo_analyze(&topo_root, 0, &topology) == 0) + return; + + if (topology.entities[TOPO_LEVEL_THREAD] > 1) + smp_smt_threads_online = topology.entities[TOPO_LEVEL_THREAD]; + if (topology.entities[TOPO_LEVEL_CORE] > 0) + smp_cores = topology.entities[TOPO_LEVEL_CORE]; } SYSINIT(cpu_mp, SI_SUB_CPU, SI_ORDER_THIRD, mp_start, NULL); @@ -1140,6 +1171,9 @@ struct topo_analysis *results) { + KASSERT(cpu_topo_probed, + ("cannot use %s before probing topology", __func__)); + results->entities[TOPO_LEVEL_PKG] = -1; results->entities[TOPO_LEVEL_CORE] = -1; results->entities[TOPO_LEVEL_THREAD] = -1; Index: sys/sys/param.h =================================================================== --- sys/sys/param.h +++ sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300003 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300004 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, Index: sys/sys/smp.h =================================================================== --- sys/sys/smp.h +++ sys/sys/smp.h @@ -62,6 +62,11 @@ int nchildren; int cpu_count; }; +#define TOPO_NODE_INITIALIZER(node) \ +{ \ + .children = TAILQ_HEAD_INITIALIZER((node).children), \ + .type = TOPO_TYPE_SYSTEM, \ +} /* * Scheduling topology of a NUMA or SMP system. @@ -139,6 +144,8 @@ struct topo_analysis { int entities[TOPO_LEVEL_COUNT]; }; +extern int cpu_topo_probed; +extern struct topo_node topo_root; int topo_analyze(struct topo_node *topo_root, int all, struct topo_analysis *results); Index: sys/x86/x86/mp_x86.c =================================================================== --- sys/x86/x86/mp_x86.c +++ sys/x86/x86/mp_x86.c @@ -147,8 +147,6 @@ SYSCTL_INT(_machdep, OID_AUTO, hyperthreading_allowed, CTLFLAG_RDTUN, &hyperthreading_allowed, 0, "Use Intel HTT logical CPUs"); -static struct topo_node topo_root; - static int pkg_id_shift; static int node_id_shift; static int core_id_shift; @@ -487,7 +485,6 @@ void topo_probe(void) { - static int cpu_topo_probed = 0; struct x86_topo_layer { int type; int subtype;