Module Name: src
Committed By: ad
Date: Fri Dec 20 21:05:34 UTC 2019
Modified Files:
src/sys/arch/aarch64/aarch64: cpu.c cpufunc.c
src/sys/arch/arm/arm32: arm32_boot.c cpu.c
src/sys/arch/macppc/macppc: cpu.c
src/sys/arch/mips/mips: cpu_subr.c
src/sys/arch/x86/x86: cpu.c cpu_topology.c identcpu.c
src/sys/kern: kern_cpu.c
src/sys/sys: cpu.h cpu_data.h sched.h
Log Message:
Some more CPU topology stuff:
- Use cegger@'s ACPI SRAT parsing code to figure out NUMA node ID for each
CPU as it is attached.
- For scheduler experiments with SMT, flag CPUs with the lowest numbered SMT
IDs as "primaries", link back to the primaries from secondaries, and build
a circular list of CPUs in each package with identical SMT IDs.
- No need for package/core/smt/numa IDs to be anything other than a u_int.
To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/aarch64/aarch64/cpu.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/aarch64/aarch64/cpufunc.c
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/arm/arm32/arm32_boot.c
cvs rdiff -u -r1.135 -r1.136 src/sys/arch/arm/arm32/cpu.c
cvs rdiff -u -r1.68 -r1.69 src/sys/arch/macppc/macppc/cpu.c
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.178 -r1.179 src/sys/arch/x86/x86/cpu.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/x86/x86/cpu_topology.c
cvs rdiff -u -r1.98 -r1.99 src/sys/arch/x86/x86/identcpu.c
cvs rdiff -u -r1.86 -r1.87 src/sys/kern/kern_cpu.c
cvs rdiff -u -r1.45 -r1.46 src/sys/sys/cpu.h
cvs rdiff -u -r1.44 -r1.45 src/sys/sys/cpu_data.h
cvs rdiff -u -r1.80 -r1.81 src/sys/sys/sched.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/aarch64/aarch64/cpu.c
diff -u src/sys/arch/aarch64/aarch64/cpu.c:1.26 src/sys/arch/aarch64/aarch64/cpu.c:1.27
--- src/sys/arch/aarch64/aarch64/cpu.c:1.26 Fri Nov 22 05:21:19 2019
+++ src/sys/arch/aarch64/aarch64/cpu.c Fri Dec 20 21:05:33 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.26 2019/11/22 05:21:19 mlelstv Exp $ */
+/* $NetBSD: cpu.c,v 1.27 2019/12/20 21:05:33 ad Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.26 2019/11/22 05:21:19 mlelstv Exp $");
+__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.27 2019/12/20 21:05:33 ad Exp $");
#include "locators.h"
#include "opt_arm_debug.h"
@@ -230,8 +230,7 @@ cpu_identify(device_t self, struct cpu_i
aprint_naive("\n");
aprint_normal(": %s\n", model);
- aprint_normal_dev(ci->ci_dev, "package %lu, core %lu, smt %lu\n",
- ci->ci_package_id, ci->ci_core_id, ci->ci_smt_id);
+ cpu_topology_print(ci);
}
static void
Index: src/sys/arch/aarch64/aarch64/cpufunc.c
diff -u src/sys/arch/aarch64/aarch64/cpufunc.c:1.11 src/sys/arch/aarch64/aarch64/cpufunc.c:1.12
--- src/sys/arch/aarch64/aarch64/cpufunc.c:1.11 Thu Dec 5 05:45:52 2019
+++ src/sys/arch/aarch64/aarch64/cpufunc.c Fri Dec 20 21:05:33 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.c,v 1.11 2019/12/05 05:45:52 ryo Exp $ */
+/* $NetBSD: cpufunc.c,v 1.12 2019/12/20 21:05:33 ad Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -29,7 +29,7 @@
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.11 2019/12/05 05:45:52 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.12 2019/12/20 21:05:33 ad Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -96,11 +96,13 @@ aarch64_gettopology(struct cpu_info * co
cpu_topology_set(ci,
__SHIFTOUT(mpidr, MPIDR_AFF2),
__SHIFTOUT(mpidr, MPIDR_AFF1),
- __SHIFTOUT(mpidr, MPIDR_AFF0));
+ __SHIFTOUT(mpidr, MPIDR_AFF0),
+ 0);
} else {
cpu_topology_set(ci,
__SHIFTOUT(mpidr, MPIDR_AFF1),
__SHIFTOUT(mpidr, MPIDR_AFF0),
+ 0,
0);
}
}
Index: src/sys/arch/arm/arm32/arm32_boot.c
diff -u src/sys/arch/arm/arm32/arm32_boot.c:1.34 src/sys/arch/arm/arm32/arm32_boot.c:1.35
--- src/sys/arch/arm/arm32/arm32_boot.c:1.34 Mon Dec 2 23:22:43 2019
+++ src/sys/arch/arm/arm32/arm32_boot.c Fri Dec 20 21:05:33 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: arm32_boot.c,v 1.34 2019/12/02 23:22:43 ad Exp $ */
+/* $NetBSD: arm32_boot.c,v 1.35 2019/12/20 21:05:33 ad Exp $ */
/*
* Copyright (c) 2002, 2003, 2005 Genetec Corporation. All rights reserved.
@@ -122,7 +122,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.34 2019/12/02 23:22:43 ad Exp $");
+__KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.35 2019/12/20 21:05:33 ad Exp $");
#include "opt_arm_debug.h"
#include "opt_cputypes.h"
@@ -361,11 +361,13 @@ cpu_hatch(struct cpu_info *ci, u_int cpu
cpu_topology_set(ci,
__SHIFTOUT(mpidr, MPIDR_AFF2),
__SHIFTOUT(mpidr, MPIDR_AFF1),
- __SHIFTOUT(mpidr, MPIDR_AFF0));
+ __SHIFTOUT(mpidr, MPIDR_AFF0),
+ 0);
} else {
cpu_topology_set(ci,
__SHIFTOUT(mpidr, MPIDR_AFF1),
__SHIFTOUT(mpidr, MPIDR_AFF0),
+ 0,
0);
}
Index: src/sys/arch/arm/arm32/cpu.c
diff -u src/sys/arch/arm/arm32/cpu.c:1.135 src/sys/arch/arm/arm32/cpu.c:1.136
--- src/sys/arch/arm/arm32/cpu.c:1.135 Mon Dec 2 23:22:43 2019
+++ src/sys/arch/arm/arm32/cpu.c Fri Dec 20 21:05:33 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.135 2019/12/02 23:22:43 ad Exp $ */
+/* $NetBSD: cpu.c,v 1.136 2019/12/20 21:05:33 ad Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
@@ -46,7 +46,7 @@
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.135 2019/12/02 23:22:43 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.136 2019/12/20 21:05:33 ad Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -114,11 +114,13 @@ cpu_attach(device_t dv, cpuid_t id)
cpu_topology_set(ci,
__SHIFTOUT(mpidr, MPIDR_AFF2),
__SHIFTOUT(mpidr, MPIDR_AFF1),
- __SHIFTOUT(mpidr, MPIDR_AFF0));
+ __SHIFTOUT(mpidr, MPIDR_AFF0),
+ 0);
} else {
cpu_topology_set(ci,
__SHIFTOUT(mpidr, MPIDR_AFF1),
__SHIFTOUT(mpidr, MPIDR_AFF0),
+ 0,
0);
}
#endif
Index: src/sys/arch/macppc/macppc/cpu.c
diff -u src/sys/arch/macppc/macppc/cpu.c:1.68 src/sys/arch/macppc/macppc/cpu.c:1.69
--- src/sys/arch/macppc/macppc/cpu.c:1.68 Fri Dec 13 23:01:41 2019
+++ src/sys/arch/macppc/macppc/cpu.c Fri Dec 20 21:05:33 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.68 2019/12/13 23:01:41 macallan Exp $ */
+/* $NetBSD: cpu.c,v 1.69 2019/12/20 21:05:33 ad Exp $ */
/*-
* Copyright (c) 2001 Tsubai Masanari.
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.68 2019/12/13 23:01:41 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.69 2019/12/20 21:05:33 ad Exp $");
#include "opt_ppcparam.h"
#include "opt_multiprocessor.h"
@@ -175,7 +175,7 @@ cpuattach(device_t parent, device_t self
core = package & 1;
package >>= 1;
}
- cpu_topology_set(ci, package, core, 0);
+ cpu_topology_set(ci, package, core, 0, 0);
if (ci->ci_khz == 0) {
cpu_OFgetspeed(self, ci);
Index: src/sys/arch/mips/mips/cpu_subr.c
diff -u src/sys/arch/mips/mips/cpu_subr.c:1.40 src/sys/arch/mips/mips/cpu_subr.c:1.41
--- src/sys/arch/mips/mips/cpu_subr.c:1.40 Tue Dec 3 15:20:59 2019
+++ src/sys/arch/mips/mips/cpu_subr.c Fri Dec 20 21:05:33 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_subr.c,v 1.40 2019/12/03 15:20:59 riastradh Exp $ */
+/* $NetBSD: cpu_subr.c,v 1.41 2019/12/20 21:05:33 ad Exp $ */
/*-
* Copyright (c) 2010, 2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.40 2019/12/03 15:20:59 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.41 2019/12/20 21:05:33 ad Exp $");
#include "opt_cputype.h"
#include "opt_ddb.h"
@@ -189,7 +189,7 @@ cpu_info_alloc(struct pmap_tlb_info *ti,
ci->ci_divisor_recip = cpu_info_store.ci_divisor_recip;
ci->ci_cpuwatch_count = cpu_info_store.ci_cpuwatch_count;
- cpu_topology_set(ci, cpu_package_id, cpu_core_id, cpu_smt_id);
+ cpu_topology_set(ci, cpu_package_id, cpu_core_id, cpu_smt_id, 0);
pmap_md_alloc_ephemeral_address_space(ci);
Index: src/sys/arch/x86/x86/cpu.c
diff -u src/sys/arch/x86/x86/cpu.c:1.178 src/sys/arch/x86/x86/cpu.c:1.179
--- src/sys/arch/x86/x86/cpu.c:1.178 Sat Dec 7 11:45:45 2019
+++ src/sys/arch/x86/x86/cpu.c Fri Dec 20 21:05:34 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.178 2019/12/07 11:45:45 nonaka Exp $ */
+/* $NetBSD: cpu.c,v 1.179 2019/12/20 21:05:34 ad Exp $ */
/*
* Copyright (c) 2000-2012 NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.178 2019/12/07 11:45:45 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.179 2019/12/20 21:05:34 ad Exp $");
#include "opt_ddb.h"
#include "opt_mpbios.h" /* for MPDEBUG */
@@ -72,6 +72,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.17
#include "lapic.h"
#include "ioapic.h"
+#include "acpica.h"
#include <sys/param.h>
#include <sys/proc.h>
@@ -106,6 +107,10 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.17
#include <x86/fpu.h>
+#if NACPICA > 0
+#include <dev/acpi/acpi_srat.h>
+#endif
+
#if NLAPIC > 0
#include <machine/apicvar.h>
#include <machine/i82489reg.h>
@@ -404,6 +409,10 @@ cpu_attach(device_t parent, device_t sel
cpu_init_tss(ci);
} else {
KASSERT(ci->ci_data.cpu_idlelwp != NULL);
+#if NACPICA > 0
+ /* Parse out NUMA info for cpu_identify(). */
+ acpisrat_init();
+#endif
}
#ifdef SVS
@@ -706,6 +715,11 @@ cpu_boot_secondary_processors(void)
x86_patch(false);
#endif
+#if NACPICA > 0
+ /* Finished with NUMA info for now. */
+ acpisrat_exit();
+#endif
+
kcpuset_create(&cpus, true);
kcpuset_set(cpus, cpu_index(curcpu()));
for (i = 0; i < maxcpus; i++) {
Index: src/sys/arch/x86/x86/cpu_topology.c
diff -u src/sys/arch/x86/x86/cpu_topology.c:1.15 src/sys/arch/x86/x86/cpu_topology.c:1.16
--- src/sys/arch/x86/x86/cpu_topology.c:1.15 Mon Dec 2 23:22:43 2019
+++ src/sys/arch/x86/x86/cpu_topology.c Fri Dec 20 21:05:34 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_topology.c,v 1.15 2019/12/02 23:22:43 ad Exp $ */
+/* $NetBSD: cpu_topology.c,v 1.16 2019/12/20 21:05:34 ad Exp $ */
/*-
* Copyright (c) 2009 Mindaugas Rasiukevicius <rmind at NetBSD org>,
@@ -36,7 +36,9 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.15 2019/12/02 23:22:43 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.16 2019/12/20 21:05:34 ad Exp $");
+
+#include "acpica.h"
#include <sys/param.h>
#include <sys/bitops.h>
@@ -44,10 +46,33 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_topology
#include <machine/specialreg.h>
+#include <dev/acpi/acpi_srat.h>
+
#include <x86/cpufunc.h>
#include <x86/cputypes.h>
#include <x86/cpuvar.h>
+static uint32_t
+x86_cpu_get_numa_node(uint32_t apic_id)
+{
+#if NACPICA > 0
+ uint32_t i, j, nn, nc;
+ struct acpisrat_cpu c;
+
+ nn = acpisrat_nodes();
+ for (i = 0; i < nn; i++) {
+ nc = acpisrat_node_cpus(i);
+ for (j = 0; j < nc; j++) {
+ acpisrat_cpu(i, j, &c);
+ if (c.apicid == apic_id) {
+ return c.nodeid;
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
void
x86_cpu_topology(struct cpu_info *ci)
{
@@ -55,7 +80,7 @@ x86_cpu_topology(struct cpu_info *ci)
u_int core_max; /* Core per package */
int n, cpu_family, apic_id, smt_bits, core_bits = 0;
uint32_t descs[4];
- int package_id, core_id, smt_id;
+ u_int package_id, core_id, smt_id, numa_id;
apic_id = ci->ci_initapicid;
cpu_family = CPUID_TO_FAMILY(ci->ci_signature);
@@ -64,17 +89,20 @@ x86_cpu_topology(struct cpu_info *ci)
package_id = apic_id;
core_id = 0;
smt_id = 0;
+ numa_id = x86_cpu_get_numa_node(apic_id);
switch (cpu_vendor) {
case CPUVENDOR_INTEL:
if (cpu_family < 6) {
- cpu_topology_set(ci, package_id, core_id, smt_id);
+ cpu_topology_set(ci, package_id, core_id, smt_id,
+ numa_id);
return;
}
break;
case CPUVENDOR_AMD:
if (cpu_family < 0xf) {
- cpu_topology_set(ci, package_id, core_id, smt_id);
+ cpu_topology_set(ci, package_id, core_id, smt_id,
+ numa_id);
return;
}
break;
@@ -182,5 +210,5 @@ x86_cpu_topology(struct cpu_info *ci)
smt_id = __SHIFTOUT(apic_id, smt_mask);
}
- cpu_topology_set(ci, package_id, core_id, smt_id);
+ cpu_topology_set(ci, package_id, core_id, smt_id, numa_id);
}
Index: src/sys/arch/x86/x86/identcpu.c
diff -u src/sys/arch/x86/x86/identcpu.c:1.98 src/sys/arch/x86/x86/identcpu.c:1.99
--- src/sys/arch/x86/x86/identcpu.c:1.98 Tue Oct 29 12:39:46 2019
+++ src/sys/arch/x86/x86/identcpu.c Fri Dec 20 21:05:34 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: identcpu.c,v 1.98 2019/10/29 12:39:46 maxv Exp $ */
+/* $NetBSD: identcpu.c,v 1.99 2019/12/20 21:05:34 ad Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.98 2019/10/29 12:39:46 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.99 2019/12/20 21:05:34 ad Exp $");
#include "opt_xen.h"
@@ -1002,8 +1002,7 @@ cpu_identify(struct cpu_info *ci)
if (ci->ci_signature != 0)
aprint_normal(", id 0x%x", ci->ci_signature);
aprint_normal("\n");
- aprint_normal_dev(ci->ci_dev, "package %lu, core %lu, smt %lu\n",
- ci->ci_package_id, ci->ci_core_id, ci->ci_smt_id);
+ cpu_topology_print(ci);
if (cpu_brand_string[0] == '\0') {
strlcpy(cpu_brand_string, cpu_getmodel(),
sizeof(cpu_brand_string));
Index: src/sys/kern/kern_cpu.c
diff -u src/sys/kern/kern_cpu.c:1.86 src/sys/kern/kern_cpu.c:1.87
--- src/sys/kern/kern_cpu.c:1.86 Wed Dec 18 19:40:34 2019
+++ src/sys/kern/kern_cpu.c Fri Dec 20 21:05:34 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_cpu.c,v 1.86 2019/12/18 19:40:34 ad Exp $ */
+/* $NetBSD: kern_cpu.c,v 1.87 2019/12/20 21:05:34 ad Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009, 2010, 2012, 2019 The NetBSD Foundation, Inc.
@@ -56,7 +56,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.86 2019/12/18 19:40:34 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.87 2019/12/20 21:05:34 ad Exp $");
#ifdef _KERNEL_OPT
#include "opt_cpu_ucode.h"
@@ -600,7 +600,8 @@ cpu_softintr_p(void)
* called early during boot, so we need to be careful what we do.
*/
void
-cpu_topology_set(struct cpu_info *ci, int package_id, int core_id, int smt_id)
+cpu_topology_set(struct cpu_info *ci, u_int package_id, u_int core_id,
+ u_int smt_id, u_int numa_id)
{
enum cpu_rel rel;
@@ -608,6 +609,7 @@ cpu_topology_set(struct cpu_info *ci, in
ci->ci_package_id = package_id;
ci->ci_core_id = core_id;
ci->ci_smt_id = smt_id;
+ ci->ci_numa_id = numa_id;
for (rel = 0; rel < __arraycount(ci->ci_sibling); rel++) {
ci->ci_sibling[rel] = ci;
ci->ci_nsibling[rel] = 1;
@@ -635,47 +637,21 @@ cpu_topology_link(struct cpu_info *ci, s
}
/*
- * Find peer CPUs in other packages.
- */
-static void
-cpu_topology_peers(void)
-{
- CPU_INFO_ITERATOR cii, cii2;
- struct cpu_info *ci, *ci2;
-
- for (CPU_INFO_FOREACH(cii, ci)) {
- if (ci->ci_nsibling[CPUREL_PEER] > 1) {
- /* Already linked. */
- continue;
- }
- for (CPU_INFO_FOREACH(cii2, ci2)) {
- if (ci != ci2 &&
- ci->ci_package_id != ci2->ci_package_id &&
- ci->ci_core_id == ci2->ci_core_id &&
- ci->ci_smt_id == ci2->ci_smt_id) {
- cpu_topology_link(ci, ci2, CPUREL_PEER);
- break;
- }
- }
- }
-}
-
-/*
* Print out the topology lists.
*/
static void
-cpu_topology_print(void)
+cpu_topology_dump(void)
{
-#ifdef DEBUG
+#if DEBUG
CPU_INFO_ITERATOR cii;
struct cpu_info *ci, *ci2;
- const char *names[] = { "core", "package", "peer" };
+ const char *names[] = { "core", "package", "peer", "smt" };
enum cpu_rel rel;
int i;
for (CPU_INFO_FOREACH(cii, ci)) {
for (rel = 0; rel < __arraycount(ci->ci_sibling); rel++) {
- printf("%s has %dx %s siblings: ", cpu_name(ci),
+ printf("%s has %d %s siblings:", cpu_name(ci),
ci->ci_nsibling[rel], names[rel]);
ci2 = ci->ci_sibling[rel];
i = 0;
@@ -712,8 +688,10 @@ cpu_topology_fake(void)
if (!cpu_topology_present) {
ci->ci_package_id = cpu_index(ci);
}
+ ci->ci_smt_primary = ci;
+ ci->ci_schedstate.spc_flags |= SPCF_SMTPRIMARY;
}
- cpu_topology_print();
+ cpu_topology_dump();
}
/*
@@ -724,8 +702,8 @@ void
cpu_topology_init(void)
{
CPU_INFO_ITERATOR cii, cii2;
- struct cpu_info *ci, *ci2;
- int ncore, npackage, npeer;
+ struct cpu_info *ci, *ci2, *ci3;
+ u_int ncore, npackage, npeer, minsmt;
bool symmetric;
if (!cpu_topology_present) {
@@ -766,8 +744,33 @@ cpu_topology_init(void)
}
}
- /* Find peers in other packages. */
- cpu_topology_peers();
+ /* Find peers in other packages, and peer SMTs in same package. */
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ if (ci->ci_nsibling[CPUREL_PEER] <= 1) {
+ for (CPU_INFO_FOREACH(cii2, ci2)) {
+ if (ci != ci2 &&
+ ci->ci_package_id != ci2->ci_package_id &&
+ ci->ci_core_id == ci2->ci_core_id &&
+ ci->ci_smt_id == ci2->ci_smt_id) {
+ cpu_topology_link(ci, ci2,
+ CPUREL_PEER);
+ break;
+ }
+ }
+ }
+ if (ci->ci_nsibling[CPUREL_SMT] <= 1) {
+ for (CPU_INFO_FOREACH(cii2, ci2)) {
+ if (ci != ci2 &&
+ ci->ci_package_id == ci2->ci_package_id &&
+ ci->ci_core_id != ci2->ci_core_id &&
+ ci->ci_smt_id == ci2->ci_smt_id) {
+ cpu_topology_link(ci, ci2,
+ CPUREL_SMT);
+ break;
+ }
+ }
+ }
+ }
/* Determine whether the topology is bogus/symmetric. */
npackage = curcpu()->ci_nsibling[CPUREL_PACKAGE];
@@ -781,13 +784,49 @@ cpu_topology_init(void)
symmetric = false;
}
}
- cpu_topology_print();
+ cpu_topology_dump();
if (symmetric == false) {
printf("cpu_topology_init: not symmetric, faking it\n");
cpu_topology_fake();
+ return;
+ }
+
+ /* Identify SMT primary in each core. */
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ ci2 = ci3 = ci;
+ minsmt = ci->ci_smt_id;
+ do {
+ if (ci2->ci_smt_id < minsmt) {
+ ci3 = ci2;
+ minsmt = ci2->ci_smt_id;
+ }
+ ci2 = ci2->ci_sibling[CPUREL_CORE];
+ } while (ci2 != ci);
+
+ /*
+ * Mark the SMT primary, and walk back over the list
+ * pointing secondaries to the primary.
+ */
+ ci3->ci_schedstate.spc_flags |= SPCF_SMTPRIMARY;
+ ci2 = ci;
+ do {
+ ci2->ci_smt_primary = ci3;
+ ci2 = ci2->ci_sibling[CPUREL_CORE];
+ } while (ci2 != ci);
}
}
+/*
+ * Print basic topology info.
+ */
+void
+cpu_topology_print(struct cpu_info *ci)
+{
+
+ aprint_normal_dev(ci->ci_dev, "numa %u, package %u, core %u, smt %u\n",
+ ci->ci_numa_id, ci->ci_package_id, ci->ci_core_id, ci->ci_smt_id);
+}
+
#ifdef CPU_UCODE
int
cpu_ucode_load(struct cpu_ucode_softc *sc, const char *fwname)
Index: src/sys/sys/cpu.h
diff -u src/sys/sys/cpu.h:1.45 src/sys/sys/cpu.h:1.46
--- src/sys/sys/cpu.h:1.45 Mon Dec 2 23:22:43 2019
+++ src/sys/sys/cpu.h Fri Dec 20 21:05:34 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.45 2019/12/02 23:22:43 ad Exp $ */
+/* $NetBSD: cpu.h,v 1.46 2019/12/20 21:05:34 ad Exp $ */
/*-
* Copyright (c) 2007 YAMAMOTO Takashi,
@@ -90,8 +90,9 @@ bool cpu_kpreempt_disabled(void);
int cpu_lwp_setprivate(struct lwp *, void *);
void cpu_intr_redistribute(void);
u_int cpu_intr_count(struct cpu_info *);
-void cpu_topology_set(struct cpu_info *, int, int, int);
+void cpu_topology_set(struct cpu_info *, u_int, u_int, u_int, u_int);
void cpu_topology_init(void);
+void cpu_topology_print(struct cpu_info *);
#endif
#ifdef _KERNEL
Index: src/sys/sys/cpu_data.h
diff -u src/sys/sys/cpu_data.h:1.44 src/sys/sys/cpu_data.h:1.45
--- src/sys/sys/cpu_data.h:1.44 Mon Dec 16 22:47:55 2019
+++ src/sys/sys/cpu_data.h Fri Dec 20 21:05:34 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_data.h,v 1.44 2019/12/16 22:47:55 ad Exp $ */
+/* $NetBSD: cpu_data.h,v 1.45 2019/12/20 21:05:34 ad Exp $ */
/*-
* Copyright (c) 2004, 2006, 2007, 2008, 2019 The NetBSD Foundation, Inc.
@@ -116,6 +116,7 @@ enum cpu_rel {
CPUREL_CORE, /* CPUs in the same core */
CPUREL_PACKAGE, /* CPUs in the same package */
CPUREL_PEER, /* peer CPUs in other packages */
+ CPUREL_SMT, /* peer SMTs in same package */
CPUREL_COUNT
};
@@ -133,11 +134,13 @@ struct cpu_data {
struct schedstate_percpu cpu_schedstate; /* scheduler state */
/* Basic topology information. May be fake. */
- cpuid_t cpu_package_id;
- cpuid_t cpu_core_id;
- cpuid_t cpu_smt_id;
+ u_int cpu_package_id;
+ u_int cpu_core_id;
+ u_int cpu_smt_id;
+ u_int cpu_numa_id;
u_int cpu_nsibling[CPUREL_COUNT];
struct cpu_info *cpu_sibling[CPUREL_COUNT];
+ struct cpu_info *cpu_smt_primary;
/*
* This section is mostly CPU-private.
@@ -186,8 +189,10 @@ struct cpu_data {
#define ci_package_id ci_data.cpu_package_id
#define ci_core_id ci_data.cpu_core_id
#define ci_smt_id ci_data.cpu_smt_id
+#define ci_numa_id ci_data.cpu_numa_id
#define ci_nsibling ci_data.cpu_nsibling
#define ci_sibling ci_data.cpu_sibling
+#define ci_smt_primary ci_data.cpu_smt_primary
#define ci_faultrng ci_data.cpu_faultrng
#define ci_counts ci_data.cpu_counts
Index: src/sys/sys/sched.h
diff -u src/sys/sys/sched.h:1.80 src/sys/sys/sched.h:1.81
--- src/sys/sys/sched.h:1.80 Fri Dec 6 21:36:10 2019
+++ src/sys/sys/sched.h Fri Dec 20 21:05:34 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sched.h,v 1.80 2019/12/06 21:36:10 ad Exp $ */
+/* $NetBSD: sched.h,v 1.81 2019/12/20 21:05:34 ad Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2007, 2008, 2019
@@ -186,6 +186,7 @@ struct schedstate_percpu {
#define SPCF_OFFLINE 0x0004 /* CPU marked offline */
#define SPCF_RUNNING 0x0008 /* CPU is running */
#define SPCF_NOINTR 0x0010 /* shielded from interrupts */
+#define SPCF_SMTPRIMARY 0x0020 /* CPU is first thread in core */
#define SPCF_SWITCHCLEAR (SPCF_SEENRR|SPCF_SHOULDYIELD)