# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Node ID 65a41e3206ac2e8347a9649d2ffa3d252e9815d2
# Parent 536c25a9654d4d3376edd2824e24dd486835c472
Fix the memory reservation calculations. Introduce a new architecture-specific
call to determine the initial reservation separately from the amount of
memory to be freed up by ballooning -- when using QEMU, we lose 8 MiB to video
RAM, which must be accounted for when ballooning, but _not_ accounted for
within the domain's memory allocation.
Tidy this code up using the new architecture-specific interface arrangement.
Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
---
tools/python/xen/xend/XendDomainInfo.py | 37 ++++++++++++++++----------
tools/python/xen/xend/image.py | 45 ++++++++++++++++++++++++--------
2 files changed, 58 insertions(+), 24 deletions(-)
diff -r 536c25a9654d -r 65a41e3206ac tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Tue Sep 05 14:17:49 2006 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py Tue Sep 05 14:17:50 2006 +0100
@@ -1285,28 +1285,37 @@ class XendDomainInfo:
for v in range(0, self.info['max_vcpu_id']+1):
xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
+ # Use architecture- and image-specific calculations to determine
+ # the various headrooms necessary, given the raw configured
+ # values.
+ # reservation, maxmem, memory, and shadow are all in KiB.
+ reservation = self.image.getRequiredInitialReservation(
+ self.info['memory'] * 1024)
+ maxmem = self.image.getRequiredAvailableMemory(
+ self.info['maxmem'] * 1024)
+ memory = self.image.getRequiredAvailableMemory(
+ self.info['memory'] * 1024)
+ shadow = self.image.getRequiredShadowMemory(
+ self.info['shadow_memory'] * 1024,
+ self.info['maxmem'] * 1024)
+
+ # Round shadow up to a multiple of a MiB, as shadow_mem_control
+ # takes MiB and we must not round down and end up under-providing.
+ shadow = ((shadow + 1023) / 1024) * 1024
+
# set memory limit
- maxmem = self.image.getRequiredMemory(self.info['maxmem'] * 1024)
xc.domain_setmaxmem(self.domid, maxmem)
- mem_kb = self.image.getRequiredMemory(self.info['memory'] * 1024)
-
- # get the domain's shadow memory requirement
- shadow_kb = self.image.getRequiredShadowMemory(mem_kb)
- shadow_kb_req = self.info['shadow_memory'] * 1024
- if shadow_kb_req > shadow_kb:
- shadow_kb = shadow_kb_req
- shadow_mb = (shadow_kb + 1023) / 1024
-
# Make sure there's enough RAM available for the domain
- balloon.free(mem_kb + shadow_mb * 1024)
+ balloon.free(memory + shadow)
# Set up the shadow memory
- shadow_cur = xc.shadow_mem_control(self.domid, shadow_mb)
+ shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024)
self.info['shadow_memory'] = shadow_cur
- # initial memory allocation
- xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0)
+ # initial memory reservation
+ xc.domain_memory_increase_reservation(self.domid, reservation, 0,
+ 0)
self.createChannels()
diff -r 536c25a9654d -r 65a41e3206ac tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Tue Sep 05 14:17:49 2006 +0100
+++ b/tools/python/xen/xend/image.py Tue Sep 05 14:17:50 2006 +0100
@@ -143,12 +143,27 @@ class ImageHandler:
raise VmError('Building domain failed: ostype=%s dom=%d err=%s'
% (self.ostype, self.vm.getDomid(), str(result)))
- def getRequiredMemory(self, mem_kb):
+ def getRequiredAvailableMemory(self, mem_kb):
+ """@param mem_kb The configured maxmem or memory, in KiB.
+ @return The corresponding required amount of memory for the domain,
+ also in KiB. This is normally the given mem_kb, but architecture- or
+ image-specific code may override this to add headroom where
+ necessary."""
return mem_kb
- def getRequiredShadowMemory(self, mem_kb):
- """@return The minimum shadow memory required, in KiB, for a domain
- with mem_kb KiB of RAM."""
+ def getRequiredInitialReservation(self, mem_kb):
+ """@param mem_kb The configured memory, in KiB.
+ @return The corresponding required amount of memory to be free, also
+ in KiB. This is normally the same as getRequiredAvailableMemory, but
+ architecture- or image-specific code may override this to
+ add headroom where necessary."""
+ return self.getRequiredAvailableMemory(mem_kb)
+
+ def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+ """@param shadow_mem_kb The configured shadow memory, in KiB.
+ @param maxmem_kb The configured maxmem, in KiB.
+ @return The corresponding required amount of shadow memory, also in
+ KiB."""
# PV domains don't need any shadow memory
return 0
@@ -418,7 +433,7 @@ class IA64_HVM_ImageHandler(HVMImageHand
ostype = "hvm"
- def getRequiredMemory(self, mem_kb):
+ def getRequiredAvailableMemory(self, mem_kb):
page_kb = 16
# ROM size for guest firmware, ioreq page and xenstore page
extra_pages = 1024 + 2
@@ -432,19 +447,29 @@ class X86_HVM_ImageHandler(HVMImageHandl
ostype = "hvm"
- def getRequiredMemory(self, mem_kb):
+ def getRequiredAvailableMemory(self, mem_kb):
page_kb = 4
# This was derived emperically:
- # 2.4 MB overhead per 1024 MB RAM + 8 MB constant
+ # 2.4 MB overhead per 1024 MB RAM
# + 4 to avoid low-memory condition
- extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12;
+ extra_mb = (2.4/1024) * (mem_kb/1024.0) + 4;
extra_pages = int( math.ceil( extra_mb*1024 / page_kb ))
return mem_kb + extra_pages * page_kb
- def getRequiredShadowMemory(self, mem_kb):
+ def getRequiredInitialReservation(self, mem_kb):
+ # Add 8 MiB overhead for QEMU's video RAM.
+ return self.getRequiredAvailableMemory(mem_kb) + 8192
+
+ def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+ # The given value is the configured value -- we need to include the
+ # overhead due to getRequiredMemory.
+ maxmem_kb = self.getRequiredMemory(maxmem_kb)
+
# 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than
# the minimum that Xen would allocate if no value were given.
- return 1024 * self.vm.getVCpuCount() + mem_kb / 256
+ return max(1024 * self.vm.getVCpuCount() + maxmem_kb / 256,
+ shadow_mem_kb)
+
_handlers = {
"powerpc": {
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|