Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Aug 2017 09:15:18 +0000 (UTC)
From:      =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= <royger@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r322347 - in head/sys/x86: acpica include x86 xen
Message-ID:  <201708100915.v7A9FIke002476@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: royger
Date: Thu Aug 10 09:15:18 2017
New Revision: 322347
URL: https://svnweb.freebsd.org/changeset/base/322347

Log:
  apic_enumerator: only set mp_ncpus and mp_maxid at probe cpus phase
  
  Populate the lapics arrays and call cpu_add/lapic_create in the setup
  phase instead. Also store the max APIC ID found in the newly
  introduced max_apic_id global variable.
  
  This is a requirement in order to make the static arrays currently
  using MAX_LAPIC_ID dynamic.
  
  Sponsored by:		Citrix Systems R&D
  MFC after:		1 month
  Reviewed by:		kib
  Differential revision:	https://reviews.freebsd.org/D11911

Modified:
  head/sys/x86/acpica/madt.c
  head/sys/x86/acpica/srat.c
  head/sys/x86/include/x86_var.h
  head/sys/x86/x86/local_apic.c
  head/sys/x86/x86/mp_x86.c
  head/sys/x86/x86/mptable.c
  head/sys/x86/xen/pvcpu_enum.c

Modified: head/sys/x86/acpica/madt.c
==============================================================================
--- head/sys/x86/acpica/madt.c	Thu Aug 10 09:02:44 2017	(r322346)
+++ head/sys/x86/acpica/madt.c	Thu Aug 10 09:15:18 2017	(r322347)
@@ -83,6 +83,8 @@ static int	madt_probe(void);
 static int	madt_probe_cpus(void);
 static void	madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
 		    void *arg __unused);
+static void	madt_setup_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
+		    void *arg __unused);
 static void	madt_register(void *dummy);
 static int	madt_setup_local(void);
 static int	madt_setup_io(void);
@@ -140,6 +142,7 @@ madt_setup_local(void)
 	bool bios_x2apic;
 
 	madt = pmap_mapbios(madt_physaddr, madt_length);
