[PATCH 3/8] conf: Add nodeset attribute to the <acpi> element

Andrea Righi via Devel posted 8 patches 1 day, 10 hours ago
[PATCH 3/8] conf: Add nodeset attribute to the <acpi> element
Posted by Andrea Righi via Devel 1 day, 10 hours ago
This enables partitioning of PCI devices into multiple isolated
instances, each requiring a dedicated virtual NUMA node definition.

Link: https://mail.gnu.org/archive/html/qemu-arm/2024-03/msg00358.html
Signed-off-by: Andrea Righi <arighi@nvidia.com>
---
 src/conf/device_conf.h            |  3 +++
 src/conf/domain_conf.c            | 30 ++++++++++++++++++++++++++++--
 src/conf/schemas/domaincommon.rng |  5 +++++
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index 2d97410f6e..e570f51824 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -185,6 +185,9 @@ struct _virDomainDeviceInfo {
      * cases we might want to prevent that from happening by
      * locking the isolation group */
     bool isolationGroupLocked;
+
+    /* NUMA nodeset affinity for this device */
+    virBitmap *acpiNodeset;
 };
 
 int virDeviceHostdevPCIDriverInfoParseXML(xmlNodePtr node,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7766e302ec..8c0bf63925 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5558,8 +5558,20 @@ virDomainDeviceInfoFormat(virBuffer *buf,
         virBufferAddLit(buf, "/>\n");
     }
 
-    if (info->acpiIndex != 0)
-        virBufferAsprintf(buf, "<acpi index='%u'/>\n", info->acpiIndex);
+    if (info->acpiIndex != 0 || info->acpiNodeset) {
+        virBufferAddLit(buf, "<acpi");
+
+        if (info->acpiIndex != 0)
+            virBufferAsprintf(buf, " index='%u'", info->acpiIndex);
+
+        if (info->acpiNodeset) {
+            g_autofree char *nodeset = virBitmapFormat(info->acpiNodeset);
+            if (nodeset)
+                virBufferAsprintf(buf, " nodeset='%s'", nodeset);
+        }
+
+        virBufferAddLit(buf, "/>\n");
+    }
 
     if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
         info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
@@ -5884,9 +5896,23 @@ virDomainDeviceInfoParseXML(virDomainXMLOption *xmlopt,
     }
 
     if ((acpi = virXPathNode("./acpi", ctxt))) {
+        g_autofree char *nodeset = NULL;
+
         if (virXMLPropUInt(acpi, "index", 10, VIR_XML_PROP_NONZERO,
                            &info->acpiIndex) < 0)
             goto cleanup;
+
+        if ((nodeset = virXMLPropString(acpi, "nodeset"))) {
+            if (virBitmapParse(nodeset, &info->acpiNodeset,
+                               VIR_DOMAIN_CPUMASK_LEN) < 0)
+                goto cleanup;
+
+            if (virBitmapIsAllClear(info->acpiNodeset)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("Invalid value of 'nodeset': %1$s"), nodeset);
+                goto cleanup;
+            }
+        }
     }
 
     if ((address = virXPathNode("./address", ctxt)) &&
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index e369fb6e81..298afe0b7c 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -7454,6 +7454,11 @@
           <ref name="unsignedInt"/>
         </attribute>
       </optional>
+      <optional>
+        <attribute name="nodeset">
+          <ref name="cpuset"/>
+        </attribute>
+      </optional>
     </element>
   </define>
 
-- 
2.51.0