summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Schmaus <flow@gentoo.org>2022-11-09 09:53:02 +0100
committerFlorian Schmaus <flow@gentoo.org>2022-11-09 09:53:02 +0100
commitfac86a27853d2f21c62fefcba9cca32e3b9bdcdc (patch)
tree57acbe9aadcfdb2594eec2e21f1bab81bd104235 /0064-tools-ocaml-GC-parameter-tuning.patch
parentXen 4.16.3-pre-patchset-0 (diff)
downloadxen-upstream-patches-fac86a27853d2f21c62fefcba9cca32e3b9bdcdc.tar.gz
xen-upstream-patches-fac86a27853d2f21c62fefcba9cca32e3b9bdcdc.tar.bz2
xen-upstream-patches-fac86a27853d2f21c62fefcba9cca32e3b9bdcdc.zip
Xen 4.16.3-pre-patchset-14.16.3-pre-patchset-1
Signed-off-by: Florian Schmaus <flow@gentoo.org>
Diffstat (limited to '0064-tools-ocaml-GC-parameter-tuning.patch')
-rw-r--r--0064-tools-ocaml-GC-parameter-tuning.patch126
1 files changed, 126 insertions, 0 deletions
diff --git a/0064-tools-ocaml-GC-parameter-tuning.patch b/0064-tools-ocaml-GC-parameter-tuning.patch
new file mode 100644
index 0000000..6c80e2d
--- /dev/null
+++ b/0064-tools-ocaml-GC-parameter-tuning.patch
@@ -0,0 +1,126 @@
+From a63bbcf5318b487ca86574d7fcf916958af5ed02 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= <edvin.torok@citrix.com>
+Date: Wed, 12 Oct 2022 19:13:07 +0100
+Subject: [PATCH 64/87] tools/ocaml: GC parameter tuning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+By default the OCaml garbage collector would return memory to the OS only
+after unused memory is 5x live memory. Tweak this to 120% instead, which
+would match the major GC speed.
+
+This is part of XSA-326.
+
+Signed-off-by: Edwin Török <edvin.torok@citrix.com>
+Acked-by: Christian Lindig <christian.lindig@citrix.com>
+(cherry picked from commit 4a8bacff20b857ca0d628ef5525877ade11f2a42)
+---
+ tools/ocaml/xenstored/define.ml | 1 +
+ tools/ocaml/xenstored/xenstored.ml | 64 ++++++++++++++++++++++++++++++
+ 2 files changed, 65 insertions(+)
+
+diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
+index 6b06f808595b..ba63a8147e09 100644
+--- a/tools/ocaml/xenstored/define.ml
++++ b/tools/ocaml/xenstored/define.ml
+@@ -25,6 +25,7 @@ let maxwatch = ref (100)
+ let maxtransaction = ref (10)
+ let maxrequests = ref (1024) (* maximum requests per transaction *)
+
++let gc_max_overhead = ref 120 (* 120% see comment in xenstored.ml *)
+ let conflict_burst_limit = ref 5.0
+ let conflict_max_history_seconds = ref 0.05
+ let conflict_rate_limit_is_aggregate = ref true
+diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
+index d44ae673c42a..3b57ad016dfb 100644
+--- a/tools/ocaml/xenstored/xenstored.ml
++++ b/tools/ocaml/xenstored/xenstored.ml
+@@ -104,6 +104,7 @@ let parse_config filename =
+ ("quota-maxsize", Config.Set_int Quota.maxsize);
+ ("quota-maxrequests", Config.Set_int Define.maxrequests);
+ ("quota-path-max", Config.Set_int Define.path_max);
++ ("gc-max-overhead", Config.Set_int Define.gc_max_overhead);
+ ("test-eagain", Config.Set_bool Transaction.test_eagain);
+ ("persistent", Config.Set_bool Disk.enable);
+ ("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
+@@ -265,6 +266,67 @@ let to_file store cons fds file =
+ (fun () -> close_out channel)
+ end
+
++(*
++ By default OCaml's GC only returns memory to the OS when it exceeds a
++ configurable 'max overhead' setting.
++ The default is 500%, that is 5/6th of the OCaml heap needs to be free
++ and only 1/6th live for a compaction to be triggerred that would
++ release memory back to the OS.
++ If the limit is not hit then the OCaml process can reuse that memory
++ for its own purposes, but other processes won't be able to use it.
++
++ There is also a 'space overhead' setting that controls how much work
++ each major GC slice does, and by default aims at having no more than
++ 80% or 120% (depending on version) garbage values compared to live
++ values.
++ This doesn't have as much relevance to memory returned to the OS as
++ long as space_overhead <= max_overhead, because compaction is only
++ triggerred at the end of major GC cycles.
++
++ The defaults are too large once the program starts using ~100MiB of
++ memory, at which point ~500MiB would be unavailable to other processes
++ (which would be fine if this was the main process in this VM, but it is
++ not).
++
++ Max overhead can also be set to 0, however this is for testing purposes
++ only (setting it lower than 'space overhead' wouldn't help because the
++ major GC wouldn't run fast enough, and compaction does have a
++ performance cost: we can only compact contiguous regions, so memory has
++ to be moved around).
++
++ Max overhead controls how often the heap is compacted, which is useful
++ if there are burst of activity followed by long periods of idle state,
++ or if a domain quits, etc. Compaction returns memory to the OS.
++
++ wasted = live * space_overhead / 100
++
++ For globally overriding the GC settings one can use OCAMLRUNPARAM,
++ however we provide a config file override to be consistent with other
++ oxenstored settings.
++
++ One might want to dynamically adjust the overhead setting based on used
++ memory, i.e. to use a fixed upper bound in bytes, not percentage. However
++ measurements show that such adjustments increase GC overhead massively,
++ while still not guaranteeing that memory is returned any more quickly
++ than with a percentage based setting.
++
++ The allocation policy could also be tweaked, e.g. first fit would reduce
++ fragmentation and thus memory usage, but the documentation warns that it
++ can be sensibly slower, and indeed one of our own testcases can trigger
++ such a corner case where it is multiple times slower, so it is best to keep
++ the default allocation policy (next-fit/best-fit depending on version).
++
++ There are other tweaks that can be attempted in the future, e.g. setting
++ 'ulimit -v' to 75% of RAM, however getting the kernel to actually return
++ NULL from allocations is difficult even with that setting, and without a
++ NULL the emergency GC won't be triggerred.
++ Perhaps cgroup limits could help, but for now tweak the safest only.
++*)
++
++let tweak_gc () =
++ Gc.set { (Gc.get ()) with Gc.max_overhead = !Define.gc_max_overhead }
++
++
+ let _ =
+ let cf = do_argv in
+ let pidfile =
+@@ -274,6 +336,8 @@ let _ =
+ default_pidfile
+ in
+
++ tweak_gc ();
++
+ (try
+ Unixext.mkdir_rec (Filename.dirname pidfile) 0o755
+ with _ ->
+--
+2.37.4
+