From 85b2ae96dfcf7dc324d6782f64c848fa412443e4 Mon Sep 17 00:00:00 2001 From: Andrea Bolognani Date: Mon, 6 Nov 2017 16:39:40 +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 --- 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 ++++ .../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 9cec1a0637..82fdfd5f73 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4736,6 +4736,9 @@ + + + @@ -4924,6 +4927,18 @@ + + + + + enabled + disabled + required + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fffcc8e9da..62d0a1683a 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", @@ -882,6 +884,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) @@ -18775,6 +18784,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; @@ -20965,6 +20990,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; } @@ -26214,6 +26251,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 e3f060b122..41443a02c9 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1723,6 +1723,7 @@ typedef enum { VIR_DOMAIN_FEATURE_GIC, VIR_DOMAIN_FEATURE_SMM, VIR_DOMAIN_FEATURE_IOAPIC, + VIR_DOMAIN_FEATURE_HPT, VIR_DOMAIN_FEATURE_LAST } virDomainFeature; @@ -1851,6 +1852,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; @@ -2323,6 +2334,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 5a4d50471d..a91b87d09a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -387,6 +387,7 @@ virDomainHostdevModeTypeToString; virDomainHostdevRemove; virDomainHostdevSubsysPCIBackendTypeToString; virDomainHostdevSubsysTypeToString; +virDomainHPTResizingTypeToString; virDomainHubTypeFromString; virDomainHubTypeToString; virDomainHypervTypeFromString; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 7cb091056b..1badadbc2e 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", ); @@ -4776,6 +4777,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 eb72db33ba..56729e4981 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7489,6 +7489,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 a36e157529..cc7596bad1 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3144,6 +3144,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)