WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-api

[Xen-API] [PATCH] Fix bug with maxmem handling

To: xen-api@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-API] [PATCH] Fix bug with maxmem handling
From: David Scott <dave.scott@xxxxxxxxxxxxx>
Date: Tue, 26 Jan 2010 15:51:41 +0000
Delivery-date: Tue, 26 Jan 2010 07:44:52 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-api-request@lists.xensource.com?subject=help>
List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>
List-post: <mailto:xen-api@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-api-bounces@xxxxxxxxxxxxxxxxxxx
# 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 +++++++++-


Attachment: 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 <=