Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144725015
D5782.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D5782.diff
View Options
Index: head/sys/conf/NOTES
===================================================================
--- head/sys/conf/NOTES
+++ head/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: head/sys/conf/options
===================================================================
--- head/sys/conf/options
+++ head/sys/conf/options
@@ -90,6 +90,7 @@
COMPILING_LINT opt_global.h
CY_PCI_FASTINTR
DEADLKRES opt_watchdog.h
+DEVICE_NUMA
EXT_RESOURCES opt_global.h
DIRECTIO
FILEMON opt_dontuse.h
@@ -603,6 +604,7 @@
VM_KMEM_SIZE_SCALE opt_vm.h
VM_KMEM_SIZE_MAX opt_vm.h
VM_NRESERVLEVEL opt_vm.h
+VM_NUMA_ALLOC opt_vm.h
VM_LEVEL_0_ORDER opt_vm.h
NO_SWAPPING opt_vm.h
MALLOC_MAKE_FAILURES opt_vm.h
Index: head/sys/dev/acpica/acpi.c
===================================================================
--- head/sys/dev/acpica/acpi.c
+++ head/sys/dev/acpica/acpi.c
@@ -31,6 +31,8 @@
__FBSDID("$FreeBSD$");
#include "opt_acpi.h"
+#include "opt_device_numa.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/proc.h>
@@ -1083,7 +1085,7 @@
int
acpi_parse_pxm(device_t dev, int *domain)
{
-#if MAXMEMDOM > 1
+#ifdef DEVICE_NUMA
ACPI_HANDLE h;
int d, pxm;
Index: head/sys/dev/acpica/acpivar.h
===================================================================
--- head/sys/dev/acpica/acpivar.h
+++ head/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: head/sys/kern/kern_cpuset.c
===================================================================
--- head/sys/kern/kern_cpuset.c
+++ head/sys/kern/kern_cpuset.c
@@ -831,7 +831,7 @@
cpuset_thread0(void)
{
struct cpuset *set;
- int error;
+ int error, i;
cpuset_zone = uma_zcreate("cpuset", sizeof(struct cpuset), NULL, NULL,
NULL, NULL, UMA_ALIGN_PTR, 0);
@@ -863,9 +863,15 @@
*/
cpuset_unr = new_unrhdr(2, INT_MAX, NULL);
- /* MD Code is responsible for initializing sets if vm_ndomains > 1. */
- if (vm_ndomains == 1)
- CPU_COPY(&all_cpus, &cpuset_domain[0]);
+ /*
+ * If MD code has not initialized per-domain cpusets, place all
+ * CPUs in domain 0.
+ */
+ for (i = 0; i < MAXMEMDOM; i++)
+ if (!CPU_EMPTY(&cpuset_domain[i]))
+ goto domains_set;
+ CPU_COPY(&all_cpus, &cpuset_domain[0]);
+domains_set:
return (set);
}
@@ -1118,7 +1124,7 @@
error = intr_getaffinity(uap->id, mask);
break;
case CPU_WHICH_DOMAIN:
- if (uap->id < 0 || uap->id >= vm_ndomains)
+ if (uap->id < 0 || uap->id >= MAXMEMDOM)
error = ESRCH;
else
CPU_COPY(&cpuset_domain[uap->id], mask);
Index: head/sys/vm/vm_domain.c
===================================================================
--- head/sys/vm/vm_domain.c
+++ head/sys/vm/vm_domain.c
@@ -39,7 +39,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
-#if MAXMEMDOM > 1
+#ifdef VM_NUMA_ALLOC
#include <sys/proc.h>
#endif
#include <sys/queue.h>
@@ -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: head/sys/vm/vm_pageout.c
===================================================================
--- head/sys/vm/vm_pageout.c
+++ head/sys/vm/vm_pageout.c
@@ -1656,12 +1656,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: head/sys/vm/vm_phys.h
===================================================================
--- head/sys/vm/vm_phys.h
+++ head/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: head/sys/vm/vm_phys.c
===================================================================
--- head/sys/vm/vm_phys.c
+++ head/sys/vm/vm_phys.c
@@ -48,9 +48,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
-#if MAXMEMDOM > 1
#include <sys/proc.h>
-#endif
#include <sys/queue.h>
#include <sys/rwlock.h>
#include <sys/sbuf.h>
@@ -73,8 +71,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 +144,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 +159,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 +277,7 @@
static __inline int
vm_rr_selectdomain(void)
{
-#if MAXMEMDOM > 1
+#ifdef VM_NUMA_ALLOC
struct thread *td;
td = curthread;
@@ -303,13 +303,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) {
@@ -433,7 +433,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 +444,7 @@
#endif
}
-#if MAXMEMDOM > 1
+#ifdef VM_NUMA_ALLOC
/*
* Outputs the VM locality table.
*/
@@ -520,6 +520,7 @@
static void
vm_phys_create_seg(vm_paddr_t start, vm_paddr_t end)
{
+#ifdef VM_NUMA_ALLOC
int i;
if (mem_affinity == NULL) {
@@ -544,6 +545,9 @@
mem_affinity[i].domain);
start = mem_affinity[i].end;
}
+#else
+ _vm_phys_create_seg(start, end, 0);
+#endif
}
/*
Index: head/sys/x86/acpica/srat.c
===================================================================
--- head/sys/x86/acpica/srat.c
+++ head/sys/x86/acpica/srat.c
@@ -28,6 +28,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_vm.h"
+
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
@@ -62,7 +64,8 @@
static ACPI_TABLE_SRAT *srat;
static vm_paddr_t srat_physaddr;
-static int vm_domains[VM_PHYSSEG_MAX];
+static int domain_pxm[MAXMEMDOM];
+static int ndomain;
static ACPI_TABLE_SLIT *slit;
static vm_paddr_t slit_physaddr;
@@ -145,8 +148,10 @@
acpi_unmap_table(slit);
slit = NULL;
+#ifdef VM_NUMA_ALLOC
/* Tell the VM about it! */
mem_locality = vm_locality_table;
+#endif
return (0);
}
@@ -340,48 +345,46 @@
int i, j, slot;
/* Enumerate all the domains. */
- vm_ndomains = 0;
+ ndomain = 0;
for (i = 0; i < num_mem; i++) {
/* See if this domain is already known. */
- for (j = 0; j < vm_ndomains; j++) {
- if (vm_domains[j] >= mem_info[i].domain)
+ for (j = 0; j < ndomain; j++) {
+ if (domain_pxm[j] >= mem_info[i].domain)
break;
}
- if (j < vm_ndomains && vm_domains[j] == mem_info[i].domain)
+ if (j < ndomain && domain_pxm[j] == mem_info[i].domain)
continue;
/* Insert the new domain at slot 'j'. */
slot = j;
- for (j = vm_ndomains; j > slot; j--)
- vm_domains[j] = vm_domains[j - 1];
- vm_domains[slot] = mem_info[i].domain;
- vm_ndomains++;
- if (vm_ndomains > MAXMEMDOM) {
- vm_ndomains = 1;
+ for (j = ndomain; j > slot; j--)
+ domain_pxm[j] = domain_pxm[j - 1];
+ domain_pxm[slot] = mem_info[i].domain;
+ ndomain++;
+ if (ndomain > MAXMEMDOM) {
+ ndomain = 1;
printf("SRAT: Too many memory domains\n");
return (EFBIG);
}
}
- /* Renumber each domain to its index in the sorted 'domains' list. */
- for (i = 0; i < vm_ndomains; i++) {
+ /* Renumber each domain to its index in the sorted 'domain_pxm' list. */
+ for (i = 0; i < ndomain; i++) {
/*
* If the domain is already the right value, no need
* to renumber.
*/
- if (vm_domains[i] == i)
+ if (domain_pxm[i] == i)
continue;
/* Walk the cpu[] and mem_info[] arrays to renumber. */
for (j = 0; j < num_mem; j++)
- if (mem_info[j].domain == vm_domains[i])
+ if (mem_info[j].domain == domain_pxm[i])
mem_info[j].domain = i;
for (j = 0; j <= MAX_APIC_ID; j++)
- if (cpus[j].enabled && cpus[j].domain == vm_domains[i])
+ if (cpus[j].enabled && cpus[j].domain == domain_pxm[i])
cpus[j].domain = i;
}
- KASSERT(vm_ndomains > 0,
- ("renumber_domains: invalid final vm_ndomains setup"));
return (0);
}
@@ -416,8 +419,11 @@
return (-1);
}
+#ifdef VM_NUMA_ALLOC
/* Point vm_phys at our memory affinity table. */
+ vm_ndomains = ndomain;
mem_affinity = mem_info;
+#endif
return (0);
}
@@ -495,12 +501,21 @@
{
int i;
- for (i = 0; i < vm_ndomains; i++) {
- if (vm_domains[i] == pxm)
+ for (i = 0; i < ndomain; i++) {
+ if (domain_pxm[i] == pxm)
return (i);
}
return (-1);
}
+#else /* MAXMEMDOM == 1 */
+
+int
+acpi_map_pxm_to_vm_domainid(int pxm)
+{
+
+ return (-1);
+}
+
#endif /* MAXMEMDOM > 1 */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 12, 5:37 PM (15 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28668913
Default Alt Text
D5782.diff (11 KB)
Attached To
Mode
D5782: Add more fine-grained kernel options for NUMA support.
Attached
Detach File
Event Timeline
Log In to Comment