+	madt_walk_table(madt_setup_cpus_handler, NULL);
 	if ((cpu_feature2 & CPUID2_X2APIC) != 0) {
 		reason = NULL;
 
@@ -302,6 +305,19 @@ madt_walk_table(acpi_subtable_handler *handler, void *
 }
 
 static void
+madt_parse_cpu(unsigned int apic_id, unsigned int flags)
+{
+
+	if (!(flags & ACPI_MADT_ENABLED) || mp_ncpus == MAXCPU ||
+	    apic_id > MAX_APIC_ID)
+		return;
+
+	mp_ncpus++;
+	mp_maxid = mp_ncpus - 1;
+	max_apic_id = max(apic_id, max_apic_id);
+}
+
+static void
 madt_add_cpu(u_int acpi_id, u_int apic_id, u_int flags)
 {
 	struct lapic_info *la;
@@ -331,6 +347,24 @@ madt_add_cpu(u_int acpi_id, u_int apic_id, u_int flags
 
 static void
 madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
+{
+	ACPI_MADT_LOCAL_APIC *proc;
+	ACPI_MADT_LOCAL_X2APIC *x2apic;
+
+	switch (entry->Type) {
+	case ACPI_MADT_TYPE_LOCAL_APIC:
+		proc = (ACPI_MADT_LOCAL_APIC *)entry;
+		madt_parse_cpu(proc->Id, proc->LapicFlags);
+		break;
+	case ACPI_MADT_TYPE_LOCAL_X2APIC:
+		x2apic = (ACPI_MADT_LOCAL_X2APIC *)entry;
+		madt_parse_cpu(x2apic->LocalApicId, x2apic->LapicFlags);
+		break;
+	}
+}
+
+static void
+madt_setup_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
 {
 	ACPI_MADT_LOCAL_APIC *proc;
 	ACPI_MADT_LOCAL_X2APIC *x2apic;

Modified: head/sys/x86/acpica/srat.c
==============================================================================
--- head/sys/x86/acpica/srat.c	Thu Aug 10 09:02:44 2017	(r322346)
+++ head/sys/x86/acpica/srat.c	Thu Aug 10 09:15:18 2017	(r322347)
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
 #include <contrib/dev/acpica/include/actables.h>
 
 #include <machine/intr_machdep.h>
+#include <machine/md_var.h>
 #include <x86/apicvar.h>
 
 #include <dev/acpica/acpivar.h>

Modified: head/sys/x86/include/x86_var.h
==============================================================================
--- head/sys/x86/include/x86_var.h	Thu Aug 10 09:02:44 2017	(r322346)
+++ head/sys/x86/include/x86_var.h	Thu Aug 10 09:15:18 2017	(r322347)
@@ -78,6 +78,7 @@ extern	int	_ufssel;
 extern	int	_ugssel;
 extern	int	use_xsave;
 extern	uint64_t xsave_mask;
+extern	u_int	max_apic_id;
 
 struct	pcb;
 struct	thread;

Modified: head/sys/x86/x86/local_apic.c
==============================================================================
--- head/sys/x86/x86/local_apic.c	Thu Aug 10 09:02:44 2017	(r322346)
+++ head/sys/x86/x86/local_apic.c	Thu Aug 10 09:15:18 2017	(r322347)
@@ -184,6 +184,7 @@ static struct eventtimer lapic_et;
 #ifdef SMP
 static uint64_t lapic_ipi_wait_mult;
 #endif
+unsigned int max_apic_id;
 
 SYSCTL_NODE(_hw, OID_AUTO, apic, CTLFLAG_RD, 0, "APIC options");
 SYSCTL_INT(_hw_apic, OID_AUTO, x2apic_mode, CTLFLAG_RD, &x2apic_mode, 0, "");

Modified: head/sys/x86/x86/mp_x86.c
==============================================================================
--- head/sys/x86/x86/mp_x86.c	Thu Aug 10 09:02:44 2017	(r322346)
+++ head/sys/x86/x86/mp_x86.c	Thu Aug 10 09:15:18 2017	(r322347)
@@ -825,10 +825,6 @@ cpu_add(u_int apic_id, char boot_cpu)
 		boot_cpu_id = apic_id;
 		cpu_info[apic_id].cpu_bsp = 1;
 	}
-	if (mp_ncpus < MAXCPU) {
-		mp_ncpus++;
-		mp_maxid = mp_ncpus - 1;
-	}
 	if (bootverbose)
 		printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
 		    "AP");

Modified: head/sys/x86/x86/mptable.c
==============================================================================
--- head/sys/x86/x86/mptable.c	Thu Aug 10 09:02:44 2017	(r322346)
+++ head/sys/x86/x86/mptable.c	Thu Aug 10 09:15:18 2017	(r322347)
@@ -191,6 +191,7 @@ static void	mptable_pci_setup(void);
 static int	mptable_probe(void);
 static int	mptable_probe_cpus(void);
 static void	mptable_probe_cpus_handler(u_char *entry, void *arg __unused);
+static void	mptable_setup_cpus_handler(u_char *entry, void *arg __unused);
 static void	mptable_register(void *dummy);
 static int	mptable_setup_local(void);
 static int	mptable_setup_io(void);
@@ -329,14 +330,11 @@ mptable_probe_cpus(void)
 
 	/* Is this a pre-defined config? */
 	if (mpfps->config_type != 0) {
-		lapic_create(0, 1);
-		lapic_create(1, 0);
+		mp_ncpus = 2;
+		mp_maxid = 1;
+		max_apic_id = 1;
 	} else {
-		cpu_mask = 0;
 		mptable_walk_table(mptable_probe_cpus_handler, &cpu_mask);
-#ifdef MPTABLE_FORCE_HTT
-		mptable_hyperthread_fixup(cpu_mask);
-#endif
 	}
 	return (0);
 }
@@ -352,9 +350,17 @@ mptable_setup_local(void)
 	/* Is this a pre-defined config? */
 	printf("MPTable: <");
 	if (mpfps->config_type != 0) {
+		lapic_create(0, 1);
+		lapic_create(1, 0);
 		addr = DEFAULT_APIC_BASE;
 		printf("Default Configuration %d", mpfps->config_type);
+
 	} else {
+		cpu_mask = 0;
+		mptable_walk_table(mptable_setup_cpus_handler, &cpu_mask);
+#ifdef MPTABLE_FORCE_HTT
+		mptable_hyperthread_fixup(cpu_mask);
+#endif
 		addr = mpct->apic_address;
 		printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id,
 		    (int)sizeof(mpct->product_id), mpct->product_id);
@@ -464,6 +470,25 @@ mptable_walk_extended_table(mptable_extended_entry_han
 
 static void
 mptable_probe_cpus_handler(u_char *entry, void *arg)
+{
+	proc_entry_ptr proc;
+
+	switch (*entry) {
+	case MPCT_ENTRY_PROCESSOR:
+		proc = (proc_entry_ptr)entry;
+		if (proc->cpu_flags & PROCENTRY_FLAG_EN &&
+		    proc->apic_id < MAX_LAPIC_ID && mp_ncpus < MAXCPU) {
+			mp_ncpus++;
+			mp_maxid = mp_ncpus - 1;
+			max_apic_id = max(max_apic_id, proc->apic_id);
+		}
+		break;
+	}
+}
+
+
+static void
+mptable_setup_cpus_handler(u_char *entry, void *arg)
 {
 	proc_entry_ptr proc;
 	u_int *cpu_mask;

Modified: head/sys/x86/xen/pvcpu_enum.c
==============================================================================
--- head/sys/x86/xen/pvcpu_enum.c	Thu Aug 10 09:02:44 2017	(r322346)
+++ head/sys/x86/xen/pvcpu_enum.c	Thu Aug 10 09:15:18 2017	(r322347)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/cpu.h>
 #include <machine/smp.h>
+#include <machine/md_var.h>
 
 #include <xen/xen-os.h>
 #include <xen/xen_intr.h>
@@ -151,11 +152,12 @@ xenpv_probe_cpus(void)
 #ifdef SMP
 	int i, ret;
 
-	for (i = 0; i < MAXCPU; i++) {
+	for (i = 0; i < MAXCPU && (i * 2) < MAX_APIC_ID; i++) {
 		ret = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
-		if (ret >= 0)
-			lapic_create((i * 2), (i == 0));
+		mp_ncpus = min(mp_ncpus + 1, MAXCPU);
 	}
+	mp_maxid = mp_ncpus - 1;
+	max_apic_id = mp_ncpus * 2;
 #endif
 	return (0);
 }
@@ -166,6 +168,16 @@ xenpv_probe_cpus(void)
 static int
 xenpv_setup_local(void)
 {
+#ifdef SMP
+	int i, ret;
+
+	for (i = 0; i < MAXCPU && (i * 2) < MAX_APIC_ID; i++) {
+		ret = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
+		if (ret >= 0)
+			lapic_create((i * 2), (i == 0));
+	}
+#endif
+
 	PCPU_SET(vcpu_id, 0);
 	lapic_init(0);
 	return (0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708100915.v7A9FIke002476>