[PATCH] qemu: Add NUMA node automatically for memory hotplug

Michal Privoznik posted 1 patch 9 months, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/8220d78f7a0cc2c51197363a0bcd3828b8ece32c.1689238089.git.mprivozn@redhat.com
src/qemu/qemu_domain.c                        | 53 ++++++++++++++++++-
...emory-hotplug-ppc64-nonuma-abi-update.args | 11 ++--
...memory-hotplug-ppc64-nonuma-abi-update.xml |  7 ++-
3 files changed, 63 insertions(+), 8 deletions(-)
[PATCH] qemu: Add NUMA node automatically for memory hotplug
Posted by Michal Privoznik 9 months, 3 weeks ago
Up until v2.11.0-rc2~19^2~3 QEMU used to require at least one
NUMA node to be configured when memory hotplug was enabled. After
that commit, QEMU automatically adds a NUMA node if none was
specified on the cmd line. Reflect this in domain XML, i.e.
explicitly add a NUMA node into our domain definition if needed.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
 src/qemu/qemu_domain.c                        | 53 ++++++++++++++++++-
 ...emory-hotplug-ppc64-nonuma-abi-update.args | 11 ++--
 ...memory-hotplug-ppc64-nonuma-abi-update.xml |  7 ++-
 3 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3700b3e711..a9ed5f5901 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4807,6 +4807,51 @@ qemuDomainDefTsegPostParse(virDomainDef *def,
 }
 
 
