xen/xen-max-free-mem.diff

138 lines
5.9 KiB
Diff

Index: xen-3.4.0-testing/tools/python/xen/xend/XendNode.py
===================================================================
--- xen-3.4.0-testing.orig/tools/python/xen/xend/XendNode.py
+++ xen-3.4.0-testing/tools/python/xen/xend/XendNode.py
@@ -809,11 +809,35 @@ class XendNode:
info['cpu_mhz'] = info['cpu_khz'] / 1000
- # physinfo is in KiB, need it in MiB
- info['total_memory'] = info['total_memory'] / 1024
- info['free_memory'] = info['free_memory'] / 1024
- info['node_to_cpu'] = self.format_node_to_cpu(info)
- info['node_to_memory'] = self.format_node_to_memory(info)
+ configured_floor = xendoptions().get_dom0_min_mem() * 1024
+ from xen.xend import balloon
+ try:
+ kernel_floor = balloon.get_dom0_min_target()
+ except:
+ kernel_floor = 0
+ dom0_min_mem = max(configured_floor, kernel_floor)
+ dom0_mem = balloon.get_dom0_current_alloc()
+ extra_mem = 0
+ if dom0_min_mem > 0 and dom0_mem > dom0_min_mem:
+ extra_mem = dom0_mem - dom0_min_mem
+ info['free_memory'] = info['free_memory'] + info['scrub_memory']
+ info['max_free_memory'] = info['free_memory'] + extra_mem
+
+ # Convert KiB to MiB, rounding down to be conservative
+ info['total_memory'] = info['total_memory'] / 1024
+ info['free_memory'] = info['free_memory'] / 1024
+ info['max_free_memory'] = info['max_free_memory'] / 1024
+ info['node_to_cpu'] = self.format_node_to_cpu(info)
+ info['node_to_memory'] = self.format_node_to_memory(info)
+
+ # FIXME: These are hard-coded to be the inverse of the getXenMemory
+ # functions in image.py. Find a cleaner way.
+ info['max_para_memory'] = info['max_free_memory'] - 4
+ if info['max_para_memory'] < 0:
+ info['max_para_memory'] = 0
+ info['max_hvm_memory'] = int((info['max_free_memory']-12) * (1-2.4/1024))
+ if info['max_hvm_memory'] < 0:
+ info['max_hvm_memory'] = 0
ITEM_ORDER = ['nr_cpus',
'nr_nodes',
@@ -824,6 +848,9 @@ class XendNode:
'virt_caps',
'total_memory',
'free_memory',
+ 'max_free_memory',
+ 'max_para_memory',
+ 'max_hvm_memory',
'node_to_cpu',
'node_to_memory'
]
Index: xen-3.4.0-testing/tools/python/xen/xend/balloon.py
===================================================================
--- xen-3.4.0-testing.orig/tools/python/xen/xend/balloon.py
+++ xen-3.4.0-testing/tools/python/xen/xend/balloon.py
@@ -41,6 +41,8 @@ SLEEP_TIME_GROWTH = 0.1
# label actually shown in the PROC_XEN_BALLOON file.
#labels = { 'current' : 'Current allocation',
# 'target' : 'Requested target',
+# 'min-target' : 'Minimum target',
+# 'max-target' : 'Maximum target',
# 'low-balloon' : 'Low-mem balloon',
# 'high-balloon' : 'High-mem balloon',
# 'limit' : 'Xen hard limit' }
@@ -67,6 +69,23 @@ def get_dom0_target_alloc():
raise VmError('Failed to query target memory allocation of dom0.')
return kb
+def get_dom0_min_target():
+ """Returns the minimum amount of memory (in KiB) that dom0 will accept."""
+
+ kb = _get_proc_balloon(labels['min-target'])
+ if kb == None:
+ raise VmError('Failed to query minimum target memory allocation of dom0.')
+ return kb
+
+def get_dom0_max_target():
+ """Returns the maximum amount of memory (in KiB) that is potentially
+ visible to dom0."""
+
+ kb = _get_proc_balloon(labels['max-target'])
+ if kb == None:
+ raise VmError('Failed to query maximum target memory allocation of dom0.')
+ return kb
+
def free(need_mem, dominfo):
"""Balloon out memory from the privileged domain so that there is the
specified required amount (in KiB) free.
Index: xen-3.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-3.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-3.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1294,6 +1294,27 @@ class XendDomainInfo:
dev_str_list = dev_str_list + [dev_str]
return dev_str_list
+ def capAndSetMemoryTarget(self, target):
+ """Potentially lowers the requested target to the largest possible
+ value (i.e., caps it), and then sets the memory target of this domain
+ to that value.
+ @param target in MiB.
+ """
+ max_target = 0
+ if self.domid == 0:
+ try:
+ from balloon import get_dom0_max_target
+ max_target = get_dom0_max_target() / 1024
+ except:
+ # It's nice to cap the max at sane values, but harmless to set
+ # them high. Carry on.
+ pass
+ if max_target and target > max_target:
+ log.debug("Requested memory target %d MiB; maximum reasonable is %d MiB.",
+ target, max_target)
+ target = max_target
+ self.setMemoryTarget(target)
+
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
Index: xen-3.4.0-testing/tools/python/xen/xend/server/SrvDomain.py
===================================================================
--- xen-3.4.0-testing.orig/tools/python/xen/xend/server/SrvDomain.py
+++ xen-3.4.0-testing/tools/python/xen/xend/server/SrvDomain.py
@@ -172,7 +172,7 @@ class SrvDomain(SrvDir):
def op_mem_target_set(self, _, req):
- return self.call(self.dom.setMemoryTarget,
+ return self.call(self.dom.capAndSetMemoryTarget,
[['target', 'int']],
req)