[PATCH 0/2] qemu: Treat memory device source nodemask as strict NUMA policy
*** BLURB HERE *** Michal Prívozník (2): qemuxmlconftest: Introduce memory-hotplug-numa-preferred test case qemu: Treat memory device source nodemask as strict NUMA policy src/qemu/qemu_command.c | 6 ++ ...-hotplug-numa-preferred.x86_64-latest.args | 44 ++++++++++++ ...y-hotplug-numa-preferred.x86_64-latest.xml | 1 + .../memory-hotplug-numa-preferred.xml | 68 +++++++++++++++++++ tests/qemuxmlconftest.c | 1 + 5 files changed, 120 insertions(+) create mode 100644 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args create mode 120000 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.xml -- 2.51.2
From: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- ...-hotplug-numa-preferred.x86_64-latest.args | 44 ++++++++++++ ...y-hotplug-numa-preferred.x86_64-latest.xml | 1 + .../memory-hotplug-numa-preferred.xml | 68 +++++++++++++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 114 insertions(+) create mode 100644 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args create mode 120000 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.xml diff --git a/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args b/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args new file mode 100644 index 0000000000..23a5f76af2 --- /dev/null +++ b/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args @@ -0,0 +1,44 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine q35,usb=off,dump-guest-core=off,acpi=off \ +-accel tcg \ +-cpu EPYC,monitor=on,x2apic=on,hypervisor=on,acpi=on,ss=on,erms=on,mpx=on,clwb=on,umip=on,pku=on,vaes=on,la57=on,rdpid=on,pks=on,fsrm=on,cmpccxadd=on,fzrm=on,fsrs=on,fsrc=on,cmp-legacy=on,3dnowext=on,3dnow=on,xsaveerptr=on,wbnoinvd=on,npt=on,vgif=on,svme-addr-chk=on,no-nested-data-bp=on,null-sel-clr-base=on,vme=off,xsavec=off,misalignsse=off,osvw=off,topoext=off,fxsr-opt=off,nrip-save=off \ +-m size=2097152k,slots=16,maxmem=15243264k \ +-overcommit mem-lock=off \ +-smp 4,sockets=4,cores=1,threads=1 \ +-object '{"qom-type":"memory-backend-ram","id":"ram-node0","size":1073741824,"host-nodes":[1],"policy":"preferred"}' \ +-numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \ +-object '{"qom-type":"memory-backend-ram","id":"ram-node1","size":1073741824,"host-nodes":[1],"policy":"preferred"}' \ +-numa node,nodeid=1,cpus=2-3,memdev=ram-node1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \ +-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ +-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"}' \ +-device '{"driver":"pc-dimm","node":0,"memdev":"memdimm0","id":"dimm0","slot":0}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-global ICH9-LPC.noreboot=off \ +-watchdog-action reset \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.2","addr":"0x0"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.xml b/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.xml new file mode 120000 index 0000000000..c26a67a029 --- /dev/null +++ b/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.xml @@ -0,0 +1 @@ +memory-hotplug-numa-preferred.xml \ No newline at end of file diff --git a/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.xml b/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.xml new file mode 100644 index 0000000000..25987a4367 --- /dev/null +++ b/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.xml @@ -0,0 +1,68 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <maxMemory slots='16' unit='KiB'>15243264</maxMemory> + <memory unit='KiB'>3145728</memory> + <currentMemory unit='KiB'>3145728</currentMemory> + <vcpu placement='static'>4</vcpu> + <numatune> + <memory mode='preferred' nodeset='1'/> + </numatune> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='host-model' check='partial'> + <numa> + <cell id='0' cpus='0-1' memory='1048576' unit='KiB'/> + <cell id='1' cpus='2-3' memory='1048576' unit='KiB'/> + </numa> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='qemu-xhci'> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='1' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/> + </controller> + <controller type='pci' index='2' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='2' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='3' port='0xa'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <watchdog model='itco' action='reset'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/> + </memballoon> + <memory model='dimm'> + <source> + <nodemask>0</nodemask> + <pagesize unit='KiB'>1048576</pagesize> + </source> + <target> + <size unit='KiB'>1048576</size> + <node>0</node> + </target> + <address type='dimm' slot='0'/> + </memory> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index de03c58c8a..b0092c0636 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2962,6 +2962,7 @@ mymain(void) DO_TEST_CAPS_LATEST("memory-hotplug-nvdimm-readonly"); DO_TEST_CAPS_ARCH_LATEST("memory-hotplug-nvdimm-ppc64", "ppc64"); DO_TEST_CAPS_ARCH_LATEST_ABI_UPDATE("memory-hotplug-nvdimm-ppc64", "ppc64"); + DO_TEST_CAPS_LATEST("memory-hotplug-numa-preferred"); DO_TEST_CAPS_LATEST("memory-hotplug-virtio-pmem"); DO_TEST_CAPS_LATEST("memory-hotplug-virtio-mem"); DO_TEST_CAPS_LATEST("memory-hotplug-multiple"); -- 2.51.2
From: Michal Privoznik <mprivozn@redhat.com> 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> --- src/qemu/qemu_command.c | 6 ++++++ .../memory-hotplug-numa-preferred.x86_64-latest.args | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b69fe23236..3736c1bafc 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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. */ diff --git a/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args b/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args index 23a5f76af2..cc318977b3 100644 --- a/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args +++ b/tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args @@ -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 \ -- 2.51.2
On a Wednesday in 2025, Michal Privoznik via Devel wrote:
*** BLURB HERE ***
Michal Prívozník (2): qemuxmlconftest: Introduce memory-hotplug-numa-preferred test case qemu: Treat memory device source nodemask as strict NUMA policy
src/qemu/qemu_command.c | 6 ++ ...-hotplug-numa-preferred.x86_64-latest.args | 44 ++++++++++++ ...y-hotplug-numa-preferred.x86_64-latest.xml | 1 + .../memory-hotplug-numa-preferred.xml | 68 +++++++++++++++++++ tests/qemuxmlconftest.c | 1 + 5 files changed, 120 insertions(+) create mode 100644 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.args create mode 120000 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/memory-hotplug-numa-preferred.xml
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko -
Michal Privoznik