Allocate all per-cpu datastructures in domain correct memory.
Reviewed by: kib, gallatin (some objections) Tested by: pho Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D21242
This commit is contained in:
parent
6565f65ce1
commit
a5e5548c88
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cpuset.h>
|
||||
#include <sys/domainset.h>
|
||||
#ifdef GPROF
|
||||
#include <sys/gmon.h>
|
||||
#endif
|
||||
@ -59,6 +60,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_extern.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_phys.h>
|
||||
|
||||
#include <x86/apicreg.h>
|
||||
#include <machine/clock.h>
|
||||
@ -75,6 +78,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/cpu.h>
|
||||
#include <x86/init.h>
|
||||
|
||||
#include <contrib/dev/acpica/include/acpi.h>
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
||||
#define WARMBOOT_TARGET 0
|
||||
#define WARMBOOT_OFF (KERNBASE + 0x0467)
|
||||
#define WARMBOOT_SEG (KERNBASE + 0x0469)
|
||||
@ -384,6 +390,25 @@ init_secondary(void)
|
||||
* local functions and data
|
||||
*/
|
||||
|
||||
#ifdef NUMA
|
||||
static void
|
||||
mp_realloc_pcpu(int cpuid, int domain)
|
||||
{
|
||||
vm_page_t m;
|
||||
vm_offset_t oa, na;
|
||||
|
||||
oa = (vm_offset_t)&__pcpu[cpuid];
|
||||
if (_vm_phys_domain(pmap_kextract(oa)) == domain)
|
||||
return;
|
||||
m = vm_page_alloc_domain(NULL, 0, domain,
|
||||
VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_ZERO);
|
||||
na = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
|
||||
pagecopy((void *)oa, (void *)na);
|
||||
pmap_enter(kernel_pmap, oa, m, VM_PROT_READ | VM_PROT_WRITE, 0, 0);
|
||||
/* XXX old pcpu page leaked. */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* start each AP in our list
|
||||
*/
|
||||
@ -392,7 +417,7 @@ native_start_all_aps(void)
|
||||
{
|
||||
u_int64_t *pt4, *pt3, *pt2;
|
||||
u_int32_t mpbioswarmvec;
|
||||
int apic_id, cpu, i;
|
||||
int apic_id, cpu, domain, i;
|
||||
u_char mpbiosreason;
|
||||
|
||||
mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
|
||||
@ -431,21 +456,41 @@ native_start_all_aps(void)
|
||||
outb(CMOS_REG, BIOS_RESET);
|
||||
outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */
|
||||
|
||||
/* Relocate pcpu areas to the correct domain. */
|
||||
#ifdef NUMA
|
||||
if (vm_ndomains > 1)
|
||||
for (cpu = 1; cpu < mp_ncpus; cpu++) {
|
||||
apic_id = cpu_apic_ids[cpu];
|
||||
domain = acpi_pxm_get_cpu_locality(apic_id);
|
||||
mp_realloc_pcpu(cpu, domain);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* start each AP */
|
||||
domain = 0;
|
||||
for (cpu = 1; cpu < mp_ncpus; cpu++) {
|
||||
apic_id = cpu_apic_ids[cpu];
|
||||
|
||||
#ifdef NUMA
|
||||
if (vm_ndomains > 1)
|
||||
domain = acpi_pxm_get_cpu_locality(apic_id);
|
||||
#endif
|
||||
/* allocate and set up an idle stack data page */
|
||||
bootstacks[cpu] = (void *)kmem_malloc(kstack_pages * PAGE_SIZE,
|
||||
bootstacks[cpu] = (void *)kmem_malloc_domainset(
|
||||
DOMAINSET_FIXED(domain), kstack_pages * PAGE_SIZE,
|
||||
M_WAITOK | M_ZERO);
|
||||
doublefault_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK |
|
||||
M_ZERO);
|
||||
mce_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO);
|
||||
nmi_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO);
|
||||
dbg_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO);
|
||||
dpcpu = (void *)kmem_malloc(DPCPU_SIZE, M_WAITOK | M_ZERO);
|
||||
doublefault_stack = (char *)kmem_malloc_domainset(
|
||||
DOMAINSET_FIXED(domain), PAGE_SIZE, M_WAITOK | M_ZERO);
|
||||
mce_stack = (char *)kmem_malloc_domainset(
|
||||
DOMAINSET_FIXED(domain), PAGE_SIZE, M_WAITOK | M_ZERO);
|
||||
nmi_stack = (char *)kmem_malloc_domainset(
|
||||
DOMAINSET_FIXED(domain), PAGE_SIZE, M_WAITOK | M_ZERO);
|
||||
dbg_stack = (char *)kmem_malloc_domainset(
|
||||
DOMAINSET_FIXED(domain), PAGE_SIZE, M_WAITOK | M_ZERO);
|
||||
dpcpu = (void *)kmem_malloc_domainset(DOMAINSET_FIXED(domain),
|
||||
DPCPU_SIZE, M_WAITOK | M_ZERO);
|
||||
|
||||
bootSTK = (char *)bootstacks[cpu] + kstack_pages * PAGE_SIZE - 8;
|
||||
bootSTK = (char *)bootstacks[cpu] +
|
||||
kstack_pages * PAGE_SIZE - 8;
|
||||
bootAP = cpu;
|
||||
|
||||
/* attempt to start the Application Processor */
|
||||
|
@ -653,6 +653,17 @@ acpi_pxm_set_cpu_locality(void)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
acpi_pxm_get_cpu_locality(int apic_id)
|
||||
{
|
||||
struct cpu_info *cpu;
|
||||
|
||||
cpu = cpu_find(apic_id);
|
||||
if (cpu == NULL)
|
||||
panic("SRAT: CPU with ID %u is not known", apic_id);
|
||||
return (cpu->domain);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free data structures allocated during acpi_pxm_init.
|
||||
*/
|
||||
|
@ -532,6 +532,7 @@ int acpi_pxm_init(int ncpus, vm_paddr_t maxphys);
|
||||
void acpi_pxm_parse_tables(void);
|
||||
void acpi_pxm_set_mem_locality(void);
|
||||
void acpi_pxm_set_cpu_locality(void);
|
||||
int acpi_pxm_get_cpu_locality(int apic_id);
|
||||
void acpi_pxm_free(void);
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user