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