diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-08-25 14:58:42 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-08-25 14:58:42 +0100 |
commit | 92f8888d407253a91e15b0be92002e5e23f9c1c3 (patch) | |
tree | a0b8ea9082d71690bb0a3af1b651f14b3b1d3ebb /xen/arch/x86/srat.c | |
parent | 1e52826824aa236e1fb27e9aa21c72432dbf399a (diff) | |
download | xen-92f8888d407253a91e15b0be92002e5e23f9c1c3.tar.gz xen-92f8888d407253a91e15b0be92002e5e23f9c1c3.tar.bz2 xen-92f8888d407253a91e15b0be92002e5e23f9c1c3.zip |
x86 numa: Fix SRAT check for discontig memory
We currently compare the sum of the pages found in the SRAT table to
the address of the highest memory page found via the e820 table to
validate the SRAT. This is completely bogus if there's any kind of
discontiguous memory, where the sum of the pages could be much smaller
than the address of the highest page. I think all that's necessary is
to validate that each usable memory range in the e820 is covered by an
SRAT entry. This might not be the most efficient way to do it, but
there are usually a relatively small number of entries on each side.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Diffstat (limited to 'xen/arch/x86/srat.c')
-rw-r--r-- | xen/arch/x86/srat.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c index 7f90e09685..b49654b78e 100644 --- a/xen/arch/x86/srat.c +++ b/xen/arch/x86/srat.c @@ -17,6 +17,7 @@ #include <xen/nodemask.h> #include <xen/acpi.h> #include <xen/numa.h> +#include <asm/e820.h> #include <asm/page.h> static struct acpi_table_slit *acpi_slit; @@ -236,23 +237,31 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) static int nodes_cover_memory(void) { int i; - u64 pxmram, e820ram; - pxmram = 0; - for_each_node_mask(i, nodes_parsed) { - u64 s = nodes[i].start >> PAGE_SHIFT; - u64 e = nodes[i].end >> PAGE_SHIFT; - pxmram += e - s; - } + for (i = 0; i < e820.nr_map; i++) { + int j, found; + unsigned long long start, end; + + if (e820.map[i].type != E820_RAM) { + continue; + } - e820ram = max_page; - /* We seem to lose 3 pages somewhere. Allow a bit of slack. */ - if ((long)(e820ram - pxmram) >= 1*1024*1024) { - printk(KERN_ERR "SRAT: PXMs only cover %"PRIu64"MB of your %" - PRIu64"MB e820 RAM. Not used.\n", - (pxmram << PAGE_SHIFT) >> 20, - (e820ram << PAGE_SHIFT) >> 20); - return 0; + start = e820.map[i].addr; + end = e820.map[i].addr + e820.map[i].size - 1; + + found = 0; + for_each_node_mask(j, nodes_parsed) { + if (start >= nodes[j].start && end <= nodes[j].end) { + found = 1; + break; + } + } + + if (!found) { + printk(KERN_ERR "SRAT: No PXM for e820 range: " + "%016Lx - %016Lx\n", start, end); + return 0; + } } return 1; } |