
The patch add support L2 table cache for qcow2 disk. L2 table cache can improve IO read and write performance for qcow2 img. Diff follows: src/conf/domain_conf.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 5 +++++ src/qemu/qemu_command.c | 7 +++++++ src/qemu/qemu_domain.c | 6 ++++++ tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args | 2 +- tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml | 3 ++- 6 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index beca0be..0a6afca 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8058,6 +8058,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, char *domain_name = NULL; int expected_secret_usage = -1; int auth_secret_usage = -1; + char *disk_l2_cache_size = NULL; + char *disk_cache_clean_interval = NULL; if (!(def = virDomainDiskDefNew(xmlopt))) return NULL; @@ -8233,6 +8235,27 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, } } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) { /* boot is parsed as part of virDomainDeviceInfoParseXML */ + } else if (xmlStrEqual(cur->name, BAD_CAST "diskCache")) { + disk_l2_cache_size = + virXMLPropString(cur, "disk_l2_cache_size"); + if (disk_l2_cache_size && + virStrToLong_ui(disk_l2_cache_size, NULL, 0, + &def->disk_cache.disk_l2_cache_size) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid disk L2 cache size '%s'"), + disk_l2_cache_size); + goto error; + } + disk_cache_clean_interval = + virXMLPropString(cur, "disk_cache_clean_interval"); + if (disk_cache_clean_interval && + virStrToLong_ui(disk_cache_clean_interval, NULL, 0, + &def->disk_cache.disk_cache_clean_interval) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid disk cache clean interval '%s'"), + disk_cache_clean_interval); + goto error; + } } } @@ -8472,6 +8495,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, VIR_FREE(vendor); VIR_FREE(product); VIR_FREE(domain_name); + VIR_FREE(disk_l2_cache_size); + VIR_FREE(disk_cache_clean_interval); ctxt->node = save_ctxt; return def; @@ -20646,6 +20671,27 @@ virDomainDiskBlockIoDefFormat(virBufferPtr buf, } } +static void +virDomainDiskCacheDefFormat(virBufferPtr buf, + virDomainDiskDefPtr def) +{ + if (def->disk_cache.disk_l2_cache_size > 0 || + def->disk_cache.disk_cache_clean_interval > 0) { + virBufferAddLit(buf, "<diskCache"); + if (def->disk_cache.disk_l2_cache_size > 0) { + virBufferAsprintf(buf, + " disk_l2_cache_size='%u'", + def->disk_cache.disk_l2_cache_size); + } + if (def->disk_cache.disk_cache_clean_interval > 0) { + virBufferAsprintf(buf, + " disk_cache_clean_interval='%u'", + def->disk_cache.disk_cache_clean_interval); + } + virBufferAddLit(buf, "/>\n"); + } +} + /* virDomainSourceDefFormatSeclabel: * @@ -20990,6 +21036,7 @@ virDomainDiskDefFormat(virBufferPtr buf, virDomainDiskGeometryDefFormat(buf, def); virDomainDiskBlockIoDefFormat(buf, def); + virDomainDiskCacheDefFormat(buf, def); /* For now, mirroring is currently output-only: we only output it * for live domains, therefore we ignore it on input except for diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 91a33cb..83ea9d3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -647,6 +647,11 @@ struct _virDomainDiskDef { unsigned int physical_block_size; } blockio; + struct { + unsigned int disk_l2_cache_size; + unsigned int disk_cache_clean_interval; + } disk_cache; + virDomainBlockIoTuneInfo blkdeviotune; char *serial; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index e087891..7c47cd3 100755 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1662,6 +1662,13 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, if (qemuBuildDriveSourceStr(disk, cfg, &opt, qemuCaps) < 0) goto error; + if (disk->disk_cache.disk_l2_cache_size > 0) + virBufferAsprintf(&opt, "l2-cache-size=%u,", + disk->disk_cache.disk_l2_cache_size); + if (disk->disk_cache.disk_cache_clean_interval > 0) + virBufferAsprintf(&opt, "cache-clean-interval=%u,", + disk->disk_cache.disk_cache_clean_interval); + if (emitDeviceSyntax) virBufferAddLit(&opt, "if=none"); else diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9f165c1..de334a7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5408,6 +5408,12 @@ qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk, CHECK_EQ(ioeventfd, "ioeventfd", true); CHECK_EQ(event_idx, "event_idx", true); CHECK_EQ(copy_on_read, "copy_on_read", true); + + CHECK_EQ(disk_cache.disk_l2_cache_size, + "diskCache disk_l2_cache_size", true); + CHECK_EQ(disk_cache.disk_cache_clean_interval, + "diskCache disk_cache_clean_interval", true); + /* "snapshot" is a libvirt internal field and thus can be changed */ /* startupPolicy is allowed to be updated. Therefore not checked here. */ CHECK_EQ(transient, "transient", true); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args index b405242..b968302 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args @@ -22,7 +22,7 @@ QEMU_AUDIO_DRV=none \ -drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,media=cdrom,\ id=drive-ide0-1-0,readonly=on \ -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \ --drive file=/tmp/data.img,format=raw,if=none,id=drive-virtio-disk0 \ +-drive file=/tmp/data.img,format=qcow2,l2-cache-size=536870912,cache-clean-interval=900,if=none,id=drive-virtio-disk0 \ -device virtio-blk-pci,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,\ id=virtio-disk0 \ -drive file=/tmp/logs.img,format=raw,if=none,id=drive-virtio-disk1 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml index b843878..43298fb 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml @@ -28,8 +28,9 @@ <address type='drive' controller='0' bus='1' target='0' unit='0'/> </disk> <disk type='file' device='disk'> - <driver name='qemu' type='raw'/> + <driver name='qemu' type='qcow2'/> <source file='/tmp/data.img'/> + <diskCache disk_l2_cache_size='53687' disk_cache_clean_interval='900' /> <target dev='vda' bus='virtio'/> </disk> <disk type='file' device='disk'> Thanks