|
|
|
|
|
|
|
|
|
|
xen-api
[Xen-API] [PATCH] Fix bug with maxmem handling
# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1264521078 0
# Node ID b001a306fbc2128979e1b7471bc34d14e6a03a02
# Parent 22cd3f304b9e0818b80ac5a40e6d4c6438c5e58a
CA-36316: fix a bug where the domain's maxmem gets out of sync in the case when
no ballooning is required e.g. if dynamic_min = dynamic_max. This causes
subsequent suspend/resume or migrate operations to demand more memory than they
strictly need.
The problem is caused by:
1. xapi creates the domain and sets maxmem = static_max
2. squeezed modifies maxmem only if it is doing some squeezing; if dynamic_min
= dynamic_max then no squeezing is necessary
3. xapi uses max(memory_actual, maxmem) as the amount "needed" by
suspend/resume/migrate
Since squeezed is managing maxmem, this patch makes it always reset maxmems to
low values in its polling loop. Note that there is a cache so we don't issue
more hypercalls than we actually need.
Also fix a logging glitch where if dynamic_min = dynamic_max, large negative
numbers were written to the log (but not used for anything)
Signed-off-by: David Scott <dave.scott@xxxxxxxxxxxxx>
diff -r 22cd3f304b9e -r b001a306fbc2 ocaml/xenops/squeeze.ml
--- a/ocaml/xenops/squeeze.ml Thu Jan 21 15:45:09 2010 +0000
+++ b/ocaml/xenops/squeeze.ml Tue Jan 26 15:51:18 2010 +0000
@@ -292,11 +292,13 @@
(* We allocate surplus memory in proportion to each domain's
dynamic_range: *)
let allocate gamma domain = Int64.of_float (gamma *. (Int64.to_float
(range domain))) in
(* gamma = the proportion where 0 <= gamma <= 1 *)
- let total_range = Int64.to_float (sum (List.map range domains)) in
- let gamma' = Int64.to_float surplus_memory_kib /. total_range in
+ let total_range = sum (List.map range domains) in
+ let gamma' = Int64.to_float surplus_memory_kib /. (Int64.to_float
total_range) in
let gamma = constrain 0. 1. gamma' in
+ debug "total_range = %Ld gamma = %f gamma' = %f" total_range gamma
gamma';
if verbose
- then debug "Total additional memory over dynamic_min = %Ld KiB; will
set gamma = %.2f (leaving unallocated %Ld KiB)" surplus_memory_kib gamma
(Int64.of_float (total_range *. (gamma' -. gamma)));
+ then debug "Total additional memory over dynamic_min = %Ld KiB; will
set gamma = %.2f (leaving unallocated %Ld KiB)" surplus_memory_kib gamma
+ (if total_range = 0L then 0L else Int64.of_float
(Int64.to_float total_range *. (gamma' -. gamma)));
List.map (fun domain -> domain, domain.dynamic_min_kib +* (allocate
gamma domain)) domains
@@ -521,30 +523,18 @@
let debug_string = String.concat "; " (host_debug_string :: (List.map (fun
domain -> short_string_of_domain domain ^ (new_target_direction domain))
host.domains)) in
debug "%s" debug_string;
- (* Deal with inactive and 'never been run' domains *)
- List.iter (fun domid ->
- try
- let domain = IntMap.find domid host.domid_to_domain in
- let mem_max_kib = min domain.target_kib
domain.memory_actual_kib in
- debug "Setting inactive domain %d mem_max = %Ld" domid
mem_max_kib;
- io.domain_setmaxmem domid mem_max_kib
- with Not_found ->
- debug "WARNING: inactive domain %d not in map" domid
- ) declared_inactive_domids;
- (* Next deal with the active domains (which may have new targets) *)
- List.iter (fun domid ->
- try
- let domain = IntMap.find domid host.domid_to_domain in
- let mem_max_kib =
- if List.mem_assoc domid new_targets
- then List.assoc domid new_targets
- else domain.target_kib in
- debug "Setting active domain %d mem_max = %Ld" domid
mem_max_kib;
- io.domain_setmaxmem domid mem_max_kib
- with Not_found ->
- debug "WARNING: active domain %d not in map" domid
- ) declared_active_domids;
-
+ (* For each domid, decide what maxmem should be *)
+ let maxmems = IntMap.mapi
+ (fun domid domain ->
+ if List.mem domid declared_inactive_domids
+ then min domain.target_kib domain.memory_actual_kib
+ else
+ if List.mem_assoc domid new_targets
+ then List.assoc domid new_targets
+ else domain.target_kib) host.domid_to_domain in
+
+ IntMap.iter io.domain_setmaxmem maxmems;
+
begin match result with
| Success ->
if io.verbose
diff -r 22cd3f304b9e -r b001a306fbc2 ocaml/xenops/squeeze_xen.ml
--- a/ocaml/xenops/squeeze_xen.ml Thu Jan 21 15:45:09 2010 +0000
+++ b/ocaml/xenops/squeeze_xen.ml Tue Jan 26 15:51:18 2010 +0000
@@ -359,11 +359,20 @@
reserved_kib := Int64.add !reserved_kib non_domain_reservations;
let host = Squeeze.make_host ~domains ~free_mem_kib:(Int64.sub
free_mem_kib !reserved_kib) in
+ Domain.gc (List.map (fun di -> di.Xc.domid) domain_infolist);
+ (* Externally-visible side-effects. It's a bit ugly to include these
here: *)
update_cooperative_table host;
update_cooperative_flags cnx;
- Domain.gc (List.map (fun di -> di.Xc.domid) domain_infolist);
+ (* It's always safe to _decrease_ a domain's maxmem towards target.
This catches the case
+ where a toolstack creates a domain with maxmem = static_max and
target < static_max (eg
+ CA-36316) *)
+ let updates = Squeeze.IntMap.fold (fun domid domain updates ->
+
if domain.Squeeze.target_kib < (Domain.get_maxmem (xc, xs) domid)
+
then Squeeze.IntMap.add domid domain.Squeeze.target_kib updates
+
else updates) host.Squeeze.domid_to_domain Squeeze.IntMap.empty in
+ Squeeze.IntMap.iter (Domain.set_maxmem_noexn (xc, xs)) updates;
Printf.sprintf "F%Ld S%Ld R%Ld T%Ld" free_pages_kib scrub_pages_kib
!reserved_kib total_pages_kib, host
2 files changed, 27 insertions(+), 28 deletions(-)
ocaml/xenops/squeeze.ml | 44 ++++++++++++++++---------------------------
ocaml/xenops/squeeze_xen.ml | 11 +++++++++-
xen-api.hg.patch
Description: Text Data
_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api
|
<Prev in Thread] |
Current Thread |
[Next in Thread> |
- [Xen-API] [PATCH] Fix bug with maxmem handling,
David Scott <=
|
|
|
|
|