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
This commit is contained in:
Roger Pau Monné 2017-08-10 09:15:18 +00:00
parent 5c5ca36ca2
commit fd1f83fb45
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=322347
7 changed files with 83 additions and 13 deletions

View File

@ -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;
@ -301,6 +304,19 @@ madt_walk_table(acpi_subtable_handler *handler, void *arg)
handler, arg);
}
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)
{
@ -335,6 +351,24 @@ 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;
switch (entry->Type) {
case ACPI_MADT_TYPE_LOCAL_APIC:
proc = (ACPI_MADT_LOCAL_APIC *)entry;

View File

@ -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>

View File

@ -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;

View File

@ -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, "");

View File

@ -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");

View File

@ -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_handler *handler, void *arg)
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;

View File

@ -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);