]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/pve/0047-savevm-async-flush-IOThread-drives-async-before-ente.patch
fix vmstate-snapshots with iothread=1
[pve-qemu.git] / debian / patches / pve / 0047-savevm-async-flush-IOThread-drives-async-before-ente.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Stefan Reiter <s.reiter@proxmox.com>
3 Date: Wed, 27 May 2020 11:33:21 +0200
4 Subject: [PATCH] savevm-async: flush IOThread-drives async before entering
5 blocking part
6
7 By flushing all drives where its possible to so before entering the
8 blocking part (where the VM is stopped), we can reduce the time spent in
9 said part for every disk that has an IOThread (other drives cannot be
10 flushed async anyway).
11
12 Suggested-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
13 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
14 ---
15 savevm-async.c | 23 +++++++++++++++++++++++
16 1 file changed, 23 insertions(+)
17
18 diff --git a/savevm-async.c b/savevm-async.c
19 index 2894c94233..4ce83a0691 100644
20 --- a/savevm-async.c
21 +++ b/savevm-async.c
22 @@ -253,6 +253,8 @@ static void coroutine_fn process_savevm_co(void *opaque)
23 {
24 int ret;
25 int64_t maxlen;
26 + BdrvNextIterator it;
27 + BlockDriverState *bs = NULL;
28
29 ret = qemu_file_get_error(snap_state.file);
30 if (ret < 0) {
31 @@ -288,6 +290,27 @@ static void coroutine_fn process_savevm_co(void *opaque)
32 }
33 }
34
35 + /* If a drive runs in an IOThread we can flush it async, and only
36 + * need to sync-flush whatever IO happens between now and
37 + * vm_stop_force_state. bdrv_next can only be called from main AioContext,
38 + * so move there now and after every flush.
39 + */
40 + aio_co_reschedule_self(qemu_get_aio_context());
41 + for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
42 + /* target has BDRV_O_NO_FLUSH, no sense calling bdrv_flush on it */
43 + if (bs == blk_bs(snap_state.target)) {
44 + continue;
45 + }
46 +
47 + AioContext *bs_ctx = bdrv_get_aio_context(bs);
48 + if (bs_ctx != qemu_get_aio_context()) {
49 + DPRINTF("savevm: async flushing drive %s\n", bs->filename);
50 + aio_co_reschedule_self(bs_ctx);
51 + bdrv_flush(bs);
52 + aio_co_reschedule_self(qemu_get_aio_context());
53 + }
54 + }
55 +
56 qemu_bh_schedule(snap_state.finalize_bh);
57 }
58