]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Treat memory device source nodemask as strict NUMA policy
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 2 Dec 2025 11:26:28 +0000 (12:26 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Tue, 9 Dec 2025 14:28:02 +0000 (15:28 +0100)
A memory device can have <nodemask/> which specifies which host
NUMA nodes the memory should be allocated from (currently
supported for dimm, virtio-mem and sgx-epc models).
But when generating corresponding command line for the device,
the NUMA policy is taken from the guest NUMA node that
corresponds to the memory device (as defined by target/node) or
overall domain NUMA policy (as defined by <numatune/>).

This may lead to memory being allocated from unexpected NUMA
node. For instance, if the memory device has
<nodemask>0</nodemask> and domain has <numatune> <memory
mode='preferred' nodeset='1'/> </numatune> then the cmd line for
the memory device also has just "policy":"preferred".

Treat <nodemask/> as mode='strict'.

But I agree that this is kind of nonsense configuration. Why
would somebody want to prefer one NUMA node but then configure
memory device to allocate NUMA from the other?

Resolves: https://issues.redhat.com/browse/RHEL-114415
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_command.c
tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args

index fb89dbec2726348d9597ecbcd8002ac25213e037..98229d7cf994ac704ec6490d7de0133add1d93db 100644 (file)
@@ -3497,6 +3497,12 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps,
         if (!virNumaNodesetIsAvailable(nodemask))
             return -1;
 
+        /* Treat source nodes as strict mode, regardless of the target guest
+         * NUMA node mode. */
+        if (hasSourceNodes) {
+            mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+        }
+
         /* If mode is "restrictive", we should only use cgroups setting allowed memory
          * nodes, and skip passing the host-nodes and policy parameters to QEMU command
          * line which means we will use system default memory policy. */
index 23a5f76af268968d759171fd442aa2f7170bc035..cc318977b320036cd34a7b4f80748578b4e82f77 100644 (file)
@@ -34,7 +34,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
 -device '{"driver":"pcie-root-port","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}' \
 -device '{"driver":"qemu-xhci","id":"usb","bus":"pci.1","addr":"0x0"}' \
 -object '{"qom-type":"thread-context","id":"tc-memdimm0","node-affinity":[0]}' \
--object '{"qom-type":"memory-backend-file","id":"memdimm0","mem-path":"/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1","prealloc":true,"size":1073741824,"host-nodes":[0],"policy":"preferred","prealloc-context":"tc-memdimm0"}' \
+-object '{"qom-type":"memory-backend-file","id":"memdimm0","mem-path":"/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1","prealloc":true,"size":1073741824,"host-nodes":[0],"policy":"bind","prealloc-context":"tc-memdimm0"}' \
 -device '{"driver":"pc-dimm","node":0,"memdev":"memdimm0","id":"dimm0","slot":0}' \
 -audiodev '{"id":"audio1","driver":"none"}' \
 -global ICH9-LPC.noreboot=off \