Index: share/man/man4/numa.4 =================================================================== --- share/man/man4/numa.4 +++ share/man/man4/numa.4 @@ -24,15 +24,15 @@ .\" .\" $FreeBSD$ .\" -.Dd July 10, 2018 +.Dd October 5, 2018 .Dt NUMA 4 .Os .Sh NAME .Nm NUMA .Nd Non-Uniform Memory Access .Sh SYNOPSIS -.Cd options SMP -.Cd options MAXMEMDOM=16 +.Cd options MAXMEMDOM +.Cd options NUMA .Pp .In sys/cpuset.h .In sys/bus.h @@ -47,14 +47,26 @@ depends upon which processor the memory or device is attached to. Accessing memory local to a processor is faster than accessing memory that is connected to one of the other processors. +.Fx +implements NUMA-aware memory allocation policies. +By default it attempts to ensure that allocations are balanced across +each domain. +Users may override the default domain selection policy using +.Xr cpuset 1 . .Pp .Nm -is enabled when the +support is enabled when the .Cd NUMA -option is used in a kernel configuration -file and the +option is specified in the kernel configuration file. +Each platform defines the .Cd MAXMEMDOM -option is set to a value greater than 1. +constant, which specifies the maximum number of supported NUMA domains. +This constant may be specified in the kernel configuration file. +.Nm +support can be disabled at boot time by setting the +.Va vm.ndomains +tunable to 1. +Other values for this tunable are currently ignored. .Pp Thread and process .Nm @@ -128,7 +140,7 @@ .Fx 11.0 and were removed in .Fx 12.0 . -Current implementation appeared in +The current implementation appeared in .Fx 12.0 . .Pp .Sh AUTHORS Index: sys/arm64/arm64/mp_machdep.c =================================================================== --- sys/arm64/arm64/mp_machdep.c +++ sys/arm64/arm64/mp_machdep.c @@ -576,11 +576,12 @@ return (FALSE); /* Try to read the numa node of this cpu */ - if (OF_getencprop(node, "numa-node-id", &domain, sizeof(domain)) > 0) { - __pcpu[id].pc_domain = domain; - if (domain < MAXMEMDOM) - CPU_SET(id, &cpuset_domain[domain]); - } + if (vm_ndomains > 1 && + OF_getencprop(node, "numa-node-id", &domain, sizeof(domain)) <= 0) + domain = 0; + __pcpu[id].pc_domain = domain; + if (domain < MAXMEMDOM) + CPU_SET(id, &cpuset_domain[domain]); return (TRUE); } Index: sys/kern/kern_cpuset.c =================================================================== --- sys/kern/kern_cpuset.c +++ sys/kern/kern_cpuset.c @@ -457,6 +457,12 @@ struct domainset *ndomain; int i, j, max; + KASSERT(domain->ds_cnt <= vm_ndomains, + ("invalid domain count in domainset %p", domain)); + KASSERT(domain->ds_policy != DOMAINSET_POLICY_PREFER || + domain->ds_prefer < vm_ndomains, + ("invalid preferred domain in domains %p", domain)); + mtx_lock_spin(&cpuset_lock); LIST_FOREACH(ndomain, &cpuset_domains, ds_link) if (domainset_equal(ndomain, domain)) Index: sys/vm/vm_phys.c =================================================================== --- sys/vm/vm_phys.c +++ sys/vm/vm_phys.c @@ -597,11 +597,22 @@ int *locality) { #ifdef NUMA - int i; + int i, n; - vm_ndomains = ndomains; - mem_affinity = affinity; - mem_locality = locality; + /* + * For now the only override value that we support is 1, which + * effectively disables NUMA-awareness in the allocators. + */ + n = ndomains; + TUNABLE_INT_FETCH("vm.ndomains", &n); + if (n == 1) + ndomains = 1; + + if (ndomains > 1) { + vm_ndomains = ndomains; + mem_affinity = affinity; + mem_locality = locality; + } for (i = 0; i < vm_ndomains; i++) DOMAINSET_SET(i, &all_domains); Index: sys/x86/acpica/srat.c =================================================================== --- sys/x86/acpica/srat.c +++ sys/x86/acpica/srat.c @@ -535,11 +535,7 @@ if (!cpu->enabled) panic("SRAT: CPU with APIC ID %u is not known", pc->pc_apic_id); -#ifdef NUMA - pc->pc_domain = cpu->domain; -#else - pc->pc_domain = 0; -#endif + pc->pc_domain = vm_ndomains > 1 ? cpu->domain : 0; CPU_SET(i, &cpuset_domain[pc->pc_domain]); if (bootverbose) printf("SRAT: CPU %u has memory domain %d\n", i, @@ -564,7 +560,7 @@ for (i = 0; i < ndomain; i++) { if (domain_pxm[i] == pxm) - return (i); + return (vm_ndomains > 1 ? i : 0); } return (-1);