File libxl.add-option-to-disable-disk-cache-flushes-in-qdisk.patch of Package xen.29064
https://bugzilla.novell.com/show_bug.cgi?id=879425
---
tools/libxl/libxl.c | 2 ++
tools/libxl/libxl.h | 12 ++++++++++++
tools/libxl/libxlu_disk.c | 2 ++
tools/libxl/libxlu_disk_i.h | 2 +-
tools/libxl/libxlu_disk_l.l | 1 +
5 files changed, 18 insertions(+), 1 deletion(-)
Index: xen-4.16.2-testing/docs/man/xl-disk-configuration.5.pod.in
===================================================================
--- xen-4.16.2-testing.orig/docs/man/xl-disk-configuration.5.pod.in
+++ xen-4.16.2-testing/docs/man/xl-disk-configuration.5.pod.in
@@ -344,6 +344,32 @@ can be used to disable "hole punching" f
were intentionally created non-sparse to avoid fragmentation of the
file.
+=item B<suse-diskcache-disable-flush>
+
+=over 4
+
+=item Description
+
+Request that the qemu block driver does not automatically flush written data to the backend storage.
+
+=item Supported values
+
+absent, present
+
+=item Mandatory
+
+No
+
+=item Default value
+
+absent
+
+=back
+
+This enables the '-disk cache=unsafe' mode inside qemu.
+In this mode writes to the underlying blockdevice are delayed.
+While using this option in production is dangerous, it improves performance during installation of a domU.
+
=back
Index: xen-4.16.2-testing/tools/include/libxl.h
===================================================================
--- xen-4.16.2-testing.orig/tools/include/libxl.h
+++ xen-4.16.2-testing/tools/include/libxl.h
@@ -528,6 +528,21 @@
#define LIBXL_HAVE_MAX_GRANT_VERSION 1
/*
+ * The libxl_device_disk has no way to indicate that cache=unsafe is
+ * supposed to be used. Provide this knob without breaking the ABI.
+ * This is done by overloading struct libxl_device_disk->readwrite:
+ * readwrite == 0: disk is readonly, cache= does not matter
+ * readwrite == 1: disk is readwrite, backend driver may tweak cache=
+ * readwrite == MAGIC: disk is readwrite, backend driver should ignore
+ * flush requests from the frontend driver.
+ * Note: the macro with MAGIC is used by libvirt to decide if this patch is applied
+ */
+#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MAGIC 0x00006000U
+#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MASK 0xffff0fffU
+#define LIBXL_SUSE_IS_CACHE_UNSAFE(rw) (((rw) & ~LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MASK) == LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MAGIC)
+#define LIBXL_SUSE_SET_CACHE_UNSAFE(rw) (((rw) & LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MASK) | LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MAGIC)
+
+/*
* libxl ABI compatibility
*
* The only guarantee which libxl makes regarding ABI compatibility
Index: xen-4.16.2-testing/tools/libs/light/libxl_disk.c
===================================================================
--- xen-4.16.2-testing.orig/tools/libs/light/libxl_disk.c
+++ xen-4.16.2-testing/tools/libs/light/libxl_disk.c
@@ -387,6 +387,8 @@ static void device_disk_add(libxl__egc *
flexarray_append_pair(back, "discard-enable",
libxl_defbool_val(disk->discard_enable) ?
"1" : "0");
+ if (LIBXL_SUSE_IS_CACHE_UNSAFE(disk->readwrite))
+ flexarray_append_pair(back, "suse-diskcache-disable-flush", "1");
flexarray_append(front, "backend-id");
flexarray_append(front, GCSPRINTF("%d", disk->backend_domid));
Index: xen-4.16.2-testing/tools/libs/light/libxl_dm.c
===================================================================
--- xen-4.16.2-testing.orig/tools/libs/light/libxl_dm.c
+++ xen-4.16.2-testing/tools/libs/light/libxl_dm.c
@@ -1019,14 +1019,27 @@ enum {
LIBXL__COLO_SECONDARY,
};
+static const char *qemu_cache_mode(const libxl_device_disk *disk)
+{
+ static const char cache_directsync[] = "directsync";
+ static const char cache_writeback[] = "writeback";
+ static const char cache_unsafe[] = "unsafe";
+
+ if (LIBXL_SUSE_IS_CACHE_UNSAFE(disk->readwrite))
+ return cache_unsafe;
+ if (disk->direct_io_safe)
+ return cache_directsync;
+ return cache_writeback;
+}
+
static char *qemu_disk_scsi_drive_string(libxl__gc *gc, const char *target_path,
int unit, const char *format,
const libxl_device_disk *disk,
int colo_mode, const char **id_ptr)
{
char *drive = NULL;
- char *common = GCSPRINTF("if=none,readonly=%s,cache=writeback",
- disk->readwrite ? "off" : "on");
+ char *common = GCSPRINTF("if=none,readonly=%s,cache=%s",
+ disk->readwrite ? "off" : "on", qemu_cache_mode(disk));
const char *exportname = disk->colo_export;
const char *active_disk = disk->active_disk;
const char *hidden_disk = disk->hidden_disk;
@@ -1085,8 +1098,8 @@ static char *qemu_disk_ide_drive_string(
switch (colo_mode) {
case LIBXL__COLO_NONE:
drive = GCSPRINTF
- ("file=%s,if=ide,index=%d,media=disk,format=%s,cache=writeback",
- target_path, unit, format);
+ ("file=%s,if=ide,index=%d,media=disk,format=%s,cache=%s",
+ target_path, unit, format, qemu_cache_mode(disk));
break;
case LIBXL__COLO_PRIMARY:
/*
@@ -1099,13 +1112,14 @@ static char *qemu_disk_ide_drive_string(
* vote-threshold=1
*/
drive = GCSPRINTF(
- "if=ide,index=%d,media=disk,cache=writeback,driver=quorum,"
+ "if=ide,index=%d,media=disk,cache=%s,driver=quorum,"
"id=%s,"
"children.0.file.filename=%s,"
"children.0.driver=%s,"
"read-pattern=fifo,"
"vote-threshold=1",
- unit, exportname, target_path, format);
+ unit, qemu_cache_mode(disk),
+ exportname, target_path, format);
break;
case LIBXL__COLO_SECONDARY:
/*
@@ -1119,7 +1133,7 @@ static char *qemu_disk_ide_drive_string(
* file.backing.backing=exportname,
*/
drive = GCSPRINTF(
- "if=ide,index=%d,id=top-colo,media=disk,cache=writeback,"
+ "if=ide,index=%d,id=top-colo,media=disk,cache=%s,"
"driver=replication,"
"mode=secondary,"
"top-id=top-colo,"
@@ -1128,7 +1142,8 @@ static char *qemu_disk_ide_drive_string(
"file.backing.driver=qcow2,"
"file.backing.file.filename=%s,"
"file.backing.backing=%s",
- unit, active_disk, hidden_disk, exportname);
+ unit, qemu_cache_mode(disk),
+ active_disk, hidden_disk, exportname);
break;
default:
abort();
@@ -1998,8 +2013,8 @@ static int libxl__build_device_model_arg
return ERROR_INVAL;
}
flexarray_vappend(dm_args, "-drive",
- GCSPRINTF("file=%s,if=none,id=ahcidisk-%d,format=%s,cache=writeback",
- target_path, disk, format),
+ GCSPRINTF("file=%s,if=none,id=ahcidisk-%d,format=%s,cache=%s",
+ target_path, disk, format, qemu_cache_mode(&disks[i])),
"-device", GCSPRINTF("ide-hd,bus=ahci0.%d,unit=0,drive=ahcidisk-%d",
disk, disk), NULL);
continue;
Index: xen-4.16.2-testing/tools/libs/util/libxlu_disk.c
===================================================================
--- xen-4.16.2-testing.orig/tools/libs/util/libxlu_disk.c
+++ xen-4.16.2-testing/tools/libs/util/libxlu_disk.c
@@ -78,6 +78,8 @@ int xlu_disk_parse(XLU_Config *cfg,
if (!disk->pdev_path || !strcmp(disk->pdev_path, ""))
disk->format = LIBXL_DISK_FORMAT_EMPTY;
}
+ if (disk->readwrite && dpc.suse_diskcache_disable_flush)
+ disk->readwrite = LIBXL_SUSE_SET_CACHE_UNSAFE(disk->readwrite);
if (!disk->vdev) {
xlu__disk_err(&dpc,0, "no vdev specified");
Index: xen-4.16.2-testing/tools/libs/util/libxlu_disk_i.h
===================================================================
--- xen-4.16.2-testing.orig/tools/libs/util/libxlu_disk_i.h
+++ xen-4.16.2-testing/tools/libs/util/libxlu_disk_i.h
@@ -10,7 +10,7 @@ typedef struct {
void *scanner;
YY_BUFFER_STATE buf;
libxl_device_disk *disk;
- int access_set, had_depr_prefix;
+ int access_set, suse_diskcache_disable_flush, had_depr_prefix;
const char *spec;
} DiskParseContext;
Index: xen-4.16.2-testing/tools/libs/util/libxlu_disk_l.l
===================================================================
--- xen-4.16.2-testing.orig/tools/libs/util/libxlu_disk_l.l
+++ xen-4.16.2-testing/tools/libs/util/libxlu_disk_l.l
@@ -207,6 +207,7 @@ colo-port=[^,]*,? { STRIP(','); setcolop
colo-export=[^,]*,? { STRIP(','); SAVESTRING("colo-export", colo_export, FROMEQUALS); }
active-disk=[^,]*,? { STRIP(','); SAVESTRING("active-disk", active_disk, FROMEQUALS); }
hidden-disk=[^,]*,? { STRIP(','); SAVESTRING("hidden-disk", hidden_disk, FROMEQUALS); }
+suse-diskcache-disable-flush,? { DPC->suse_diskcache_disable_flush = 1; }
/* the target magic parameter, eats the rest of the string */