+static int
+qemuDomainDefNumaAutoAdd(virDomainDef *def,
+                         unsigned int parseFlags)
+{
+    bool abiUpdate = !!(parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE);
+    unsigned long long initialMem;
+    size_t i;
+
+    if (!abiUpdate ||
+        !virDomainDefHasMemoryHotplug(def) ||
+        virDomainNumaGetNodeCount(def->numa) > 0) {
+        return 0;
+    }
+
+    initialMem = virDomainDefGetMemoryInitial(def);
+
+    if (!def->numa)
+        def->numa = virDomainNumaNew();
+
+    virDomainNumaSetNodeCount(def->numa, 1);
+    virDomainNumaSetNodeMemorySize(def->numa, 0, initialMem);
+
+    for (i = 0; i < def->nmems; i++) {
+        virDomainMemoryDef *mem = def->mems[i];
+
+        switch (mem->model) {
+        case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+            if (mem->targetNode == -1)
+                mem->targetNode = 0;
+            break;
+
+        case VIR_DOMAIN_MEMORY_MODEL_NONE:
+        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+        case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
+        case VIR_DOMAIN_MEMORY_MODEL_LAST:
+            break;
+        }
+    }
+
+    return 0;
+}
+
+
 /**
  * qemuDomainDefNumaCPUsRectify:
  * @numa: pointer to numa definition
@@ -4841,8 +4886,12 @@ qemuDomainDefNumaCPUsRectify(virDomainDef *def,
 
 static int
 qemuDomainDefNumaCPUsPostParse(virDomainDef *def,
-                               virQEMUCaps *qemuCaps)
+                               virQEMUCaps *qemuCaps,
+                               unsigned int parseFlags)
 {
+    if (qemuDomainDefNumaAutoAdd(def, parseFlags) < 0)
+        return -1;
+
     return qemuDomainDefNumaCPUsRectify(def, qemuCaps);
 }
 
@@ -4914,7 +4963,7 @@ qemuDomainDefPostParse(virDomainDef *def,
     if (qemuDomainDefTsegPostParse(def, qemuCaps) < 0)
         return -1;
 
-    if (qemuDomainDefNumaCPUsPostParse(def, qemuCaps) < 0)
+    if (qemuDomainDefNumaCPUsPostParse(def, qemuCaps, parseFlags) < 0)
         return -1;
 
     return 0;
diff --git a/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args b/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args
index 83bfb1123c..18ae15aa0b 100644
--- a/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args
+++ b/tests/qemuxml2argvdata/memory-hotplug-ppc64-nonuma-abi-update.args
@@ -10,13 +10,14 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
 -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 pseries,usb=off,dump-guest-core=off,memory-backend=ppc_spapr.ram \
+-machine pseries,usb=off,dump-guest-core=off \
 -accel kvm \
 -cpu POWER9 \
--m size=1048576k,slots=16,maxmem=4194304k \
--object '{"qom-type":"memory-backend-ram","id":"ppc_spapr.ram","size":1073741824}' \
+-m size=1310720k,slots=16,maxmem=4194304k \
 -overcommit mem-lock=off \
 -smp 1,sockets=1,cores=1,threads=1 \
+-object '{"qom-type":"memory-backend-ram","id":"ram-node0","size":1342177280}' \
+-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
 -uuid 49545eb3-75e1-2d0a-acdd-f0294406c99e \
 -display none \
 -no-user-config \
@@ -27,9 +28,9 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
 -no-shutdown \
 -boot strict=on \
 -object '{"qom-type":"memory-backend-ram","id":"memdimm0","size":536870912}' \
--device '{"driver":"pc-dimm","memdev":"memdimm0","id":"dimm0","slot":0}' \
+-device '{"driver":"pc-dimm","node":0,"memdev":"memdimm0","id":"dimm0","slot":0}' \
 -object '{"qom-type":"memory-backend-ram","id":"memdimm1","size":536870912}' \
--device '{"driver":"pc-dimm","memdev":"memdimm1","id":"dimm1","slot":1}' \
+-device '{"driver":"pc-dimm","node":0,"memdev":"memdimm1","id":"dimm1","slot":1}' \
 -audiodev '{"id":"audio1","driver":"none"}' \
 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
 -msg timestamp=on
diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml b/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml
index d0be98f140..c4677dc977 100644
--- a/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml
+++ b/tests/qemuxml2xmloutdata/memory-hotplug-ppc64-nonuma-abi-update.xml
@@ -2,7 +2,7 @@
   <name>QEMUGuest1</name>
   <uuid>49545eb3-75e1-2d0a-acdd-f0294406c99e</uuid>
   <maxMemory slots='16' unit='KiB'>4194304</maxMemory>
-  <memory unit='KiB'>2097152</memory>
+  <memory unit='KiB'>2098177</memory>
   <currentMemory unit='KiB'>2097152</currentMemory>
   <vcpu placement='static'>1</vcpu>
   <os>
@@ -11,6 +11,9 @@
   </os>
   <cpu mode='custom' match='exact' check='none'>
     <model fallback='forbid'>POWER9</model>
+    <numa>
+      <cell id='0' cpus='0' memory='1049601' unit='KiB'/>
+    </numa>
   </cpu>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
@@ -29,12 +32,14 @@
     <memory model='dimm'>
       <target>
         <size unit='KiB'>524288</size>
+        <node>0</node>
       </target>
       <address type='dimm' slot='0'/>
     </memory>
     <memory model='dimm'>
       <target>
         <size unit='KiB'>524288</size>
+        <node>0</node>
       </target>
       <address type='dimm' slot='1'/>
     </memory>
-- 
2.41.0
Re: [PATCH] qemu: Add NUMA node automatically for memory hotplug
Posted by Kristina Hanicova 9 months, 3 weeks ago
On Thu, Jul 13, 2023 at 4:23 PM Michal Privoznik <mprivozn@redhat.com>
wrote:

> Up until v2.11.0-rc2~19^2~3 QEMU used to require at least one
> NUMA node to be configured when memory hotplug was enabled. After
> that commit, QEMU automatically adds a NUMA node if none was
> specified on the cmd line. Reflect this in domain XML, i.e.
> explicitly add a NUMA node into our domain definition if needed.
>
> Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
> ---
>  src/qemu/qemu_domain.c                        | 53 ++++++++++++++++++-
>  ...emory-hotplug-ppc64-nonuma-abi-update.args | 11 ++--
>  ...memory-hotplug-ppc64-nonuma-abi-update.xml |  7 ++-
>  3 files changed, 63 insertions(+), 8 deletions(-)
>

Reviewed-by: Kristina Hanicova <khanicov@redhat.com>
Kristina