dom0: qmemman: Support for maxmem != physical memory (#235)

This commit is contained in:
Marek Marczykowski 2011-05-12 15:20:26 +02:00
parent ef517e5e66
commit b57b41aafa
2 changed files with 43 additions and 5 deletions

View File

@ -9,6 +9,7 @@ class DomainState:
def __init__(self, id):
self.meminfo = None #dictionary of memory info read from client
self.memory_actual = None #the current memory size
self.memory_maximum = None #the maximum memory size
self.mem_used = None #used memory, computed based on meminfo
self.id = id #domain id
self.last_target = 0 #the last memset target
@ -42,6 +43,7 @@ class SystemState:
id = str(domain['domid'])
if self.domdict.has_key(id):
self.domdict[id].memory_actual = domain['mem_kb']*1024
self.domdict[id].memory_maximum = domain['maxmem_kb']*1024
#the below works (and is fast), but then 'xm list' shows unchanged memory value
def mem_set(self, id, val):

View File

@ -61,7 +61,7 @@ def prefmem(domain):
#dom0 is special, as it must have large cache, for vbds. Thus, give it a special boost
if domain.id == '0':
return domain.mem_used*CACHE_FACTOR + 350*1024*1024
return domain.mem_used*CACHE_FACTOR
return min(domain.mem_used*CACHE_FACTOR, domain.memory_maximum)
def memory_needed(domain):
#do not change
@ -104,8 +104,11 @@ def balloon(memsize, domain_dictionary):
#redistribute positive "total_available_memory" of memory between domains, proportionally to prefmem
def balance_when_enough_memory(domain_dictionary, xen_free_memory, total_mem_pref, total_available_memory):
donors_rq = list()
acceptors_rq = list()
print 'balance_when_enough_memory(', xen_free_memory, total_mem_pref, total_available_memory, ')'
target_memory = {}
# memory not assigned because of static max
left_memory = 0
acceptors_count = 0
for i in domain_dictionary.keys():
if domain_dictionary[i].meminfo is None:
continue
@ -114,10 +117,41 @@ def balance_when_enough_memory(domain_dictionary, xen_free_memory, total_mem_pre
target_nonint = prefmem(domain_dictionary[i]) + scale*total_available_memory
#prevent rounding errors
target = int(0.999*target_nonint)
#do not try to give more memory than static max
if target > domain_dictionary[i].memory_maximum:
left_memory += target-domain_dictionary[i].memory_maximum
target = domain_dictionary[i].memory_maximum
else:
# count domains which can accept more memory
acceptors_count += 1
target_memory[i] = target
# distribute left memory across all acceptors
while left_memory > 0:
print ' left_memory:', left_memory, 'acceptors_count:', acceptors_count
new_left_memory = 0
for i in target_memory.keys():
target = target_memory[i]
if target < domain_dictionary[i].memory_maximum:
memory_bonus = int(0.999*(left_memory/acceptors_count))
if target+memory_bonus >= domain_dictionary[i].memory_maximum:
new_left_memory += target+memory_bonus - domain_dictionary[i].memory_maximum
target = domain_dictionary[i].memory_maximum
acceptors_count -= 1
else:
target += memory_bonus
target_memory[i] = target
left_memory = new_left_memory
# split target_memory dictionary to donors and acceptors
# this is needed to first get memory from donors and only then give it to acceptors
donors_rq = list()
acceptors_rq = list()
for i in target_memory.keys():
target = target_memory[i]
if (target < domain_dictionary[i].memory_actual):
donors_rq.append((i, target))
else:
acceptors_rq.append((i, target))
# print 'balance(enough): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq
return donors_rq + acceptors_rq
@ -140,7 +174,9 @@ def balance_when_low_on_memory(domain_dictionary, xen_free_memory, total_mem_pre
for i in acceptors:
scale = 1.0*prefmem(domain_dictionary[i])/total_mem_pref_acceptors
target_nonint = domain_dictionary[i].memory_actual + scale*squeezed_mem
acceptors_rq.append((i, int(target_nonint)))
#do not try to give more memory than static max
target = min(int(0.999*target_nonint), domain_dictionary[i].memory_maximum)
acceptors_rq.append((i, target))
# print 'balance(low): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq
return donors_rq + acceptors_rq
@ -171,7 +207,7 @@ def balance(xen_free_memory, domain_dictionary):
continue
need = memory_needed(domain_dictionary[i])
# print 'domain' , i, 'act/pref', domain_dictionary[i].memory_actual, prefmem(domain_dictionary[i]), 'need=', need
if need < 0:
if need < 0 or domain_dictionary[i].memory_actual >= domain_dictionary[i].memory_maximum:
donors.append(i)
else:
acceptors.append(i)