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

[PATCH for-4.17 v1 1/2] xenctrl.ml: make domain_getinfolist tail recursive


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Edwin Török <edvin.torok@xxxxxxxxxx>
  • Date: Tue, 1 Nov 2022 17:59:16 +0000
  • Authentication-results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: <pau.safont@xxxxxxxxxx>, Edwin Török <edvin.torok@xxxxxxxxxx>, Christian Lindig <christian.lindig@xxxxxxxxxx>, David Scott <dave@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>
  • Delivery-date: Tue, 01 Nov 2022 18:00:00 +0000
  • Ironport-data: A9a23:CqrAvK6HpKl6A7m5+udmkQxRtDrHchMFZxGqfqrLsTDasY5as4F+v jcZWmmCaKqCMTH1LYpyOoi0pxkFuMSEmtVmQQRlqHtmHi5G8cbLO4+Ufxz6V8+wwm8vb2o8t plDNYOQRCwQZiWBzvt4GuG59RGQ7YnRGvynTraBYnoqLeNdYH9JoQp5nOIkiZJfj9G8Agec0 fv/uMSaM1K+s9JOGjt8B5mr9VU+4ZwehBtC5gZkPKkT5QeE/5UoJMl3yZ+ZfiOQrrZ8RoZWd 86bpJml82XQ+QsaC9/Nut4XpWVTH9Y+lSDX4pZnc/DKbipq/0Te4Y5iXBYoUm9Fii3hojxE4 I4lWapc6+seFvakdOw1C3G0GszlVEFM0OevzXOX6aR/w6BaGpdFLjoH4EweZOUlFuhL7W5m9 c0hcRs3QFO4xKGU253kSLNFpsgcBZy+VG8fkikIITDxCP8nRdbIQrnQ5M8e1zA17ixMNa+AP YxDM2MpNUmeJU0UUrsUIMtWcOOAi3XhcjsetFWPoqkf6GnP1g1hlrPqNbI5f/TaG5kFxx7F9 goq+UynX0kXMdyV2wCDrGuHl8PvnCXdSZ4dQejQGvlC3wTImz175ActfUS/iem0jAi5Qd03A 0Ad5CcGt6U5802vCN7nUHWQsHOC+xIRRddUO+k78x2WjLrZ5R6DAWoJRSIHb8Yp3PLaXhRzi AXPxYmwQ2Uy7vvFEhpx64t4sxuyCBFMBlUsJhRHDikezIbh+qgTgi3mG4ML/LGOsvX5HjT5w javpSc4hqkOgcNj65hX7WwrkBr3+MGXE1ddChH/Gzv8s1gnPNLNi5mAswCz0BpWEGqOorBtV lAgktPW0u0BBIrleMelELRUR+HBCxpo3VThbb9T83sJrWrFF52LJ9o4DNRCyKBBa59sRNMRS BWP0T69HbcKVJdQUYd5YpiqF+MhxrX6GNLuW5j8N4QQPcItLVTdp3AzOCZ8OlwBd2B1z8kC1 WqzK57wXR7294w6pNZJewvt+eBynX1vrY8ibZv60w6mwdKjiI29EN843K+1RrlgtMu5TPD9q Yk32z2il0oCC4UTo0D/reYuELz9BSNgXs2q9JcHL7Drz8gPMDhJNsI9CIgJI+RN95m5XM+Sl p1hcie0EGbCuEA=
  • Ironport-hdrordr: A9a23:TUFdLqG+5LsUrrVgpLqEGMeALOsnbusQ8zAXPiBKJCC9E/bo8P xG+c5w6faaslkssR0b9+xofZPwIk80lqQFhbX5X43DYOCOggLBQL2Kr7GSoQEIcxeUygc379 YET0ERMrzN5VgRt7eH3OG7eexQv+VuJsqT9JnjJ3QGd3AaV0l5hT0JbDpyiidNNXN77ZxSLu vk2uN34wCOVF4wdcqBCnwMT4H41qD2fMKPW29/O/Y/gjP+9g+V1A==
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On a host with ~1000 VMs (the support limit for XAPI) domain_getinfolist
took O(n^2) time (n=number of domains).
This couples with xenopsd making inefficient calls to
domain_getinfolist(1 call/VM) resulted in visibly bad performance of
XAPI.

It was calling the Xen domainfolist hypercall N/2 times.
Optimize this such that it is called at most 2 times during normal use.

Implement a tail recursive `rev_concat` equivalent to `concat |> rev`,
and use it instead of calling `@` multiple times.

The added benefit is that the list of domains should now actually be in
increasing order instead of having pairs of 2 changing direction every time.

Signed-off-by: Edwin Török <edvin.torok@xxxxxxxxxx>
Tested-by: Pau Ruiz Safont <pau.safont@xxxxxxxxxx>
---
 tools/ocaml/libs/xc/xenctrl.ml | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml
index 28ed642231..3ebedffdc7 100644
--- a/tools/ocaml/libs/xc/xenctrl.ml
+++ b/tools/ocaml/libs/xc/xenctrl.ml
@@ -226,14 +226,25 @@ external domain_shutdown: handle -> domid -> 
shutdown_reason -> unit
 external _domain_getinfolist: handle -> domid -> int -> domaininfo list
        = "stub_xc_domain_getinfolist"
 
+let rev_append_fold acc e = List.rev_append e acc
+
+(**
+       [rev_concat lst] is equivalent to [lst |> List.concat |> List.rev]
+       except it is tail recursive, whereas [List.concat] isn't.
+       Example:
+       rev_concat [[10;9;8];[7;6];[5]]] = [5; 6; 7; 8; 9; 10]
+*)
+let rev_concat lst = List.fold_left rev_append_fold [] lst
+
 let domain_getinfolist handle first_domain =
        let nb = 2 in
-       let last_domid l = (List.hd l).domid + 1 in
-       let rec __getlist from =
-               let l = _domain_getinfolist handle from nb in
-               (if List.length l = nb then __getlist (last_domid l) else []) @ 
l
-               in
-       List.rev (__getlist first_domain)
+       let rec __getlist lst from =
+               (* _domain_getinfolist returns domains in reverse order, 
largest first *)
+               match _domain_getinfolist handle from nb with
+               | [] -> rev_concat lst
+               | (hd :: _) as l -> __getlist (l :: lst) (hd.domid + 1)
+       in
+       __getlist [] first_domain
 
 external domain_getinfo: handle -> domid -> domaininfo= 
"stub_xc_domain_getinfo"
 
-- 
2.34.1




 


Rackspace

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