diff options
author | jhb <jhb@FreeBSD.org> | 2012-01-03 20:53:58 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-01-03 20:53:58 +0000 |
commit | 6d5201fff5de9848473516a5a44af10d3453890c (patch) | |
tree | a20bb1afc42a8b4194be47565b5a0b77a26ac301 /sys/x86 | |
parent | b168d78675f739ce802bf0e2264c8ae4c538e984 (diff) | |
download | FreeBSD-src-6d5201fff5de9848473516a5a44af10d3453890c.zip FreeBSD-src-6d5201fff5de9848473516a5a44af10d3453890c.tar.gz |
Fix a few bugs in the SRAT parsing code:
- Actually increment ndomain when building our list of known domains
so that we can properly renumber them to be 0-based and dense.
- If the number of domains exceeds the configured maximum (VM_NDOMAIN),
bail out of processing the SRAT and disable NUMA rather than hitting an
obscure panic later.
- Don't bother parsing the SRAT at all if VM_NDOMAIN is set to 1 to
disable NUMA (the default).
Reported by: phk (2)
MFC after: 1 week
Diffstat (limited to 'sys/x86')
-rw-r--r-- | sys/x86/acpica/srat.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/x86/acpica/srat.c b/sys/x86/acpica/srat.c index cd04f87..6c6eb8f 100644 --- a/sys/x86/acpica/srat.c +++ b/sys/x86/acpica/srat.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <dev/acpica/acpivar.h> +#if VM_NDOMAIN > 1 struct cpu_info { int enabled:1; int has_memory:1; @@ -237,9 +238,9 @@ check_phys_avail(void) /* * Renumber the memory domains to be compact and zero-based if not - * already. + * already. Returns an error if there are too many domains. */ -static void +static int renumber_domains(void) { int domains[VM_PHYSSEG_MAX]; @@ -261,6 +262,11 @@ renumber_domains(void) for (j = ndomain; j > slot; j--) domains[j] = domains[j - 1]; domains[slot] = mem_info[i].domain; + ndomain++; + if (ndomain > VM_NDOMAIN) { + printf("SRAT: Too many memory domains\n"); + return (EFBIG); + } } /* Renumber each domain to its index in the sorted 'domains' list. */ @@ -280,6 +286,7 @@ renumber_domains(void) if (cpus[j].enabled && cpus[j].domain == domains[i]) cpus[j].domain = i; } + return (0); } /* @@ -306,13 +313,12 @@ parse_srat(void *dummy) srat_walk_table(srat_parse_entry, &error); acpi_unmap_table(srat); srat = NULL; - if (error || check_domains() != 0 || check_phys_avail() != 0) { + if (error || check_domains() != 0 || check_phys_avail() != 0 || + renumber_domains() != 0) { srat_physaddr = 0; return; } - renumber_domains(); - /* Point vm_phys at our memory affinity table. */ mem_affinity = mem_info; } @@ -354,3 +360,4 @@ srat_set_cpus(void *dummy) } } SYSINIT(srat_set_cpus, SI_SUB_CPU, SI_ORDER_ANY, srat_set_cpus, NULL); +#endif /* VM_NDOMAIN > 1 */ |