Skip to content

Commit 59d8116

Browse files
committed
CP-54065, xenopsd: use domain_claim_pages on a single node, if possible
Xen currently supports to modes to claim memory for a domain: without any node in particular, or claim memory in a single NUMA node. When planning a domain, return the nodes that will host the domain, and how much memory. In the case where the domain fits in a single NUMA node, claim pages on that node, otherwise fall back to previous behaviour. The memory claims need to happen while the memory measurements hold valid, that is while no VMs are started, otherwise ENOMEM might be returned. Because the current mode is a best-effort, log when the claim does not work. Signed-off-by: Pau Ruiz Safont <pau.ruizsafont@cloud.com>
1 parent 9aa1577 commit 59d8116

8 files changed

Lines changed: 165 additions & 117 deletions

File tree

ocaml/xenopsd/lib/softaffinity.ml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ let plan host nodes ~vm =
2626
(Fmt.to_to_string NUMARequest.pp_dump requested)
2727
(Fmt.to_to_string NUMAResource.pp_dump allocated) ;
2828
let candidate = nodes.(nodeidx) in
29-
( NUMAResource.union allocated candidate
30-
, node :: picked
31-
, NUMARequest.shrink requested candidate
32-
)
29+
(* This is where the memory allocated to the node can be calculated *)
30+
let remaining_request = NUMARequest.shrink requested candidate in
31+
(NUMAResource.union allocated candidate, node :: picked, remaining_request)
3332
in
3433
let plan_valid (avg, nodes) =
3534
let allocated, picked, remaining =
@@ -72,8 +71,8 @@ let plan host nodes ~vm =
7271
| None ->
7372
debug "No allocations possible" ;
7473
None
75-
| Some allocated ->
74+
| Some (allocated, nodes) ->
7675
debug "Allocated resources: %s"
7776
(Fmt.to_to_string NUMAResource.pp_dump allocated) ;
7877
assert (NUMARequest.fits vm allocated) ;
79-
Some allocated.NUMAResource.affinity
78+
Some (allocated.NUMAResource.affinity, nodes)

ocaml/xenopsd/lib/softaffinity.mli

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414

1515
open Topology
1616

17-
val plan : NUMA.t -> NUMAResource.t array -> vm:NUMARequest.t -> CPUSet.t option
17+
val plan :
18+
NUMA.t
19+
-> NUMAResource.t array
20+
-> vm:NUMARequest.t
21+
-> (Topology.CPUSet.t * Topology.NUMA.node list) option
1822
(** [plan host nodes ~vm] returns the CPU soft affinity recommended for [vm],
1923
Such that the memory latency between the NUMA nodes of the vCPUs is small,
2024
and usage of NUMA nodes is balanced.

ocaml/xenopsd/lib/topology.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ module NUMA = struct
298298
None
299299
else (
300300
List.iter (fun (Node n) -> t.node_usage.(n) <- t.node_usage.(n) + 1) nodes ;
301-
Some result
301+
Some (result, nodes)
302302
)
303303

304304
let pp_dump_node = Fmt.(using (fun (Node x) -> x) int)

ocaml/xenopsd/lib/topology.mli

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ module NUMA : sig
150150
NUMA nodes > 16 it limits the length of the sequence to [n+65520], to
151151
avoid exponential blowup. *)
152152

153-
val choose : t -> (node list * NUMAResource.t) Seq.t -> NUMAResource.t option
153+
val choose :
154+
t
155+
-> (node list * NUMAResource.t) Seq.t
156+
-> (NUMAResource.t * node list) option
154157
(** [choose t resources] will choose one NUMA node deterministically, trying
155158
to keep the overall NUMA node usage balanced *)
156159

ocaml/xenopsd/test/test_topology.ml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,26 +210,28 @@ let test_allocate ?(mem = default_mem) (expected_cores, h) ~vms () =
210210
match Softaffinity.plan h nodes ~vm with
211211
| None ->
212212
Alcotest.fail "No NUMA plan"
213-
| Some plan ->
214-
D.debug "NUMA allocation succeeded for VM %d: %s" i
215-
(Fmt.to_to_string CPUSet.pp_dump plan) ;
213+
| Some (cpu_plan, mem_plan) ->
214+
D.debug
215+
"NUMA allocation succeeded for VM %d: [CPUS: %s]; [nodes: %s]" i
216+
(Fmt.to_to_string CPUSet.pp_dump cpu_plan)
217+
(Fmt.to_to_string Fmt.(Dump.list NUMA.pp_dump_node) mem_plan) ;
216218
let usednodes =
217-
plan
219+
cpu_plan
218220
|> CPUSet.elements
219221
|> List.map (NUMA.node_of_cpu h)
220222
|> List.sort_uniq compare
221223
|> List.to_seq
222224
in
223225
let costs_numa_aware =
224-
vm_access_costs h plans (vm_cores, usednodes, plan)
226+
vm_access_costs h plans (vm_cores, usednodes, cpu_plan)
225227
in
226228
let costs_default =
227229
vm_access_costs h plans (vm_cores, NUMA.nodes h, NUMA.all_cpus h)
228230
in
229231
cost_not_worse ~default:costs_default costs_numa_aware ;
230232
( costs_default :: costs_old
231233
, costs_numa_aware :: costs_new
232-
, ((vm_cores, List.of_seq usednodes), plan) :: plans
234+
, ((vm_cores, List.of_seq usednodes), cpu_plan) :: plans
233235
)
234236
)
235237
([], [], [])

0 commit comments

Comments
 (0)