peterdelevoryas / rpms / qemu

Forked from rpms/qemu 2 years ago
Clone

Blame 0202-qcow2-Discard-VM-state-in-active-L1-after-creating-s.patch

298366
From 16d78f7cd9e1455ebb0599706ba5badfa3ee4fdc Mon Sep 17 00:00:00 2001
298366
From: Kevin Wolf <kwolf@redhat.com>
298366
Date: Fri, 6 Sep 2013 12:32:26 +0200
298366
Subject: [PATCH] qcow2: Discard VM state in active L1 after creating snapshot
298366
298366
During savevm, the VM state is written to the active L1 of the image and
298366
then a snapshot is taken. After that, the VM state isn't needed any more
298366
in the active L1 and should be discarded. This is implemented by this
298366
patch.
298366
298366
The impact of not discarding the VM state is that a snapshot can never
298366
become smaller than any previous snapshot (because it would be padded
298366
with old VM state), and more importantly that future savevm operations
298366
cause unnecessary COWs (with associated flushes), which makes subsequent
298366
snapshots much slower.
298366
298366
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
298366
---
298366
 block/qcow2-snapshot.c | 7 +++++++
298366
 block/qcow2.c          | 5 -----
298366
 block/qcow2.h          | 5 +++++
298366
 3 files changed, 12 insertions(+), 5 deletions(-)
298366
298366
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
298366
index 0caac90..ae33b45 100644
298366
--- a/block/qcow2-snapshot.c
298366
+++ b/block/qcow2-snapshot.c
298366
@@ -401,6 +401,13 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
298366
 
298366
     g_free(old_snapshot_list);
298366
 
298366
+    /* The VM state isn't needed any more in the active L1 table; in fact, it
298366
+     * hurts by causing expensive COW for the next snapshot. */
298366
+    qcow2_discard_clusters(bs, qcow2_vm_state_offset(s),
298366
+                           align_offset(sn->vm_state_size, s->cluster_size)
298366
+                                >> BDRV_SECTOR_BITS,
298366
+                           QCOW2_DISCARD_NEVER);
298366
+
298366
 #ifdef DEBUG_ALLOC
298366
     {
298366
       BdrvCheckResult result = {0};
298366
diff --git a/block/qcow2.c b/block/qcow2.c
298366
index 16e45a0..f63c2cb 100644
298366
--- a/block/qcow2.c
298366
+++ b/block/qcow2.c
298366
@@ -1666,11 +1666,6 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
298366
     return 0;
298366
 }
298366
 
298366
-static int64_t qcow2_vm_state_offset(BDRVQcowState *s)
298366
-{
298366
-	return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
298366
-}
298366
-
298366
 static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
298366
 {
298366
     BDRVQcowState *s = bs->opaque;
298366
diff --git a/block/qcow2.h b/block/qcow2.h
298366
index 52cf193..da61d18 100644
298366
--- a/block/qcow2.h
298366
+++ b/block/qcow2.h
298366
@@ -324,6 +324,11 @@ static inline int64_t align_offset(int64_t offset, int n)
298366
     return offset;
298366
 }
298366
 
298366
+static inline int64_t qcow2_vm_state_offset(BDRVQcowState *s)
298366
+{
298366
+	return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
298366
+}
298366
+
298366
 static inline int qcow2_get_cluster_type(uint64_t l2_entry)
298366
 {
298366
     if (l2_entry & QCOW_OFLAG_COMPRESSED) {