]>
Commit | Line | Data |
---|---|---|
f063a8aa TL |
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 |