dom0: qmemman: Support for maxmem != physical memory (#235)
This commit is contained in:
parent
ef517e5e66
commit
b57b41aafa
@ -9,6 +9,7 @@ class DomainState:
|
|||||||
def __init__(self, id):
|
def __init__(self, id):
|
||||||
self.meminfo = None #dictionary of memory info read from client
|
self.meminfo = None #dictionary of memory info read from client
|
||||||
self.memory_actual = None #the current memory size
|
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.mem_used = None #used memory, computed based on meminfo
|
||||||
self.id = id #domain id
|
self.id = id #domain id
|
||||||
self.last_target = 0 #the last memset target
|
self.last_target = 0 #the last memset target
|
||||||
@ -42,6 +43,7 @@ class SystemState:
|
|||||||
id = str(domain['domid'])
|
id = str(domain['domid'])
|
||||||
if self.domdict.has_key(id):
|
if self.domdict.has_key(id):
|
||||||
self.domdict[id].memory_actual = domain['mem_kb']*1024
|
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
|
#the below works (and is fast), but then 'xm list' shows unchanged memory value
|
||||||
def mem_set(self, id, val):
|
def mem_set(self, id, val):
|
||||||
|
@ -61,7 +61,7 @@ def prefmem(domain):
|
|||||||
#dom0 is special, as it must have large cache, for vbds. Thus, give it a special boost
|
#dom0 is special, as it must have large cache, for vbds. Thus, give it a special boost
|
||||||
if domain.id == '0':
|
if domain.id == '0':
|
||||||
return domain.mem_used*CACHE_FACTOR + 350*1024*1024
|
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):
|
def memory_needed(domain):
|
||||||
#do not change
|
#do not change
|
||||||
@ -104,8 +104,11 @@ def balloon(memsize, domain_dictionary):
|
|||||||
|
|
||||||
#redistribute positive "total_available_memory" of memory between domains, proportionally to prefmem
|
#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):
|
def balance_when_enough_memory(domain_dictionary, xen_free_memory, total_mem_pref, total_available_memory):
|
||||||
donors_rq = list()
|
print 'balance_when_enough_memory(', xen_free_memory, total_mem_pref, total_available_memory, ')'
|
||||||
acceptors_rq = list()
|
target_memory = {}
|
||||||
|
# memory not assigned because of static max
|
||||||
|
left_memory = 0
|
||||||
|
acceptors_count = 0
|
||||||
for i in domain_dictionary.keys():
|
for i in domain_dictionary.keys():
|
||||||
if domain_dictionary[i].meminfo is None:
|
if domain_dictionary[i].meminfo is None:
|
||||||
continue
|
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
|
target_nonint = prefmem(domain_dictionary[i]) + scale*total_available_memory
|
||||||
#prevent rounding errors
|
#prevent rounding errors
|
||||||
target = int(0.999*target_nonint)
|
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):
|
if (target < domain_dictionary[i].memory_actual):
|
||||||
donors_rq.append((i, target))
|
donors_rq.append((i, target))
|
||||||
else:
|
else:
|
||||||
acceptors_rq.append((i, target))
|
acceptors_rq.append((i, target))
|
||||||
|
|
||||||
# print 'balance(enough): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq
|
# print 'balance(enough): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq
|
||||||
return 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:
|
for i in acceptors:
|
||||||
scale = 1.0*prefmem(domain_dictionary[i])/total_mem_pref_acceptors
|
scale = 1.0*prefmem(domain_dictionary[i])/total_mem_pref_acceptors
|
||||||
target_nonint = domain_dictionary[i].memory_actual + scale*squeezed_mem
|
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
|
# print 'balance(low): xen_free_memory=', xen_free_memory, 'requests:', donors_rq + acceptors_rq
|
||||||
return donors_rq + acceptors_rq
|
return donors_rq + acceptors_rq
|
||||||
|
|
||||||
@ -171,7 +207,7 @@ def balance(xen_free_memory, domain_dictionary):
|
|||||||
continue
|
continue
|
||||||
need = memory_needed(domain_dictionary[i])
|
need = memory_needed(domain_dictionary[i])
|
||||||
# print 'domain' , i, 'act/pref', domain_dictionary[i].memory_actual, prefmem(domain_dictionary[i]), 'need=', need
|
# 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)
|
donors.append(i)
|
||||||
else:
|
else:
|
||||||
acceptors.append(i)
|
acceptors.append(i)
|
||||||
|
Loading…
Reference in New Issue
Block a user