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