# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1259362817 0
# Node ID 895c6ed73dbc4fa98dd9ea351a887ccbaa2c714b
# Parent a42ee172122fcfb19efe8fd406ba3c84a120708c
CA-35372: the ballooning simulator now checks that target <= maxmem.
This patch addes a new scenario to the simulator which triggers a failure. The
subsequent patch will fix it.
Note that we order updates to target and maxmem to ensure that we don't
trivially violate the desired property.
Signed-off-by: David Scott <dave.scott@xxxxxxxxxxxxx>
diff -r a42ee172122f -r 895c6ed73dbc ocaml/xenops/squeeze_test.ml
--- a/ocaml/xenops/squeeze_test.ml Fri Nov 27 23:00:16 2009 +0000
+++ b/ocaml/xenops/squeeze_test.ml Fri Nov 27 23:00:17 2009 +0000
@@ -44,9 +44,17 @@
(** Helper function to change the domain's balloon target *)
method set_target new_target_kib =
if new_target_kib <> domain.target_kib
- then debug "domid %d: target change was %Ld now %Ld"
- domain.domid domain.target_kib new_target_kib;
+ then debug "domid %d: target change was %Ld now %Ld (max %Ld)"
+ domain.domid domain.target_kib new_target_kib
domain.memory_max_kib;
+ if new_target_kib > domain.memory_max_kib
+ then failwith (Printf.sprintf "Target set above max_mem domid
%d; max_mem = %Ld; target = %Ld" domain.domid domain.memory_max_kib
new_target_kib);
domain <- { domain with target_kib = new_target_kib }
+
+ (** Helper function to set the domain's maxmem *)
+ method set_maxmem new_max_kib =
+ if domain.target_kib > new_max_kib
+ then failwith (Printf.sprintf "mem_max set below target domid %d;
max_mem = %Ld; target = %Ld" domain.domid new_max_kib domain.target_kib);
+ domain <- { domain with memory_max_kib = new_max_kib }
(**
Given a number of time units since the last call to 'update',
@@ -106,6 +114,20 @@
else minimum_memory -* domain.memory_actual_kib
(* this takes us to the minimum *)
end
+
+(** Represents a VM which fails to allocate above a certain threshold *)
+class idealised_vm_with_upper_limit initial_domain rate limit = object
+ inherit vm initial_domain
+
+ method compute_memory_actual_delta time_passed =
+ let delta = compute_memory_actual_delta domain rate time_passed in
+ let proposed_new_memory_actual = domain.memory_actual_kib +* delta in
+ if proposed_new_memory_actual < limit
+ then delta
+ else (limit -* domain.memory_actual_kib)
+end
+
+
(** Represents a VM whose balloon driver has completely failed *)
class stuck_vm initial_domain = object
@@ -157,9 +179,9 @@
should_succeed = true;
scenario_domains = [
new idealised_vm_with_limit
- (domain_make 0 true 1000L 1500L 2000L 1500L 0L 4L) 100L
1250L;
+ (domain_make 0 true 1000L 1500L 2000L 1500L 1500L 4L)
100L 1250L;
new intermittently_stuck_vm
- (domain_make 1 true 2500L 3500L 4500L 3500L 0L 4L) 500L
0.25;
+ (domain_make 1 true 2500L 3500L 4500L 3500L 3500L 4L)
500L 0.25;
];
host_free_mem_kib = 0L;
required_mem_kib = 1000L;
@@ -173,9 +195,9 @@
should_succeed = true;
scenario_domains = [
new intermittently_stuck_vm
- (domain_make 1 true 500L 3500L 4500L 3500L 0L 4L) 100L
3.;
+ (domain_make 1 true 500L 3500L 4500L 3500L 3500L 4L)
100L 3.;
new intermittently_stuck_vm
- (domain_make 0 true 500L 1500L 2500L 1500L 0L 4L) 100L
1.5;
+ (domain_make 0 true 500L 1500L 2500L 1500L 1500L 4L)
100L 1.5;
];
host_free_mem_kib = 0L;
required_mem_kib = 1000L;
@@ -188,8 +210,8 @@
freed";
should_succeed = false;
scenario_domains = [
- new idealised_vm (domain_make 0 true 1000L 1500L 2000L 1500L 0L
0L) 100L;
- new idealised_vm (domain_make 1 true 2000L 2500L 3000L 2500L 0L
0L) 100L;
+ new idealised_vm (domain_make 0 true 1000L 1500L 2000L 1500L
1500L 0L) 100L;
+ new idealised_vm (domain_make 1 true 2000L 2500L 3000L 2500L
2500L 0L) 100L;
];
host_free_mem_kib = 0L;
required_mem_kib = 1500L;
@@ -203,9 +225,9 @@
should_succeed = false;
scenario_domains = [
new idealised_vm
- (domain_make 0 true 1000L 1500L 2000L 1500L 0L 0L) 100L;
+ (domain_make 0 true 1000L 1500L 2000L 1500L 1500L 0L)
100L;
new idealised_vm_with_limit
- (domain_make 1 true 2000L 2500L 3000L 2500L 0L 0L) 100L
2250L;
+ (domain_make 1 true 2000L 2500L 3000L 2500L 2500L 0L)
100L 2250L;
];
host_free_mem_kib = 0L;
required_mem_kib = 1000L;
@@ -222,10 +244,10 @@
scenario_domains = [
(* The stuck domain is using more than it should be if the
memory was freed and everything balanced *)
new stuck_vm
- (domain_make 0 true (*min*)5000L (*target*)7000L
(*max*)7000L (*actual*)7000L 0L 0L);
+ (domain_make 0 true (*min*)5000L (*target*)7000L
(*max*)7000L (*actual*)7000L 7000L 0L);
(* The working domain is using less than it should be if the
memory was freed and everything balanced *)
new idealised_vm
- (domain_make 1 true (*min*)5000L (*target*)6000L
(*max*)11000L (*actual*)6000L 0L 0L) 100L;
+ (domain_make 1 true (*min*)5000L (*target*)6000L
(*max*)11000L (*actual*)6000L 6000L 0L) 100L;
];
host_free_mem_kib = 0L;
@@ -262,6 +284,21 @@
domains are both stuck if we don't take this into account. *)
}
+let scenario_h = {
+ name = "h";
+ description = "a small domain with a hidden upper limit and a perfectly
working domain";
+ should_succeed = true;
+ scenario_domains = [
+ new idealised_vm_with_upper_limit
+ (domain_make 0 true 1000L 1500L 2000L 1500L 1500L 4L)
100L 1500L;
+ new idealised_vm
+ (domain_make 1 true 1000L 1500L 2000L 1500L 1500L 4L)
100L; (* this one can take up the slack *)
+ ];
+ host_free_mem_kib = 1000L;
+ required_mem_kib = 0L;
+ fistpoints = [ ];
+}
+
(* scenario_a with < 24L after the balancing will fail *)
let all_scenarios = [
@@ -272,6 +309,7 @@
scenario_e;
scenario_f;
scenario_g;
+ scenario_h;
]
(*
@@ -313,9 +351,19 @@
(* Update all the recorded balloon targets *)
let execute_action (action: action) =
let domain = List.assoc action.action_domid domid_to_domain in
- domain#set_target action.new_target_kib
+ if action.new_target_kib > domain#get_domain.memory_max_kib then begin
+ domain#set_maxmem action.new_target_kib;
+ domain#set_target action.new_target_kib;
+ end else begin
+ domain#set_target action.new_target_kib;
+ domain#set_maxmem action.new_target_kib;
+ 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
+ in
(* Allow the simulated balloon drivers to change memory_actual_kib *)
(* and update host_free_memory accordingly. *)
let update_balloons time =
@@ -353,7 +401,7 @@
let io = {
Squeeze.gettimeofday = gettimeofday;
make_host = (fun () -> Printf.sprintf "F%Ld" !host_free_mem_kib, make_host
());
- domain_setmaxmem = (fun domid kib -> ());
+ domain_setmaxmem = setmaxmem;
wait = wait;
execute_action = execute_action;
target_host_free_mem_kib = scenario.required_mem_kib;
diff -r a42ee172122f -r 895c6ed73dbc ocaml/xenops/squeeze_xen.ml
--- a/ocaml/xenops/squeeze_xen.ml Fri Nov 27 23:00:16 2009 +0000
+++ b/ocaml/xenops/squeeze_xen.ml Fri Nov 27 23:00:17 2009 +0000
@@ -282,9 +282,15 @@
let target_kib = action.Squeeze.new_target_kib in
if target_kib < 0L
then failwith "Proposed target is negative (domid %d): %Ld"
domid target_kib;
-
- domain_setmaxmem_noexn xc domid target_kib;
- set_target_noexn xs path target_kib
+ let di = Xc.domain_getinfo xc domid in
+ let memory_max_kib = Xc.pages_to_kib (Int64.of_nativeint
di.Xc.max_memory_pages) in
+ if target_kib > memory_max_kib then begin
+ domain_setmaxmem_noexn xc domid target_kib;
+ set_target_noexn xs path target_kib;
+ end else begin
+ set_target_noexn xs path target_kib;
+ domain_setmaxmem_noexn xc domid target_kib;
+ end
with e ->
debug "Failed to reset balloon target (domid: %d) (target:
%Ld): %s"
action.Squeeze.action_domid
action.Squeeze.new_target_kib
2 files changed, 72 insertions(+), 18 deletions(-)
ocaml/xenops/squeeze_test.ml | 78 +++++++++++++++++++++++++++++++++---------
ocaml/xenops/squeeze_xen.ml | 12 ++++--
xen-api.hg-3.patch
Description: Text Data
_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api
|