Index: sys/conf/NOTES =================================================================== --- sys/conf/NOTES +++ sys/conf/NOTES @@ -229,7 +229,15 @@ # MAXMEMDOM defines the maximum number of memory domains that can boot in the # system. A default value should already be defined by every architecture. -options MAXMEMDOM=1 +options MAXMEMDOM=2 + +# VM_NUMA_ALLOC enables use of memory domain-aware allocation in the VM +# system. +options VM_NUMA_ALLOC + +# DEVICE_NUMA enables reporting of domain affinity of I/O devices via +# bus_get_domain(), etc. +options DEVICE_NUMA # ADAPTIVE_MUTEXES changes the behavior of blocking mutexes to spin # if the thread that currently owns the mutex is executing on another Index: sys/conf/options =================================================================== --- sys/conf/options +++ sys/conf/options @@ -597,6 +597,8 @@ RWLOCK_NOINLINE opt_global.h SX_NOINLINE opt_global.h VFS_BIO_DEBUG opt_global.h +VM_NUMA_ALLOC opt_global.h +DEVICE_NUMA opt_global.h # These are VM related options VM_KMEM_SIZE opt_vm.h Index: sys/dev/acpica/acpi.c =================================================================== --- sys/dev/acpica/acpi.c +++ sys/dev/acpica/acpi.c @@ -1083,7 +1083,7 @@ int acpi_parse_pxm(device_t dev, int *domain) { -#if MAXMEMDOM > 1 +#ifdef DEVICE_NUMA ACPI_HANDLE h; int d, pxm; Index: sys/dev/acpica/acpivar.h =================================================================== --- sys/dev/acpica/acpivar.h +++ sys/dev/acpica/acpivar.h @@ -502,9 +502,7 @@ * * Returns the VM domain ID if found, or -1 if not found / invalid. */ -#if MAXMEMDOM > 1 extern int acpi_map_pxm_to_vm_domainid(int pxm); -#endif extern int acpi_get_domain(device_t dev, device_t child, int *domain); extern int acpi_parse_pxm(device_t dev, int *domain); Index: sys/vm/vm_domain.c =================================================================== --- sys/vm/vm_domain.c +++ sys/vm/vm_domain.c @@ -39,7 +39,7 @@ #include #include #include -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC #include #endif #include @@ -64,7 +64,7 @@ static __inline int vm_domain_rr_selectdomain(int skip_domain) { -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC struct thread *td; td = curthread; @@ -188,8 +188,13 @@ return (-1); case VM_POLICY_FIXED_DOMAIN: case VM_POLICY_FIXED_DOMAIN_ROUND_ROBIN: +#ifdef VM_NUMA_ALLOC if (vp->p.domain >= 0 && vp->p.domain < vm_ndomains) return (0); +#else + if (vp->p.domain == 0) + return (0); +#endif return (-1); default: return (-1); @@ -221,6 +226,7 @@ vm_domain_policy_type_t vt, int domain) { +#ifdef VM_NUMA_ALLOC switch (vt) { case VM_POLICY_FIXED_DOMAIN: vi->policy = VM_POLICY_FIXED_DOMAIN; @@ -249,6 +255,10 @@ vi->n = vm_ndomains; break; } +#else + vi->domain = 0; + vi->n = 1; +#endif return (0); } @@ -259,6 +269,8 @@ _vm_domain_iterator_set_policy(struct vm_domain_iterator *vi, const struct vm_domain_policy *vt) { + +#ifdef VM_NUMA_ALLOC /* * Initialise the iterator. * @@ -300,6 +312,10 @@ vi->n = vm_ndomains; break; } +#else + vi->domain = 0; + vi->n = 1; +#endif } void @@ -334,6 +350,7 @@ if (vi->n <= 0) return (-1); +#ifdef VM_NUMA_ALLOC switch (vi->policy) { case VM_POLICY_FIXED_DOMAIN: case VM_POLICY_FIRST_TOUCH: @@ -358,6 +375,10 @@ vi->n--; break; } +#else + *domain = 0; + vi->n--; +#endif return (0); } Index: sys/vm/vm_page.c =================================================================== --- sys/vm/vm_page.c +++ sys/vm/vm_page.c @@ -466,7 +466,11 @@ mtx_init(&vm_page_queue_free_mtx, "vm page free queue", NULL, MTX_DEF); for (i = 0; i < PA_LOCK_COUNT; i++) mtx_init(&pa_lock[i], "vm page", NULL, MTX_DEF); +#ifdef VM_NUMA_ALLOC for (i = 0; i < vm_ndomains; i++) +#else + for (i = 0; i < 1; i++) +#endif vm_page_domain_init(&vm_dom[i]); /* @@ -3895,7 +3899,11 @@ db_printf("pq_free %d pq_cache %d\n", vm_cnt.v_free_count, vm_cnt.v_cache_count); +#ifdef VM_NUMA_ALLOC for (dom = 0; dom < vm_ndomains; dom++) { +#else + for (dom = 0; dom < 1; dom++) { +#endif db_printf( "dom %d page_cnt %d free %d pq_act %d pq_inact %d pass %d\n", dom, Index: sys/vm/vm_pageout.c =================================================================== --- sys/vm/vm_pageout.c +++ sys/vm/vm_pageout.c @@ -1341,8 +1341,10 @@ vmd->vmd_oom = TRUE; old_vote = atomic_fetchadd_int(&vm_pageout_oom_vote, 1); +#ifdef VM_NUMA_ALLOC if (old_vote != vm_ndomains - 1) return; +#endif /* * The current pagedaemon thread is the last in the quorum to @@ -1656,12 +1658,12 @@ vm_pageout(void) { int error; -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC int i; #endif swap_pager_swap_init(); -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC for (i = 1; i < vm_ndomains; i++) { error = kthread_add(vm_pageout_worker, (void *)(uintptr_t)i, curproc, NULL, 0, 0, "dom%d", i); Index: sys/vm/vm_phys.h =================================================================== --- sys/vm/vm_phys.h +++ sys/vm/vm_phys.h @@ -99,7 +99,7 @@ static inline struct vm_domain * vm_phys_domain(vm_page_t m) { -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC int domn, segind; /* XXXKIB try to assert that the page is managed */ Index: sys/vm/vm_phys.c =================================================================== --- sys/vm/vm_phys.c +++ sys/vm/vm_phys.c @@ -48,7 +48,7 @@ #include #include #include -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC #include #endif #include @@ -73,8 +73,10 @@ _Static_assert(sizeof(long) * NBBY >= VM_PHYSSEG_MAX, "Too many physsegs."); +#ifdef VM_NUMA_ALLOC struct mem_affinity *mem_affinity; int *mem_locality; +#endif int vm_ndomains = 1; @@ -144,7 +146,7 @@ SYSCTL_OID(_vm, OID_AUTO, phys_segs, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, sysctl_vm_phys_segs, "A", "Phys Seg Info"); -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC static int sysctl_vm_phys_locality(SYSCTL_HANDLER_ARGS); SYSCTL_OID(_vm, OID_AUTO, phys_locality, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, sysctl_vm_phys_locality, "A", "Phys Locality Info"); @@ -159,7 +161,7 @@ static struct mtx vm_default_policy_mtx; MTX_SYSINIT(vm_default_policy, &vm_default_policy_mtx, "default policy mutex", MTX_DEF); -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC static struct vm_domain_policy vm_default_policy = VM_DOMAIN_POLICY_STATIC_INITIALISER(VM_POLICY_FIRST_TOUCH_ROUND_ROBIN, 0); #else @@ -277,7 +279,7 @@ static __inline int vm_rr_selectdomain(void) { -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC struct thread *td; td = curthread; @@ -303,13 +305,13 @@ static void vm_policy_iterator_init(struct vm_domain_iterator *vi) { -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC struct vm_domain_policy lcl; #endif vm_domain_iterator_init(vi); -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC /* Copy out the thread policy */ vm_domain_policy_localcopy(&lcl, &curthread->td_vm_dom_policy); if (lcl.p.policy != VM_POLICY_NONE) { @@ -368,7 +370,11 @@ if (error != 0) return (error); sbuf_new_for_sysctl(&sbuf, NULL, 128 * vm_ndomains, req); +#ifdef VM_NUMA_ALLOC for (dom = 0; dom < vm_ndomains; dom++) { +#else + for (dom = 0; dom < 1; dom++) { +#endif sbuf_printf(&sbuf,"\nDOMAIN %d:\n", dom); for (flind = 0; flind < vm_nfreelists; flind++) { sbuf_printf(&sbuf, "\nFREE LIST %d:\n" @@ -433,7 +439,7 @@ vm_phys_mem_affinity(int f, int t) { -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC if (mem_locality == NULL) return (-1); if (f >= vm_ndomains || t >= vm_ndomains) @@ -444,7 +450,7 @@ #endif } -#if MAXMEMDOM > 1 +#ifdef VM_NUMA_ALLOC /* * Outputs the VM locality table. */ @@ -520,11 +526,14 @@ static void vm_phys_create_seg(vm_paddr_t start, vm_paddr_t end) { +#ifdef VM_NUMA_ALLOC int i; if (mem_affinity == NULL) { +#endif _vm_phys_create_seg(start, end, 0); return; +#ifdef VM_NUMA_ALLOC } for (i = 0;; i++) { @@ -544,6 +553,7 @@ mem_affinity[i].domain); start = mem_affinity[i].end; } +#endif } /* @@ -695,7 +705,11 @@ /* * Initialize the free queues. */ +#ifdef VM_NUMA_ALLOC for (dom = 0; dom < vm_ndomains; dom++) { +#else + for (dom = 0; dom < 1; dom++) { +#endif for (flind = 0; flind < vm_nfreelists; flind++) { for (pind = 0; pind < VM_NFREEPOOL; pind++) { fl = vm_phys_free_queues[dom][flind][pind]; @@ -1496,7 +1510,11 @@ struct vm_freelist *fl; int flind, oind, pind, dom; +#ifdef VM_NUMA_ALLOC for (dom = 0; dom < vm_ndomains; dom++) { +#else + for (dom = 0; dom < 1; dom++) { +#endif db_printf("DOMAIN: %d\n", dom); for (flind = 0; flind < vm_nfreelists; flind++) { db_printf("FREE LIST %d:\n" Index: sys/x86/acpica/srat.c =================================================================== --- sys/x86/acpica/srat.c +++ sys/x86/acpica/srat.c @@ -145,8 +145,10 @@ acpi_unmap_table(slit); slit = NULL; +#ifdef VM_NUMA_ALLOC /* Tell the VM about it! */ mem_locality = vm_locality_table; +#endif return (0); } @@ -416,8 +418,10 @@ return (-1); } +#ifdef VM_NUMA_ALLOC /* Point vm_phys at our memory affinity table. */ mem_affinity = mem_info; +#endif return (0); } @@ -503,4 +507,13 @@ return (-1); } +#else /* MAXMEMDOM == 1 */ + +int +acpi_map_pxm_to_vm_domainid(int pxm) +{ + + return (-1); +} + #endif /* MAXMEMDOM > 1 */