[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH 3 of 3] CA-35372: when setting maxmem to cap the allocations of a domain, set the target too



# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1259362818 0
# Node ID f509339c8f7474c96d3ca6532d2d184443440cc5
# Parent  895c6ed73dbc4fa98dd9ea351a887ccbaa2c714b
CA-35372: when setting maxmem to cap the allocations of a domain, set the 
target too.

This required rewriting the logic which determines whether domains are active 
or inactive.
Now we say that a domain is 'making progress' if it is moving towards its 
target. Domains
which are 'making progress' are always active. We say that a domain is inactive 
if (i) it
has not reached its target; and (ii) it hasn't been 'making progress' for more 
than the
threshold (currently 5s).

Signed-off-by: David Scott <dave.scott@xxxxxxxxxxxxx>

diff -r 895c6ed73dbc -r f509339c8f74 ocaml/xenops/squeeze.ml
--- a/ocaml/xenops/squeeze.ml   Fri Nov 27 23:00:17 2009 +0000
+++ b/ocaml/xenops/squeeze.ml   Fri Nov 27 23:00:18 2009 +0000
@@ -188,62 +188,65 @@
        *)
        let assume_balloon_driver_stuck_after = 5. (* seconds *)
 
-       type t = { memory_actual_updates: (int, int64 * float) Hashtbl.t;
-                  has_hit_targets: (int, bool) Hashtbl.t }
+       type per_domain_state = {
+               mutable last_actual_kib: int64; (** last value of memory actual 
seen *)
+               mutable last_makingprogress_time: float; (** last time we saw 
progress towards the target *)
+               mutable stuck: bool; 
+       }
+       type t = {
+               per_domain: (int, per_domain_state) Hashtbl.t;
+       }
 
        (** Make a monitoring object *)
-       let make () : t = { memory_actual_updates = Hashtbl.create 10; 
has_hit_targets = Hashtbl.create 10 }
+       let make () : t = 
+         { per_domain = Hashtbl.create 10 }
 
        (** Update our internal state given a snapshot of the outside world *)
-       let update (x: t) (state: host) (now: float) =
+       let update (x: t) (host: host) (now: float) =
                List.iter
