|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 13/15] x86/PVH: prefer smaller E820 regions for stealing from
Nibbling from the end of large regions tends to split full 2Mb (or even
full 1Gb) ranges, which Dom0 may otherwise be able to use superpage
mappings for (when, like Linux, it e.g. has a direct-map).
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
Instead of comparing original sizes, we may want to compare remaining
sizes. That may (slightly) further increase the risk of successive steals
not ending up adjacent, though.
There is the (pre-existing and purely theoretical at this point) risk of
(entry->addr + entry->size - size) underflowing. Do we think we need to
cover that remote case?
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -192,6 +192,7 @@ static int __init pvh_steal_ram(struct d
paddr_t kernel_start = (paddr_t)elf->dest_base & PAGE_MASK;
paddr_t kernel_end = ROUNDUP((paddr_t)elf->dest_base + elf->dest_size,
PAGE_SIZE);
+ struct e820entry *good = NULL;
unsigned int i = d->arch.nr_e820;
/*
@@ -202,26 +203,35 @@ static int __init pvh_steal_ram(struct d
while ( i-- )
{
struct e820entry *entry = &d->arch.e820[i];
+ paddr_t res;
if ( entry->type != E820_RAM || entry->addr + entry->size > limit )
continue;
- *addr = (entry->addr + entry->size - size) & ~(align - 1);
+ res = (entry->addr + entry->size - size) & ~(align - 1);
/* Avoid kernel range, if this is the region it lives in. */
- if ( *addr < kernel_end && *addr + size > kernel_start )
- *addr = (kernel_start - size) & ~(align - 1);
+ if ( res < kernel_end && res + size > kernel_start )
+ res = (kernel_start - size) & ~(align - 1);
- if ( *addr < entry->addr ||
+ if ( res < entry->addr ||
/* Don't steal from the low 1MB due to the copying done there. */
- *addr < MB(1) )
+ res < MB(1) )
continue;
- entry->size = *addr - entry->addr;
- return 0;
+ if ( !good || good->size > entry->size )
+ {
+ good = entry;
+ *addr = res;
+ }
}
- return -ENOMEM;
+ if ( !good )
+ return -ENOMEM;
+
+ good->size = *addr - good->addr;
+
+ return 0;
}
/* NB: memory map must be sorted at all times for this to work correctly. */
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |