404507
From 6d24efd64d6de00d29f8bf2329940c427f5cc6f9 Mon Sep 17 00:00:00 2001
404507
Message-Id: <6d24efd64d6de00d29f8bf2329940c427f5cc6f9@dist-git>
404507
From: Andrea Bolognani <abologna@redhat.com>
404507
Date: Wed, 15 Nov 2017 10:28:54 +0100
404507
Subject: [PATCH] qemu: Enable configuration of HPT resizing for pSeries guests
404507
404507
Most of the time it's okay to leave this up to negotiation between
404507
the guest and the host, but in some situations it can be useful to
404507
manually decide the behavior, especially to enforce its availability.
404507
404507
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1308743
404507
404507
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
404507
Reviewed-by: John Ferlan <jferlan@redhat.com>
404507
(cherry picked from commit 85b2ae96dfcf7dc324d6782f64c848fa412443e4)
404507
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
404507
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
404507
---
404507
 docs/schemas/domaincommon.rng                    | 15 ++++++++
404507
 src/conf/domain_conf.c                           | 46 +++++++++++++++++++++++-
404507
 src/conf/domain_conf.h                           | 12 +++++++
404507
 src/libvirt_private.syms                         |  1 +
404507
 src/qemu/qemu_capabilities.c                     |  8 +++++
404507
 src/qemu/qemu_capabilities.h                     |  1 +
404507
 src/qemu/qemu_command.c                          | 20 +++++++++++
404507
 src/qemu/qemu_domain.c                           |  8 +++++
404507
 tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml |  1 +
404507
 9 files changed, 111 insertions(+), 1 deletion(-)
404507
404507
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
404507
index 710b3af7f7..367861c1ea 100644
404507
--- a/docs/schemas/domaincommon.rng
404507
+++ b/docs/schemas/domaincommon.rng
404507
@@ -4722,6 +4722,9 @@
404507
           <optional>
404507
             <ref name="ioapic"/>
404507
           </optional>
404507
+          <optional>
404507
+            <ref name="hpt"/>
404507
+          </optional>
404507
         </interleave>
404507
       </element>
404507
     </optional>
404507
@@ -4910,6 +4913,18 @@
404507
     </element>
404507
   </define>
404507
 
404507
+  <define name="hpt">
404507
+    <element name="hpt">
404507
+      <attribute name="resizing">
404507
+        <choice>
404507
+          <value>enabled</value>
404507
+          <value>disabled</value>
404507
+          <value>required</value>
404507
+        </choice>
404507
+      </attribute>
404507
+    </element>
404507
+  </define>
404507
+
404507
   <define name="address">
404507
     <element name="address">
404507
       <choice>
404507
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
404507
index ca5d0bcc54..641a978f07 100644
404507
--- a/src/conf/domain_conf.c
404507
+++ b/src/conf/domain_conf.c
404507
@@ -148,7 +148,9 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
404507
               "vmport",
404507
               "gic",
404507
               "smm",
404507
-              "ioapic")
404507
+              "ioapic",
404507
+              "hpt",
404507
+);
404507
 
404507
 VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST,
404507
               "default",
404507
@@ -877,6 +879,13 @@ VIR_ENUM_IMPL(virDomainIOAPIC,
404507
               "qemu",
404507
               "kvm")
404507
 
404507
+VIR_ENUM_IMPL(virDomainHPTResizing,
404507
+              VIR_DOMAIN_HPT_RESIZING_LAST,
404507
+              "enabled",
404507
+              "disabled",
404507
+              "required",
404507
+);
404507
+
404507
 /* Internal mapping: subset of block job types that can be present in
404507
  * <mirror> XML (remaining types are not two-phase). */
404507
 VIR_ENUM_DECL(virDomainBlockJob)
404507
@@ -18765,6 +18774,22 @@ virDomainDefParseXML(xmlDocPtr xml,
404507
             }
404507
             break;
404507
 
404507
+        case VIR_DOMAIN_FEATURE_HPT:
404507
+            tmp = virXMLPropString(nodes[i], "resizing");
404507
+            if (tmp) {
404507
+                int value = virDomainHPTResizingTypeFromString(tmp);
404507
+                if (value < 0) {
404507
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
404507
+                                   _("Unknown HPT resizing setting: %s"),
404507
+                                   tmp);
404507
+                    goto error;
404507
+                }
404507
+                def->hpt_resizing = value;
404507
+                def->features[val] = VIR_TRISTATE_SWITCH_ON;
404507
+                VIR_FREE(tmp);
404507
+            }
404507
+            break;
404507
+
404507
         /* coverity[dead_error_begin] */
404507
         case VIR_DOMAIN_FEATURE_LAST:
404507
             break;
404507
@@ -20955,6 +20980,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
404507
         return false;
404507
     }
404507
 
404507
+    /* HPT resizing */
404507
+    if (src->features[VIR_DOMAIN_FEATURE_HPT] == VIR_TRISTATE_SWITCH_ON) {
404507
+        if (src->hpt_resizing != dst->hpt_resizing) {
404507
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
404507
+                           _("HPT resizing configuration differs: "
404507
+                             "source: '%s', destination: '%s'"),
404507
+                           virDomainHPTResizingTypeToString(src->hpt_resizing),
404507
+                           virDomainHPTResizingTypeToString(dst->hpt_resizing));
404507
+            return false;
404507
+        }
404507
+    }
404507
+
404507
     return true;
404507
 }
404507
 
404507
@@ -26204,6 +26241,13 @@ virDomainDefFormatInternal(virDomainDefPtr def,
404507
                 }
404507
                 break;
404507
 
404507
+            case VIR_DOMAIN_FEATURE_HPT:
404507
+                if (def->features[i] == VIR_TRISTATE_SWITCH_ON) {
404507
+                    virBufferAsprintf(buf, "<hpt resizing='%s'/>\n",
404507
+                                      virDomainHPTResizingTypeToString(def->hpt_resizing));
404507
+                }
404507
+                break;
404507
+
404507
             /* coverity[dead_error_begin] */
404507
             case VIR_DOMAIN_FEATURE_LAST:
404507
                 break;
404507
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
404507
index 388fa92dda..f967e603d1 100644
404507
--- a/src/conf/domain_conf.h
404507
+++ b/src/conf/domain_conf.h
404507
@@ -1715,6 +1715,7 @@ typedef enum {
404507
     VIR_DOMAIN_FEATURE_GIC,
404507
     VIR_DOMAIN_FEATURE_SMM,
404507
     VIR_DOMAIN_FEATURE_IOAPIC,
404507
+    VIR_DOMAIN_FEATURE_HPT,
404507
 
404507
     VIR_DOMAIN_FEATURE_LAST
404507
 } virDomainFeature;
404507
@@ -1843,6 +1844,16 @@ typedef enum {
404507
 
404507
 VIR_ENUM_DECL(virDomainIOAPIC);
404507
 
404507
+typedef enum {
404507
+    VIR_DOMAIN_HPT_RESIZING_ENABLED = 0,
404507
+    VIR_DOMAIN_HPT_RESIZING_DISABLED,
404507
+    VIR_DOMAIN_HPT_RESIZING_REQUIRED,
404507
+
404507
+    VIR_DOMAIN_HPT_RESIZING_LAST
404507
+} virDomainHPTResizing;
404507
+
404507
+VIR_ENUM_DECL(virDomainHPTResizing);
404507
+
404507
 /* Operating system configuration data & machine / arch */
404507
 typedef struct _virDomainOSEnv virDomainOSEnv;
404507
 typedef virDomainOSEnv *virDomainOSEnvPtr;
404507
@@ -2315,6 +2326,7 @@ struct _virDomainDef {
404507
     virGICVersion gic_version;
404507
     char *hyperv_vendor_id;
404507
     virDomainIOAPIC ioapic;
404507
+    virDomainHPTResizing hpt_resizing;
404507
 
404507
     /* These options are of type virTristateSwitch: ON = keep, OFF = drop */
404507
     int caps_features[VIR_DOMAIN_CAPS_FEATURE_LAST];
404507
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
404507
index 6653f95722..8d1d4a896b 100644
404507
--- a/src/libvirt_private.syms
404507
+++ b/src/libvirt_private.syms
404507
@@ -385,6 +385,7 @@ virDomainHostdevModeTypeToString;
404507
 virDomainHostdevRemove;
404507
 virDomainHostdevSubsysPCIBackendTypeToString;
404507
 virDomainHostdevSubsysTypeToString;
404507
+virDomainHPTResizingTypeToString;
404507
 virDomainHubTypeFromString;
404507
 virDomainHubTypeToString;
404507
 virDomainHypervTypeFromString;
404507
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
404507
index 37a58b3640..3793f16590 100644
404507
--- a/src/qemu/qemu_capabilities.c
404507
+++ b/src/qemu/qemu_capabilities.c
404507
@@ -443,6 +443,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
404507
               /* 270 */
404507
               "vxhs",
404507
               "virtio-blk.num-queues",
404507
+              "machine.pseries.resize-hpt",
404507
     );
404507
 
404507
 
404507
@@ -4780,6 +4781,13 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
404507
     if (qemuCaps->version >= 2006000)
404507
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP_SPLIT);
404507
 
404507
+    /* HPT resizing is supported since QEMU 2.10 on ppc64; unfortunately
404507
+     * there's no sane way to probe for it */
404507
+    if (qemuCaps->version >= 2010000 &&
404507
+        ARCH_IS_PPC64(qemuCaps->arch)) {
404507
+        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
404507
+    }
404507
+
404507
     if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
404507
         goto cleanup;
404507
 
404507
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
404507
index cacc2b77ed..f0e2e9016f 100644
404507
--- a/src/qemu/qemu_capabilities.h
404507
+++ b/src/qemu/qemu_capabilities.h
404507
@@ -429,6 +429,7 @@ typedef enum {
404507
     /* 270 */
404507
     QEMU_CAPS_VXHS, /* -drive file.driver=vxhs via query-qmp-schema */
404507
     QEMU_CAPS_VIRTIO_BLK_NUM_QUEUES, /* virtio-blk-*.num-queues */
404507
+    QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT, /* -machine pseries,resize-hpt */
404507
 
404507
     QEMU_CAPS_LAST /* this must always be the last item */
404507
 } virQEMUCapsFlags;
404507
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
404507
index e60f93083f..aa7079229f 100644
404507
--- a/src/qemu/qemu_command.c
404507
+++ b/src/qemu/qemu_command.c
404507
@@ -7566,6 +7566,26 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
404507
             }
404507
         }
404507
 
404507
+        if (def->features[VIR_DOMAIN_FEATURE_HPT] == VIR_TRISTATE_SWITCH_ON) {
404507
+            const char *str;
404507
+
404507
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT)) {
404507
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
404507
+                               _("HTP resizing is not supported by this "
404507
+                                 "QEMU binary"));
404507
+                goto cleanup;
404507
+            }
404507
+
404507
+            str = virDomainHPTResizingTypeToString(def->hpt_resizing);
404507
+            if (!str) {
404507
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
404507
+                               _("Invalid setting for HPT resizing"));
404507
+                goto cleanup;
404507
+            }
404507
+
404507
+            virBufferAsprintf(&buf, ",resize-hpt=%s", str);
404507
+        }
404507
+
404507
         if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
404507
             virQEMUCapsGet(qemuCaps, QEMU_CAPS_LOADPARM))
404507
             qemuAppendLoadparmMachineParm(&buf, def);
404507
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
404507
index 81f45516af..485e085cea 100644
404507
--- a/src/qemu/qemu_domain.c
404507
+++ b/src/qemu/qemu_domain.c
404507
@@ -3109,6 +3109,14 @@ qemuDomainDefVerifyFeatures(const virDomainDef *def)
404507
         return -1;
404507
     }
404507
 
404507
+    if (def->features[VIR_DOMAIN_FEATURE_HPT] == VIR_TRISTATE_SWITCH_ON &&
404507
+        !qemuDomainIsPSeries(def)) {
404507
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
404507
+                       "%s",
404507
+                       _("HPT tuning is only supported for pSeries guests"));
404507
+        return -1;
404507
+    }
404507
+
404507
     return 0;
404507
 }
404507
 
404507
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
404507
index 0dfa20726c..b0ee3f1523 100644
404507
--- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
404507
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
404507
@@ -177,6 +177,7 @@
404507
   <flag name='virtio-gpu.max_outputs'/>
404507
   <flag name='vxhs'/>
404507
   <flag name='virtio-blk.num-queues'/>
404507
+  <flag name='machine.pseries.resize-hpt'/>
404507
   <version>2010000</version>
404507
   <kvmVersion>0</kvmVersion>
404507
   <package> (v2.10.0)</package>
404507
-- 
404507
2.15.0
404507