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

[Xen-changelog] [xen stable-4.6] oxenstored: don't wake to issue no conflict-credit



commit d9c4094f973f143bb276ba0d81078f4d2803e982
Author:     Thomas Sanders <thomas.sanders@xxxxxxxxxx>
AuthorDate: Fri Mar 24 19:55:03 2017 +0000
Commit:     Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
CommitDate: Wed Apr 5 15:19:02 2017 +0100

    oxenstored: don't wake to issue no conflict-credit
    
    In the main loop, when choosing the timeout for the select function
    call, we were setting it so as to wake up to issue conflict-credit to
    any domains that could accept it. When xenstore is idle, this would
    mean waking up every 50ms (by default) to do no work. With this
    commit, we check whether any domain is below its cap, and if not then
    we set the timeout for longer (the same timeout as before the
    conflict-protection feature was added).
    
    Reported-by: Juergen Gross <jgross@xxxxxxxx>
    Signed-off-by: Thomas Sanders <thomas.sanders@xxxxxxxxxx>
    Reviewed-by: Jonathan Davies <jonathan.davies@xxxxxxxxxx>
---
 tools/ocaml/xenstored/domains.ml   | 51 ++++++++++++++++++++++++++++++--------
 tools/ocaml/xenstored/xenstored.ml |  5 +++-
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/tools/ocaml/xenstored/domains.ml b/tools/ocaml/xenstored/domains.ml
index 63c6ad5..25fd592 100644
--- a/tools/ocaml/xenstored/domains.ml
+++ b/tools/ocaml/xenstored/domains.ml
@@ -35,8 +35,9 @@ type domains = {
        on_first_conflict_pause: unit -> unit;
 
        (* If config is set to use individual instead of aggregate 
conflict-rate-limiting,
-          we use this instead of the queues. *)
-       mutable n_paused: int;
+          we use these counts instead of the queues. The second one includes 
the first. *)
+       mutable n_paused: int;    (* Number of domains with zero or negative 
credit *)
+       mutable n_penalised: int; (* Number of domains with less than maximum 
credit *)
 }
 
 let init eventchn on_first_conflict_pause = {
@@ -46,6 +47,7 @@ let init eventchn on_first_conflict_pause = {
        doms_with_conflict_penalty = Queue.create ();
        on_first_conflict_pause = on_first_conflict_pause;
        n_paused = 0;
+       n_penalised = 0;
 }
 let del doms id = Hashtbl.remove doms.table id
 let exist doms id = Hashtbl.mem doms.table id
@@ -53,6 +55,23 @@ let find doms id = Hashtbl.find doms.table id
 let number doms = Hashtbl.length doms.table
 let iter doms fct = Hashtbl.iter (fun _ b -> fct b) doms.table
 
+let rec is_empty_queue q =
+       Queue.is_empty q ||
+               if !(Queue.peek q) = None
+               then (
+                       ignore (Queue.pop q);
+                       is_empty_queue q
+               ) else false
+
+let all_at_max_credit doms =
+       if !Define.conflict_rate_limit_is_aggregate
+       then
+               (* Check both becuase if burst limit is 1.0 then a domain can 
go straight
+                * from max-credit to paused without getting into the penalty 
queue. *)
+               is_empty_queue doms.doms_with_conflict_penalty
+               && is_empty_queue doms.doms_conflict_paused
+       else doms.n_penalised = 0
+
 (* Functions to handle queues of domains given that the domain might be 
deleted while in a queue. *)
 let push dom queue =
        Queue.push (ref (Some dom)) queue
@@ -132,13 +151,16 @@ let decr_conflict_credit doms dom =
        let before = dom.Domain.conflict_credit in
        let after = max (-1.0) (before -. 1.0) in
        dom.Domain.conflict_credit <- after;
+       let newly_penalised =
+               before >= !Define.conflict_burst_limit
+               && after < !Define.conflict_burst_limit in
+       let newly_paused = before > 0.0 && after <= 0.0 in
        if !Define.conflict_rate_limit_is_aggregate then (
-               if before >= !Define.conflict_burst_limit
-               && after < !Define.conflict_burst_limit
+               if newly_penalised
                && after > 0.0
                then (
                        push dom doms.doms_with_conflict_penalty
-               ) else if before > 0.0 && after <= 0.0
+               ) else if newly_paused
                then (
                        let first_pause = Queue.is_empty 
doms.doms_conflict_paused in
                        push dom doms.doms_conflict_paused;
@@ -146,9 +168,12 @@ let decr_conflict_credit doms dom =
                ) else (
                        (* The queues are correct already: no further action 
needed. *)
                )
-       ) else if before > 0.0 && after <= 0.0 then (
-               doms.n_paused <- doms.n_paused + 1;
-               if doms.n_paused = 1 then doms.on_first_conflict_pause ()
+       ) else (
+               if newly_penalised then doms.n_penalised <- doms.n_penalised + 
1;
+               if newly_paused then (
+                       doms.n_paused <- doms.n_paused + 1;
+                       if doms.n_paused = 1 then doms.on_first_conflict_pause 
()
+               )
        )
 
 (* Give one point of credit to one domain, and update the queues 
appropriately. *)
@@ -177,9 +202,13 @@ let incr_conflict_credit doms =
                        let before = dom.Domain.conflict_credit in
                        let after = min (before +. 1.0) 
!Define.conflict_burst_limit in
                        dom.Domain.conflict_credit <- after;
+
                        if before <= 0.0 && after > 0.0
-                       then doms.n_paused <- doms.n_paused - 1
+                       then doms.n_paused <- doms.n_paused - 1;
+
+                       if before < !Define.conflict_burst_limit
+                       && after >= !Define.conflict_burst_limit
+                       then doms.n_penalised <- doms.n_penalised - 1
                in
-               (* Scope for optimisation (probably tiny): avoid iteration if 
all domains are at max credit *)
-               iter doms inc
+               if doms.n_penalised > 0 then iter doms inc
        )
diff --git a/tools/ocaml/xenstored/xenstored.ml 
b/tools/ocaml/xenstored/xenstored.ml
index 1d79b9e..03e19bb 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -438,7 +438,10 @@ let _ =
                        peaceful_mw;
                let start_time = Unix.gettimeofday () in
                let timeout =
-                       let until_next_activity = min (max 0. 
(!next_frequent_ops -. start_time)) period_ops_interval in
+                       let until_next_activity =
+                               if Domains.all_at_max_credit domains
+                               then period_ops_interval
+                               else min (max 0. (!next_frequent_ops -. 
start_time)) period_ops_interval in
                        if peaceful_mw <> [] then 0. else until_next_activity
                in
                let inset, outset = Connections.select ~only_if:is_peaceful 
cons in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.6

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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