Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv

protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver";
protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver";
private final static long HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IO_URING = 6003000;
private final static long HYPERVISOR_QEMU_VERSION_SUPPORTS_IO_URING = 5000000;

protected HypervisorType _hypervisorType;
protected String _hypervisorURI;
Expand Down Expand Up @@ -342,6 +344,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected MemStat _memStat = new MemStat(_dom0MinMem, _dom0OvercommitMem);
private final LibvirtUtilitiesHelper libvirtUtilitiesHelper = new LibvirtUtilitiesHelper();

protected long getHypervisorLibvirtVersion() {
return _hypervisorLibvirtVersion;
}

protected long getHypervisorQemuVersion() {
return _hypervisorQemuVersion;
}

@Override
public ExecutionResult executeInVR(final String routerIp, final String script, final String args) {
return executeInVR(routerIp, script, args, _timeout);
Expand Down Expand Up @@ -2619,6 +2629,8 @@ public int compare(final DiskTO arg0, final DiskTO arg1) {
disk.setDiscard(DiscardType.UNMAP);
}

setDiskIoDriver(disk);

if (pool.getType() == StoragePoolType.RBD) {
/*
For RBD pools we use the secret mechanism in libvirt.
Expand Down Expand Up @@ -2719,6 +2731,18 @@ private KVMPhysicalDisk getPhysicalDiskPrimaryStore(PrimaryDataStoreTO primaryDa
return storagePool.getPhysicalDisk(data.getPath());
}

/**
* Set Disk IO Driver, if supported by the Libvirt/Qemu version.
* IO Driver works for:
* (i) Qemu >= 5.0;
* (ii) Libvirt >= 6.3.0
*/
protected void setDiskIoDriver(DiskDef disk) {
if (getHypervisorLibvirtVersion() >= HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IO_URING && getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_SUPPORTS_IO_URING) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and tests have passed, but this enables io_uring as default for the matching version of qemu and libvirt, could that cause an issue @GabrielBrascher for different type of guest OS?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rhtyd as far as I know there are no issues with different types of guest OS.
This would impact the Hypervisor side; thus, it is important that the virtualization layer supports it.
As far as I know, both Ubuntu and Centos would support as long as the Qemu >= 5.0 and Libvirt >= 6.3.0.

One issue that I have seen with this proposed implementation is when (live) migrating from a KVM node that supports IO_URING to one that does not. I will check how to update the IO Driver when migrating.

disk.setIoDriver(DiskDef.IoDriver.IOURING);
}
}

private KVMPhysicalDisk getPhysicalDiskFromNfsStore(String dataStoreUrl, DataTO data) {
final String volPath = dataStoreUrl + File.separator + data.getPath();
final int index = volPath.lastIndexOf("/");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,26 @@ public String toString() {

}

/**
* This enum specifies IO Drivers, each option controls specific policies on I/O.
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
*/
public enum IoDriver {
NATIVE("native"),
THREADS("threads"),
IOURING("io_uring");
String ioDriver;

IoDriver(String driver) {
ioDriver = driver;
}

@Override
public String toString() {
return ioDriver;
}
}

private DeviceType _deviceType; /* floppy, disk, cdrom */
private DiskType _diskType;
private DiskProtocol _diskProtocol;
Expand Down Expand Up @@ -681,6 +701,7 @@ public String toString() {
private String _serial;
private boolean qemuDriver = true;
private DiscardType _discard = DiscardType.IGNORE;
private IoDriver ioDriver;

public DiscardType getDiscard() {
return _discard;
Expand All @@ -690,6 +711,14 @@ public void setDiscard(DiscardType discard) {
this._discard = discard;
}

public DiskDef.IoDriver getIoDriver() {
return ioDriver;
}

public void setIoDriver(IoDriver ioDriver) {
this.ioDriver = ioDriver;
}

public void setDeviceType(DeviceType deviceType) {
_deviceType = deviceType;
}
Expand Down Expand Up @@ -1001,6 +1030,11 @@ public String toString() {
if(_discard != null && _discard != DiscardType.IGNORE) {
diskBuilder.append("discard='" + _discard.toString() + "' ");
}

if(ioDriver != null) {
diskBuilder.append(String.format("io='%s'", ioDriver));
}

diskBuilder.append("/>\n");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ public class LibvirtComputingResourceTest {
@Mock
LibvirtVMDef vmDef;

private final static long HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IOURING = 6003000;
private final static long HYPERVISOR_QEMU_VERSION_SUPPORTS_IOURING = 5000000;

String hyperVisorType = "kvm";
Random random = new Random();
final String memInfo = "MemTotal: 5830236 kB\n" +
Expand Down Expand Up @@ -5209,4 +5212,37 @@ public void testAddExtraConfigComponentNotEmptyExtraConfig() {
libvirtComputingResource.addExtraConfigComponent(extraConfig, vmDef);
Mockito.verify(vmDef, times(1)).addComp(any());
}

@Test
public void setDiskIoDriverTestIoUring() {
DiskDef diskDef = configureAndTestSetDiskIoDriverTest(HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IOURING, HYPERVISOR_QEMU_VERSION_SUPPORTS_IOURING);
Assert.assertEquals(DiskDef.IoDriver.IOURING, diskDef.getIoDriver());
}

@Test
public void setDiskIoDriverTestLibvirtSupportsIoUring() {
DiskDef diskDef = configureAndTestSetDiskIoDriverTest(123l, HYPERVISOR_QEMU_VERSION_SUPPORTS_IOURING);
Assert.assertNotEquals(DiskDef.IoDriver.IOURING, diskDef.getIoDriver());
}

@Test
public void setDiskIoDriverTestQemuSupportsIoUring() {
DiskDef diskDef = configureAndTestSetDiskIoDriverTest(HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IOURING, 123l);
Assert.assertNotEquals(DiskDef.IoDriver.IOURING, diskDef.getIoDriver());
}

@Test
public void setDiskIoDriverTestNoSupportToIoUring() {
DiskDef diskDef = configureAndTestSetDiskIoDriverTest(123l, 123l);
Assert.assertNotEquals(DiskDef.IoDriver.IOURING, diskDef.getIoDriver());
}

private DiskDef configureAndTestSetDiskIoDriverTest(long hypervisorLibvirtVersion, long hypervisorQemuVersion) {
DiskDef diskDef = new DiskDef();
LibvirtComputingResource libvirtComputingResourceSpy = Mockito.spy(new LibvirtComputingResource());
Mockito.when(libvirtComputingResourceSpy.getHypervisorLibvirtVersion()).thenReturn(hypervisorLibvirtVersion);
Mockito.when(libvirtComputingResourceSpy.getHypervisorQemuVersion()).thenReturn(hypervisorQemuVersion);
libvirtComputingResourceSpy.setDiskIoDriver(diskDef);
return diskDef;
}
}