direct-io.hg
changeset 11417:65a41e3206ac
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@xensource.com>
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@xensource.com>
author | Ewan Mellor <ewan@xensource.com> |
---|---|
date | Tue Sep 05 14:17:50 2006 +0100 (2006-09-05) |
parents | 536c25a9654d |
children | 45746c770018 |
files | tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py |
line diff
1.1 --- a/tools/python/xen/xend/XendDomainInfo.py Tue Sep 05 14:17:49 2006 +0100 1.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Sep 05 14:17:50 2006 +0100 1.3 @@ -1285,28 +1285,37 @@ class XendDomainInfo: 1.4 for v in range(0, self.info['max_vcpu_id']+1): 1.5 xc.vcpu_setaffinity(self.domid, v, self.info['cpus']) 1.6 1.7 + # Use architecture- and image-specific calculations to determine 1.8 + # the various headrooms necessary, given the raw configured 1.9 + # values. 1.10 + # reservation, maxmem, memory, and shadow are all in KiB. 1.11 + reservation = self.image.getRequiredInitialReservation( 1.12 + self.info['memory'] * 1024) 1.13 + maxmem = self.image.getRequiredAvailableMemory( 1.14 + self.info['maxmem'] * 1024) 1.15 + memory = self.image.getRequiredAvailableMemory( 1.16 + self.info['memory'] * 1024) 1.17 + shadow = self.image.getRequiredShadowMemory( 1.18 + self.info['shadow_memory'] * 1024, 1.19 + self.info['maxmem'] * 1024) 1.20 + 1.21 + # Round shadow up to a multiple of a MiB, as shadow_mem_control 1.22 + # takes MiB and we must not round down and end up under-providing. 1.23 + shadow = ((shadow + 1023) / 1024) * 1024 1.24 + 1.25 # set memory limit 1.26 - maxmem = self.image.getRequiredMemory(self.info['maxmem'] * 1024) 1.27 xc.domain_setmaxmem(self.domid, maxmem) 1.28 1.29 - mem_kb = self.image.getRequiredMemory(self.info['memory'] * 1024) 1.30 - 1.31 - # get the domain's shadow memory requirement 1.32 - shadow_kb = self.image.getRequiredShadowMemory(mem_kb) 1.33 - shadow_kb_req = self.info['shadow_memory'] * 1024 1.34 - if shadow_kb_req > shadow_kb: 1.35 - shadow_kb = shadow_kb_req 1.36 - shadow_mb = (shadow_kb + 1023) / 1024 1.37 - 1.38 # Make sure there's enough RAM available for the domain 1.39 - balloon.free(mem_kb + shadow_mb * 1024) 1.40 + balloon.free(memory + shadow) 1.41 1.42 # Set up the shadow memory 1.43 - shadow_cur = xc.shadow_mem_control(self.domid, shadow_mb) 1.44 + shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024) 1.45 self.info['shadow_memory'] = shadow_cur 1.46 1.47 - # initial memory allocation 1.48 - xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0) 1.49 + # initial memory reservation 1.50 + xc.domain_memory_increase_reservation(self.domid, reservation, 0, 1.51 + 0) 1.52 1.53 self.createChannels() 1.54
2.1 --- a/tools/python/xen/xend/image.py Tue Sep 05 14:17:49 2006 +0100 2.2 +++ b/tools/python/xen/xend/image.py Tue Sep 05 14:17:50 2006 +0100 2.3 @@ -143,12 +143,27 @@ class ImageHandler: 2.4 raise VmError('Building domain failed: ostype=%s dom=%d err=%s' 2.5 % (self.ostype, self.vm.getDomid(), str(result))) 2.6 2.7 - def getRequiredMemory(self, mem_kb): 2.8 + def getRequiredAvailableMemory(self, mem_kb): 2.9 + """@param mem_kb The configured maxmem or memory, in KiB. 2.10 + @return The corresponding required amount of memory for the domain, 2.11 + also in KiB. This is normally the given mem_kb, but architecture- or 2.12 + image-specific code may override this to add headroom where 2.13 + necessary.""" 2.14 return mem_kb 2.15 2.16 - def getRequiredShadowMemory(self, mem_kb): 2.17 - """@return The minimum shadow memory required, in KiB, for a domain 2.18 - with mem_kb KiB of RAM.""" 2.19 + def getRequiredInitialReservation(self, mem_kb): 2.20 + """@param mem_kb The configured memory, in KiB. 2.21 + @return The corresponding required amount of memory to be free, also 2.22 + in KiB. This is normally the same as getRequiredAvailableMemory, but 2.23 + architecture- or image-specific code may override this to 2.24 + add headroom where necessary.""" 2.25 + return self.getRequiredAvailableMemory(mem_kb) 2.26 + 2.27 + def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): 2.28 + """@param shadow_mem_kb The configured shadow memory, in KiB. 2.29 + @param maxmem_kb The configured maxmem, in KiB. 2.30 + @return The corresponding required amount of shadow memory, also in 2.31 + KiB.""" 2.32 # PV domains don't need any shadow memory 2.33 return 0 2.34 2.35 @@ -418,7 +433,7 @@ class IA64_HVM_ImageHandler(HVMImageHand 2.36 2.37 ostype = "hvm" 2.38 2.39 - def getRequiredMemory(self, mem_kb): 2.40 + def getRequiredAvailableMemory(self, mem_kb): 2.41 page_kb = 16 2.42 # ROM size for guest firmware, ioreq page and xenstore page 2.43 extra_pages = 1024 + 2 2.44 @@ -432,19 +447,29 @@ class X86_HVM_ImageHandler(HVMImageHandl 2.45 2.46 ostype = "hvm" 2.47 2.48 - def getRequiredMemory(self, mem_kb): 2.49 + def getRequiredAvailableMemory(self, mem_kb): 2.50 page_kb = 4 2.51 # This was derived emperically: 2.52 - # 2.4 MB overhead per 1024 MB RAM + 8 MB constant 2.53 + # 2.4 MB overhead per 1024 MB RAM 2.54 # + 4 to avoid low-memory condition 2.55 - extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12; 2.56 + extra_mb = (2.4/1024) * (mem_kb/1024.0) + 4; 2.57 extra_pages = int( math.ceil( extra_mb*1024 / page_kb )) 2.58 return mem_kb + extra_pages * page_kb 2.59 2.60 - def getRequiredShadowMemory(self, mem_kb): 2.61 + def getRequiredInitialReservation(self, mem_kb): 2.62 + # Add 8 MiB overhead for QEMU's video RAM. 2.63 + return self.getRequiredAvailableMemory(mem_kb) + 8192 2.64 + 2.65 + def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): 2.66 + # The given value is the configured value -- we need to include the 2.67 + # overhead due to getRequiredMemory. 2.68 + maxmem_kb = self.getRequiredMemory(maxmem_kb) 2.69 + 2.70 # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than 2.71 # the minimum that Xen would allocate if no value were given. 2.72 - return 1024 * self.vm.getVCpuCount() + mem_kb / 256 2.73 + return max(1024 * self.vm.getVCpuCount() + maxmem_kb / 256, 2.74 + shadow_mem_kb) 2.75 + 2.76 2.77 _handlers = { 2.78 "powerpc": {