diff --git a/dom0/qmemman/qmemman.py b/dom0/qmemman/qmemman.py index cbfc0543..ba788394 100755 --- a/dom0/qmemman/qmemman.py +++ b/dom0/qmemman/qmemman.py @@ -19,6 +19,7 @@ class SystemState: self.xc = xen.lowlevel.xc.xc() self.xs = xen.lowlevel.xs.xs() self.BALOON_DELAY = 0.1 + self.XEN_FREE_MEM_LEFT = 50*1024*1024 def add_domain(self, id): self.domdict[id] = DomainState(id) @@ -74,7 +75,7 @@ class SystemState: while True: xenfree = self.get_free_xen_memory() print 'got xenfree=', xenfree - if xenfree >= memsize: + if xenfree >= memsize + self.XEN_FREE_MEM_LEFT: return True self.refresh_memactual() if prev_memory_actual is not None: @@ -82,7 +83,7 @@ class SystemState: if prev_memory_actual[i] == self.domdict[i].memory_actual: self.domdict[i].no_progress = True print 'domain', i, 'stuck at', self.domdict[i].memory_actual - memset_reqs = qmemman_algo.balloon(memsize-xenfree, self.domdict) + memset_reqs = qmemman_algo.balloon(memsize + self.XEN_FREE_MEM_LEFT - xenfree, self.domdict) print 'requests:', memset_reqs if niter > MAX_TRIES or len(memset_reqs) == 0: return False @@ -98,7 +99,7 @@ class SystemState: qmemman_algo.refresh_meminfo_for_domain(self.domdict[domid], val) self.do_balance() - def is_balance_req_significant(self, memset_reqs): + def is_balance_req_significant(self, memset_reqs, xenfree): total_memory_transfer = 0 MIN_TOTAL_MEMORY_TRANSFER = 150*1024*1024 MIN_MEM_CHANGE_WHEN_UNDER_PREF = 15*1024*1024 @@ -111,7 +112,7 @@ class SystemState: if last_target > 0 and last_target < pref and memory_change > MIN_MEM_CHANGE_WHEN_UNDER_PREF: print 'dom', dom, 'is below pref, allowing balance' return True - return total_memory_transfer > MIN_TOTAL_MEMORY_TRANSFER + return total_memory_transfer + abs(xenfree - self.XEN_FREE_MEM_LEFT) > MIN_TOTAL_MEMORY_TRANSFER def print_stats(self, xenfree, memset_reqs): for i in self.domdict.keys(): @@ -124,8 +125,8 @@ class SystemState: return self.refresh_memactual() xenfree = self.get_free_xen_memory() - memset_reqs = qmemman_algo.balance(xenfree, self.domdict) - if not self.is_balance_req_significant(memset_reqs): + memset_reqs = qmemman_algo.balance(xenfree - self.XEN_FREE_MEM_LEFT, self.domdict) + if not self.is_balance_req_significant(memset_reqs, xenfree): return self.print_stats(xenfree, memset_reqs) diff --git a/dom0/qmemman/qmemman_algo.py b/dom0/qmemman/qmemman_algo.py index 06037206..1cda2c81 100755 --- a/dom0/qmemman/qmemman_algo.py +++ b/dom0/qmemman/qmemman_algo.py @@ -97,7 +97,7 @@ def balance_when_enough_memory(domdict, xenfree, total_mem_pref, totalsum): scale = 1.0*prefmem(domdict[i])/total_mem_pref target_nonint = prefmem(domdict[i]) + scale*totalsum #prevent rounding errors - target = int(0.995*target_nonint) + target = int(0.999*target_nonint) if (target < domdict[i].memory_actual): donors_rq.append((i, target)) else: @@ -118,6 +118,9 @@ def balance_when_low_on_memory(domdict, xenfree, total_mem_pref_acceptors, donor continue squeezed_mem -= avail donors_rq.append((i, prefmem(domdict[i]))) +#the below can happen if initially xen free memory is below 50M + if squeezed_mem < 0: + return donors_rq for i in acceptors: scale = 1.0*prefmem(domdict[i])/total_mem_pref_acceptors target_nonint = domdict[i].memory_actual + scale*squeezed_mem