]>
Commit | Line | Data |
---|---|---|
84403c2d DM |
1 | From c8856d5cbcf3d427cd02c9556f845486ab5362bc Mon Sep 17 00:00:00 2001 |
2 | From: Dietmar Maurer <dietmar@proxmox.com> | |
3 | Date: Fri, 14 Feb 2020 12:37:27 +0100 | |
4 | Subject: [PATCH qemu 3/7] PVE backup: move backup_state.cancel to | |
5 | backup_state.stat.cancel | |
6 | ||
7 | In order to avoid lock contention with qmp_backup_cancel. | |
8 | --- | |
9 | blockdev.c | 25 +++++++++++++++---------- | |
10 | 1 file changed, 15 insertions(+), 10 deletions(-) | |
11 | ||
12 | diff --git a/blockdev.c b/blockdev.c | |
13 | index 2f84f8832d..a4b5b98224 100644 | |
14 | --- a/blockdev.c | |
15 | +++ b/blockdev.c | |
16 | @@ -3204,9 +3204,9 @@ static void block_on_coroutine_fn(CoroutineEntry *entry, void *entry_arg) | |
17 | AIO_WAIT_WHILE(ctx, !wrapper.finished); | |
18 | } | |
19 | ||
20 | - | |
21 | static struct PVEBackupState { | |
22 | struct { | |
23 | + // Everithing accessed from qmp command, protected using rwlock | |
24 | CoRwlock rwlock; | |
25 | Error *error; | |
26 | time_t start_time; | |
27 | @@ -3217,8 +3217,8 @@ static struct PVEBackupState { | |
28 | size_t total; | |
29 | size_t transferred; | |
30 | size_t zero_bytes; | |
31 | + bool cancel; | |
32 | } stat; | |
33 | - bool cancel; | |
34 | int64_t speed; | |
35 | VmaWriter *vmaw; | |
36 | GList *di_list; | |
37 | @@ -3247,13 +3247,16 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target, | |
38 | const unsigned char *buf = pbuf; | |
39 | PVEBackupDevInfo *di = opaque; | |
40 | ||
41 | - qemu_co_mutex_lock(&backup_state.backup_mutex); | |
42 | + qemu_co_rwlock_rdlock(&backup_state.stat.rwlock); | |
43 | + bool cancel = backup_state.stat.cancel; | |
44 | + qemu_co_rwlock_unlock(&backup_state.stat.rwlock); | |
45 | ||
46 | - if (backup_state.cancel) { | |
47 | - qemu_co_mutex_unlock(&backup_state.backup_mutex); | |
48 | + if (cancel) { | |
49 | return size; // return success | |
50 | } | |
51 | ||
52 | + qemu_co_mutex_lock(&backup_state.backup_mutex); | |
53 | + | |
54 | uint64_t cluster_num = start / VMA_CLUSTER_SIZE; | |
55 | if ((cluster_num * VMA_CLUSTER_SIZE) != start) { | |
56 | qemu_co_rwlock_rdlock(&backup_state.stat.rwlock); | |
57 | @@ -3419,9 +3422,11 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque) | |
58 | { | |
59 | assert(qemu_in_coroutine()); | |
60 | ||
61 | - qemu_co_mutex_lock(&backup_state.backup_mutex); | |
62 | + qemu_co_rwlock_wrlock(&backup_state.stat.rwlock); | |
63 | + backup_state.stat.cancel = true; | |
64 | + qemu_co_rwlock_unlock(&backup_state.stat.rwlock); | |
65 | ||
66 | - backup_state.cancel = true; | |
67 | + qemu_co_mutex_lock(&backup_state.backup_mutex); | |
68 | ||
69 | // Avoid race between block jobs and backup-cancel command: | |
70 | if (!backup_state.vmaw) { | |
71 | @@ -3542,7 +3547,7 @@ static void coroutine_fn pvebackup_co_run_next_job(void) | |
72 | ||
73 | if (job_should_pause(&job->job)) { | |
74 | qemu_co_rwlock_rdlock(&backup_state.stat.rwlock); | |
75 | - bool error_or_canceled = backup_state.stat.error || backup_state.cancel; | |
76 | + bool error_or_canceled = backup_state.stat.error || backup_state.stat.cancel; | |
77 | qemu_co_rwlock_unlock(&backup_state.stat.rwlock); | |
78 | ||
79 | if (error_or_canceled) { | |
80 | @@ -3761,10 +3766,10 @@ static void coroutine_fn pvebackup_co_start(void *opaque) | |
81 | } | |
82 | /* initialize global backup_state now */ | |
83 | ||
84 | - backup_state.cancel = false; | |
85 | - | |
86 | qemu_co_rwlock_wrlock(&backup_state.stat.rwlock); | |
87 | ||
88 | + backup_state.stat.cancel = false; | |
89 | + | |
90 | if (backup_state.stat.error) { | |
91 | error_free(backup_state.stat.error); | |
92 | backup_state.stat.error = NULL; | |
93 | -- | |
94 | 2.20.1 | |
95 |