Skip to content

Commit c4b621a

Browse files
kiwiflyerrohityadavcloud
authored andcommitted
kvm: HyperV Enlightment for Improved Windows Server 2008+ Performance (#2870)
Windows has support for several paravirt features that it will use when running on Hyper-V, Microsoft's hypervisor. These features are called enlightenments. Many of the features are similar to paravirt functionality that exists with Linux on KVM (virtio, kvmclock, PV EOI, etc.) Nowadays QEMU/KVM can also enable support for several Hyper-V enlightenments. When enabled, Windows VMs running on KVM will use many of the same paravirt optimizations they would use when running on Hyper-V. A number of years ago, a PR was introduced that added a good portion of the code to enable this feature set, but it was never completed. This PR enables the existing features. The previous patch set detailed in #1013 also included the tests. By selecting Windows PV, the enlightenment additions will be applied to the libvirt configuration. This is support on Windows Server 2008 and beyond, so all currently supported versions of Windows Server. In our testing, we've seen benchmark improvements of around 20-25% running on Centos 7 hosts and it is also supported on Centos/RHEL 6.5 and later. Testing on Ubuntu would be appreciated.
1 parent 6f44a8d commit c4b621a

File tree

3 files changed

+21
-15
lines changed

3 files changed

+21
-15
lines changed

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,19 @@ protected void setQuotaAndPeriod(VirtualMachineTO vmTO, CpuTuneDef ctd) {
20162016
}
20172017
}
20182018

2019+
protected void enlightenWindowsVm(VirtualMachineTO vmTO, FeaturesDef features) {
2020+
if (vmTO.getOs().contains("Windows PV")) {
2021+
// If OS is Windows PV, then enable the features. Features supported on Windows 2008 and later
2022+
LibvirtVMDef.HyperVEnlightenmentFeatureDef hyv = new LibvirtVMDef.HyperVEnlightenmentFeatureDef();
2023+
hyv.setFeature("relaxed", true);
2024+
hyv.setFeature("vapic", true);
2025+
hyv.setFeature("spinlocks", true);
2026+
hyv.setRetries(8096);
2027+
features.addHyperVFeature(hyv);
2028+
s_logger.info("Enabling KVM Enlightment Features to VM domain " + vmTO.getUuid());
2029+
}
2030+
}
2031+
20192032
public LibvirtVMDef createVMFromSpec(final VirtualMachineTO vmTO) {
20202033
final LibvirtVMDef vm = new LibvirtVMDef();
20212034
vm.setDomainName(vmTO.getName());
@@ -2101,14 +2114,10 @@ So if getMinSpeed() returns null we fall back to getSpeed().
21012114
features.addFeatures("pae");
21022115
features.addFeatures("apic");
21032116
features.addFeatures("acpi");
2104-
//for rhel 6.5 and above, hyperv enlightment feature is added
2105-
/*
2106-
* if (vmTO.getOs().contains("Windows Server 2008") && hostOsVersion != null && ((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7))) {
2107-
* LibvirtVMDef.HyperVEnlightenmentFeatureDef hyv = new LibvirtVMDef.HyperVEnlightenmentFeatureDef();
2108-
* hyv.setRelaxed(true);
2109-
* features.addHyperVFeature(hyv);
2110-
* }
2111-
*/
2117+
2118+
//KVM hyperv enlightenment features based on OS Type
2119+
enlightenWindowsVm(vmTO, features);
2120+
21122121
vm.addComp(features);
21132122

21142123
final TermPolicy term = new TermPolicy();
@@ -2120,7 +2129,7 @@ So if getMinSpeed() returns null we fall back to getSpeed().
21202129
final ClockDef clock = new ClockDef();
21212130
if (vmTO.getOs().startsWith("Windows")) {
21222131
clock.setClockOffset(ClockDef.ClockOffset.LOCALTIME);
2123-
clock.setTimer("rtc", "catchup", null);
2132+
clock.setTimer("hypervclock", null, null);
21242133
} else if (vmTO.getType() != VirtualMachine.Type.User || isGuestPVEnabled(vmTO.getOs())) {
21252134
if (_hypervisorLibvirtVersion >= 9 * 1000 + 10) {
21262135
clock.setTimer("kvmclock", null, null, _noKvmClock);

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ public String toString() {
370370

371371
if (_timerName.equals("kvmclock") && _noKvmClock) {
372372
clockBuilder.append("present='no' />");
373+
} else if (_timerName.equals("hypervclock")) {
374+
clockBuilder.append("present='yes' />");
373375
} else {
374376
if (_tickPolicy != null) {
375377
clockBuilder.append("tickpolicy='");

plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
2727
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
2828
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
29-
import com.cloud.utils.Pair;
3029

3130
public class LibvirtVMDefTest extends TestCase {
3231

@@ -155,12 +154,8 @@ public void testHypervEnlightDef() {
155154
assertFalse(defs.contains("relaxed"));
156155
assertFalse(defs.contains("vapic"));
157156
assertFalse(defs.contains("spinlocks"));
158-
assertTrue("Windows Server 2008 R2".contains("Windows Server 2008"));
157+
assertTrue("Windows PV".contains("Windows PV"));
159158

160-
Pair<Integer,Integer> hostOsVersion = new Pair<Integer,Integer>(6,5);
161-
assertTrue((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7));
162-
hostOsVersion = new Pair<Integer,Integer>(7,1);
163-
assertTrue((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7));
164159
}
165160

166161
public void testRngDef() {

0 commit comments

Comments
 (0)