-                       (fun domain ->
-                          let hit_target = has_hit_target 
domain.inaccuracy_kib domain.memory_actual_kib domain.target_kib in
-                          if not hit_target && Hashtbl.mem x.has_hit_targets 
domain.domid then begin
-                            debug "domid %d is nolonger on its target; target 
= %Ld; memory_actual = %Ld" domain.domid domain.target_kib 
domain.memory_actual_kib;
-                            Hashtbl.remove x.has_hit_targets domain.domid
-                          end;
-
-                          let have_useful_update = 
-                            (* either I have no information at all *)
-                            if not (Hashtbl.mem x.memory_actual_updates 
domain.domid) then begin
-                              true
-                            end else if domain.memory_actual_kib <> fst 
(Hashtbl.find x.memory_actual_updates domain.domid) then begin
-                              (* or the information I have is out of date *)
-                              true
-                            end else if hit_target then begin
-                              (* we assume that if the target has been hit 
then the domain is still active *)
-                              if not (Hashtbl.mem x.has_hit_targets 
domain.domid) then begin
-                                if domain.domid <> 0 (* dom0 is boring and 
sits on its target *)
-                                then debug "domid %d has hit its target; 
target = %Ld; memory_actual = %Ld" domain.domid domain.target_kib 
domain.memory_actual_kib;
-                                Hashtbl.replace x.has_hit_targets domain.domid 
true
-                              end;
-                              true
-                            end else false in
-                            if have_useful_update 
-                            then Hashtbl.replace x.memory_actual_updates 
domain.domid (domain.memory_actual_kib, now)
+                       (fun (domain: domain) ->
+                                let direction = direction_of_actual 
domain.inaccuracy_kib domain.memory_actual_kib domain.target_kib in
+                                if not(Hashtbl.mem x.per_domain domain.domid)
+                                then Hashtbl.replace x.per_domain domain.domid
+                                  (* new domains are considered to be making 
progress now and not stuck *)
+                                  { last_actual_kib = domain.memory_actual_kib;
+                                        last_makingprogress_time = now;
+                                        stuck = false };
+                                let state = Hashtbl.find x.per_domain 
domain.domid in
+                                let delta_actual = domain.memory_actual_kib -* 
state.last_actual_kib in
+                                state.last_actual_kib <- 
domain.memory_actual_kib;
+                                (* If memory_actual is moving towards the 
target then we say we are makingprogress *)
+                                let makingprogress = (delta_actual > 0L && 
direction = Some Down) || (delta_actual < 0L && direction = Some Up) in
+                                (* We keep track of the last time we were 
makingprogress. If we are makingprogress now 
+                                       then we are not stuck. *)
+                                if makingprogress then begin
+                                  state.last_makingprogress_time <- now;
+                                  state.stuck <- false;
+                                end;
+                                (* If there is a request (ie work to do) and 
we haven't been makingprogress for more than the
+                                       assume_balloon_driver_stuck_after then 
declare this domain stuck. *)
+                                let request = direction <> None in (* ie 
target <> actual *)
+                                if request && (now -. 
state.last_makingprogress_time > assume_balloon_driver_stuck_after)
+                                then state.stuck <- true;
                        )
-                       state.domains;
+                       host.domains;
                (* Clear out dead domains just in case someone keeps *)
                (* one of these things around for a long time.       *)
-               let live_domids = List.map (fun domain -> domain.domid) 
state.domains in
+               let live_domids = List.map (fun domain -> domain.domid) 
host.domains in
                let to_delete = Hashtbl.fold
                        (fun domid _ acc ->
                                if List.mem domid live_domids then acc else 
domid :: acc
                        )
-                       x.memory_actual_updates []
+                       x.per_domain []
                in
-               List.iter (Hashtbl.remove x.memory_actual_updates) to_delete;
-               List.iter (Hashtbl.remove x.has_hit_targets) to_delete
+               List.iter (Hashtbl.remove x.per_domain) to_delete
 
        (** Return true if we think a particular driver is still making useful 
progress.
            If it is not making progress it may have either hit its target or 
it may have failed. *)
        let domid_is_active (x: t) domid (now: float) = 
-         if not (Hashtbl.mem x.memory_actual_updates domid)
+         if not (Hashtbl.mem x.per_domain domid)
          then false (* it must have been destroyed *)
-         else 
-           let _, time = Hashtbl.find x.memory_actual_updates domid in
-           now -. time <= assume_balloon_driver_stuck_after
+         else not (Hashtbl.find x.per_domain domid).stuck
 end
 
 type fistpoint = 
diff -r 895c6ed73dbc -r f509339c8f74 ocaml/xenops/squeeze_test.ml
--- a/ocaml/xenops/squeeze_test.ml      Fri Nov 27 23:00:17 2009 +0000
+++ b/ocaml/xenops/squeeze_test.ml      Fri Nov 27 23:00:18 2009 +0000
@@ -360,9 +360,8 @@
        end
   in
   let setmaxmem domid kib =
-    let domain = List.assoc domid domid_to_domain in
-       debug "setmaxmem domid = %d; kib = %Ld target = %Ld" domid kib 
(domain#get_domain.target_kib);
-       domain#set_maxmem kib
+       debug "setmaxmem domid = %d; kib = %Ld" domid kib;
+       execute_action { Squeeze.action_domid = domid; new_target_kib = kib }
   in
   (* Allow the simulated balloon drivers to change memory_actual_kib *)
   (* and update host_free_memory accordingly.                        *)
diff -r 895c6ed73dbc -r f509339c8f74 ocaml/xenops/squeeze_xen.ml
--- a/ocaml/xenops/squeeze_xen.ml       Fri Nov 27 23:00:17 2009 +0000
+++ b/ocaml/xenops/squeeze_xen.ml       Fri Nov 27 23:00:18 2009 +0000
@@ -305,7 +305,7 @@
 let io ~xc ~xs = {
   Squeeze.gettimeofday = Unix.gettimeofday;
   make_host = (fun () -> make_host ~xc ~xs);
-  domain_setmaxmem = (fun domid kib -> domain_setmaxmem_noexn xc domid kib);
+  domain_setmaxmem = (fun domid kib -> execute_action ~xc ~xs { 
Squeeze.action_domid = domid; new_target_kib = kib });
   wait = (fun delay -> ignore(Unix.select [] [] [] delay));
   execute_action = (fun action -> execute_action ~xc ~xs action);
   target_host_free_mem_kib = target_host_free_mem_kib;
3 files changed, 44 insertions(+), 42 deletions(-)
ocaml/xenops/squeeze.ml      |   79 +++++++++++++++++++++---------------------
ocaml/xenops/squeeze_test.ml |    5 +-
ocaml/xenops/squeeze_xen.ml  |    2 -


Attachment: xen-api.hg-3.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.