Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F110658588
D2460.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D2460.diff
View Options
Index: head/sys/vm/vm_phys.h
===================================================================
--- head/sys/vm/vm_phys.h
+++ head/sys/vm/vm_phys.h
@@ -61,6 +61,7 @@
};
extern struct mem_affinity *mem_affinity;
+int *mem_locality;
extern int vm_ndomains;
extern struct vm_phys_seg vm_phys_segs[];
extern int vm_phys_nsegs;
Index: head/sys/vm/vm_phys.c
===================================================================
--- head/sys/vm/vm_phys.c
+++ head/sys/vm/vm_phys.c
@@ -71,6 +71,7 @@
"Too many physsegs.");
struct mem_affinity *mem_affinity;
+int *mem_locality;
int vm_ndomains = 1;
@@ -140,6 +141,10 @@
SYSCTL_OID(_vm, OID_AUTO, phys_segs, CTLTYPE_STRING | CTLFLAG_RD,
NULL, 0, sysctl_vm_phys_segs, "A", "Phys Seg Info");
+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");
+
SYSCTL_INT(_vm, OID_AUTO, ndomains, CTLFLAG_RD,
&vm_ndomains, 0, "Number of physical memory domains available.");
@@ -297,6 +302,48 @@
return (error);
}
+/*
+ * Return affinity, or -1 if there's no affinity information.
+ */
+static int
+vm_phys_mem_affinity(int f, int t)
+{
+
+ if (mem_locality == NULL)
+ return (-1);
+ if (f >= vm_ndomains || t >= vm_ndomains)
+ return (-1);
+ return (mem_locality[f * vm_ndomains + t]);
+}
+
+/*
+ * Outputs the VM locality table.
+ */
+static int
+sysctl_vm_phys_locality(SYSCTL_HANDLER_ARGS)
+{
+ struct sbuf sbuf;
+ int error, i, j;
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+ sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
+
+ sbuf_printf(&sbuf, "\n");
+
+ for (i = 0; i < vm_ndomains; i++) {
+ sbuf_printf(&sbuf, "%d: ", i);
+ for (j = 0; j < vm_ndomains; j++) {
+ sbuf_printf(&sbuf, "%d ", vm_phys_mem_affinity(i, j));
+ }
+ sbuf_printf(&sbuf, "\n");
+ }
+ error = sbuf_finish(&sbuf);
+ sbuf_delete(&sbuf);
+ return (error);
+}
+
static void
vm_freelist_add(struct vm_freelist *fl, vm_page_t m, int order, int tail)
{
Index: head/sys/x86/acpica/srat.c
===================================================================
--- head/sys/x86/acpica/srat.c
+++ head/sys/x86/acpica/srat.c
@@ -64,9 +64,97 @@
static int vm_domains[VM_PHYSSEG_MAX];
+static ACPI_TABLE_SLIT *slit;
+static vm_paddr_t slit_physaddr;
+static int vm_locality_table[MAXMEMDOM * MAXMEMDOM];
+
static void srat_walk_table(acpi_subtable_handler *handler, void *arg);
/*
+ * SLIT parsing.
+ */
+
+static void
+slit_parse_table(ACPI_TABLE_SLIT *s)
+{
+ int i, j;
+ int i_domain, j_domain;
+ int offset = 0;
+ uint8_t e;
+
+ /*
+ * This maps the SLIT data into the VM-domain centric view.
+ * There may be sparse entries in the PXM namespace, so
+ * remap them to a VM-domain ID and if it doesn't exist,
+ * skip it.
+ *
+ * It should result in a packed 2d array of VM-domain
+ * locality information entries.
+ */
+
+ if (bootverbose)
+ printf("SLIT.Localities: %d\n", (int) s->LocalityCount);
+ for (i = 0; i < s->LocalityCount; i++) {
+ i_domain = acpi_map_pxm_to_vm_domainid(i);
+ if (i_domain < 0)
+ continue;
+
+ if (bootverbose)
+ printf("%d: ", i);
+ for (j = 0; j < s->LocalityCount; j++) {
+ j_domain = acpi_map_pxm_to_vm_domainid(j);
+ if (j_domain < 0)
+ continue;
+ e = s->Entry[i * s->LocalityCount + j];
+ if (bootverbose)
+ printf("%d ", (int) e);
+ /* 255 == "no locality information" */
+ if (e == 255)
+ vm_locality_table[offset] = -1;
+ else
+ vm_locality_table[offset] = e;
+ offset++;
+ }
+ if (bootverbose)
+ printf("\n");
+ }
+}
+
+/*
+ * Look for an ACPI System Locality Distance Information Table ("SLIT")
+ */
+static int
+parse_slit(void)
+{
+
+ if (resource_disabled("slit", 0)) {
+ return (-1);
+ }
+
+ slit_physaddr = acpi_find_table(ACPI_SIG_SLIT);
+ if (slit_physaddr == 0) {
+ return (-1);
+ }
+
+ /*
+ * Make a pass over the table to populate the cpus[] and
+ * mem_info[] tables.
+ */
+ slit = acpi_map_table(slit_physaddr, ACPI_SIG_SLIT);
+ slit_parse_table(slit);
+ acpi_unmap_table(slit);
+ slit = NULL;
+
+ /* Tell the VM about it! */
+ mem_locality = vm_locality_table;
+ return (0);
+}
+
+/*
+ * SRAT parsing.
+ */
+
+/*
* Returns true if a memory range overlaps with at least one range in
* phys_avail[].
*/
@@ -301,17 +389,17 @@
/*
* Look for an ACPI System Resource Affinity Table ("SRAT")
*/
-static void
-parse_srat(void *dummy)
+static int
+parse_srat(void)
{
int error;
if (resource_disabled("srat", 0))
- return;
+ return (-1);
srat_physaddr = acpi_find_table(ACPI_SIG_SRAT);
if (srat_physaddr == 0)
- return;
+ return (-1);
/*
* Make a pass over the table to populate the cpus[] and
@@ -325,13 +413,39 @@
if (error || check_domains() != 0 || check_phys_avail() != 0 ||
renumber_domains() != 0) {
srat_physaddr = 0;
- return;
+ return (-1);
}
/* Point vm_phys at our memory affinity table. */
mem_affinity = mem_info;
+
+ return (0);
+}
+
+static void
+init_mem_locality(void)
+{
+ int i;
+
+ /*
+ * For now, assume 255 == "no locality information for
+ * this pairing.
+ */
+ for (i = 0; i < MAXMEMDOM * MAXMEMDOM; i++)
+ vm_locality_table[i] = -1;
+}
+
+static void
+parse_acpi_tables(void *dummy)
+{
+
+ if (parse_srat() < 0)
+ return;
+ init_mem_locality();
+ (void) parse_slit();
}
-SYSINIT(parse_srat, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_srat, NULL);
+SYSINIT(parse_acpi_tables, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_acpi_tables,
+ NULL);
static void
srat_walk_table(acpi_subtable_handler *handler, void *arg)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 22, 1:45 PM (1 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16772563
Default Alt Text
D2460.diff (5 KB)
Attached To
Mode
D2460: Add SLIT enumeration and memory locality table to VM/ACPI.
Attached
Detach File
Event Timeline
Log In to Comment