aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/srat.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-08-25 14:58:42 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-08-25 14:58:42 +0100
commit92f8888d407253a91e15b0be92002e5e23f9c1c3 (patch)
treea0b8ea9082d71690bb0a3af1b651f14b3b1d3ebb /xen/arch/x86/srat.c
parent1e52826824aa236e1fb27e9aa21c72432dbf399a (diff)
downloadxen-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.c39
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;
}