[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
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |