mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 03:12:22 +00:00
qemu: Add support for paravirtual spinlocks in the guest
The linux kernel recently added support for paravirtual spinlock handling to avoid performance regressions on overcomitted hosts. This feature needs to be turned in the hypervisor so that the guest OS is notified about the possible support. This patch adds a new feature "paravirt-spinlock" to the XML and supporting code to enable the "kvm_pv_unhalt" pseudo CPU feature in qemu. https://bugzilla.redhat.com/show_bug.cgi?id=1008989
This commit is contained in:
parent
de7b5faf43
commit
e0dc851164
@ -1193,6 +1193,7 @@
|
||||
<vapic state='on'/>
|
||||
<spinlocks state='on' retries='4096'/>
|
||||
</hyperv>
|
||||
<pvspinlock/>
|
||||
|
||||
</features>
|
||||
...</pre>
|
||||
@ -1264,6 +1265,13 @@
|
||||
</tr>
|
||||
</table>
|
||||
</dd>
|
||||
<dt><code>pvspinlock</code></dt>
|
||||
<dd>Notify the guest that the host supports paravirtual spinlocks
|
||||
for example by exposing the pvticketlocks mechanism. This feature
|
||||
can be explicitly disabled by using <code>state='off'</code>
|
||||
attribute.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="elementsTime">Time keeping</a></h3>
|
||||
|
@ -3561,7 +3561,7 @@
|
||||
</define>
|
||||
<!--
|
||||
A set of optional features: PAE, APIC, ACPI,
|
||||
HyperV Enlightenment and HAP support
|
||||
HyperV Enlightenment, paravirtual spinlocks and HAP support
|
||||
-->
|
||||
<define name="features">
|
||||
<optional>
|
||||
@ -3607,6 +3607,14 @@
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="pvspinlock">
|
||||
<optional>
|
||||
<ref name="featurestate"/>
|
||||
</optional>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</optional>
|
||||
|
@ -142,7 +142,8 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
|
||||
"hap",
|
||||
"viridian",
|
||||
"privnet",
|
||||
"hyperv")
|
||||
"hyperv",
|
||||
"pvspinlock")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainFeatureState, VIR_DOMAIN_FEATURE_STATE_LAST,
|
||||
"default",
|
||||
@ -11440,6 +11441,22 @@ virDomainDefParseXML(xmlDocPtr xml,
|
||||
def->features[val] = VIR_DOMAIN_FEATURE_STATE_ON;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_FEATURE_PVSPINLOCK:
|
||||
node = ctxt->node;
|
||||
ctxt->node = nodes[i];
|
||||
if ((tmp = virXPathString("string(./@state)", ctxt))) {
|
||||
if ((def->features[val] = virDomainFeatureStateTypeFromString(tmp)) == -1) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("unknown state atribute '%s' of feature '%s'"),
|
||||
tmp, virDomainFeatureTypeToString(val));
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
def->features[val] = VIR_DOMAIN_FEATURE_STATE_ON;
|
||||
}
|
||||
ctxt->node = node;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_FEATURE_LAST:
|
||||
break;
|
||||
}
|
||||
@ -16807,6 +16824,23 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
||||
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_FEATURE_PVSPINLOCK:
|
||||
switch ((enum virDomainFeatureState) def->features[i]) {
|
||||
case VIR_DOMAIN_FEATURE_STATE_LAST:
|
||||
case VIR_DOMAIN_FEATURE_STATE_DEFAULT:
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_FEATURE_STATE_ON:
|
||||
virBufferAsprintf(buf, " <%s state='on'/>\n", name);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_FEATURE_STATE_OFF:
|
||||
virBufferAsprintf(buf, " <%s state='off'/>\n", name);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_FEATURE_APIC:
|
||||
if (def->features[i] == VIR_DOMAIN_FEATURE_STATE_ON) {
|
||||
virBufferAddLit(buf, " <apic");
|
||||
|
@ -1619,6 +1619,7 @@ enum virDomainFeature {
|
||||
VIR_DOMAIN_FEATURE_VIRIDIAN,
|
||||
VIR_DOMAIN_FEATURE_PRIVNET,
|
||||
VIR_DOMAIN_FEATURE_HYPERV,
|
||||
VIR_DOMAIN_FEATURE_PVSPINLOCK,
|
||||
|
||||
VIR_DOMAIN_FEATURE_LAST
|
||||
};
|
||||
|
@ -6718,6 +6718,19 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
|
||||
have_cpu = true;
|
||||
}
|
||||
|
||||
if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK]) {
|
||||
char sign;
|
||||
if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_DOMAIN_FEATURE_STATE_ON)
|
||||
sign = '+';
|
||||
else
|
||||
sign = '-';
|
||||
|
||||
virBufferAsprintf(&buf, "%s,%ckvm_pv_unhalt",
|
||||
have_cpu ? "" : default_model,
|
||||
sign);
|
||||
have_cpu = true;
|
||||
}
|
||||
|
||||
if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_FEATURE_STATE_ON) {
|
||||
if (!have_cpu) {
|
||||
virBufferAdd(&buf, default_model, -1);
|
||||
|
@ -0,0 +1,5 @@
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
|
||||
/usr/bin/qemu -S -M pc \
|
||||
-cpu qemu32,-kvm_pv_unhalt -m 214 -smp 6 -nographic -monitor \
|
||||
unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial \
|
||||
none -parallel none
|
26
tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml
Normal file
26
tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<domain type='qemu'>
|
||||
<name>QEMUGuest1</name>
|
||||
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory unit='KiB'>219100</memory>
|
||||
<currentMemory unit='KiB'>219100</currentMemory>
|
||||
<vcpu placement='static'>6</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='network'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<pae/>
|
||||
<pvspinlock state='off'/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu</emulator>
|
||||
<controller type='usb' index='0'/>
|
||||
<controller type='pci' index='0' model='pci-root'/>
|
||||
<memballoon model='virtio'/>
|
||||
</devices>
|
||||
</domain>
|
@ -0,0 +1,5 @@
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
|
||||
/usr/bin/qemu -S -M pc \
|
||||
-cpu qemu32,+kvm_pv_unhalt -m 214 -smp 6 -nographic -monitor \
|
||||
unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial \
|
||||
none -parallel none
|
26
tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml
Normal file
26
tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<domain type='qemu'>
|
||||
<name>QEMUGuest1</name>
|
||||
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory unit='KiB'>219100</memory>
|
||||
<currentMemory unit='KiB'>219100</currentMemory>
|
||||
<vcpu placement='static'>6</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='network'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<pae/>
|
||||
<pvspinlock state='on'/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu</emulator>
|
||||
<controller type='usb' index='0'/>
|
||||
<controller type='pci' index='0' model='pci-root'/>
|
||||
<memballoon model='virtio'/>
|
||||
</devices>
|
||||
</domain>
|
@ -448,6 +448,8 @@ mymain(void)
|
||||
QEMU_CAPS_CHARDEV_SPICEVMC, QEMU_CAPS_SPICE, QEMU_CAPS_HDA_DUPLEX);
|
||||
DO_TEST("eoi-disabled", NONE);
|
||||
DO_TEST("eoi-enabled", NONE);
|
||||
DO_TEST("pv-spinlock-disabled", NONE);
|
||||
DO_TEST("pv-spinlock-enabled", NONE);
|
||||
DO_TEST("kvmclock+eoi-disabled", QEMU_CAPS_ENABLE_KVM);
|
||||
|
||||
DO_TEST("hyperv", NONE);
|
||||
|
@ -159,6 +159,8 @@ mymain(void)
|
||||
DO_TEST("cpu-eoi-enabled");
|
||||
DO_TEST("eoi-disabled");
|
||||
DO_TEST("eoi-enabled");
|
||||
DO_TEST("pv-spinlock-disabled");
|
||||
DO_TEST("pv-spinlock-enabled");
|
||||
|
||||
DO_TEST("hyperv");
|
||||
DO_TEST("hyperv-off");
|
||||
|
Loading…
x
Reference in New Issue
Block a user