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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to