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)
 

Reply via email to