[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in Blo
From: |
Emanuele Giuseppe Esposito |
Subject: |
[PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState |
Date: |
Mon, 14 Jun 2021 09:33:50 +0200 |
By adding acquire/release pairs, we ensure that .ret and .error_is_read
fields are written by block_copy_dirty_clusters before .finished is true.
The atomic here are necessary because the fields are concurrently modified
also outside coroutines.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block/block-copy.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/block/block-copy.c b/block/block-copy.c
index 6416929abd..5348e1f61b 100644
--- a/block/block-copy.c
+++ b/block/block-copy.c
@@ -53,14 +53,14 @@ typedef struct BlockCopyCallState {
Coroutine *co;
/* State */
- bool finished;
+ bool finished; /* atomic */
QemuCoSleep sleep; /* TODO: protect API with a lock */
/* To reference all call states from BlockCopyState */
QLIST_ENTRY(BlockCopyCallState) list;
/* OUT parameters */
- bool cancelled;
+ bool cancelled; /* atomic */
/* Fields protected by lock in BlockCopyState */
bool error_is_read;
int ret;
@@ -650,7 +650,8 @@ block_copy_dirty_clusters(BlockCopyCallState *call_state)
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
assert(QEMU_IS_ALIGNED(bytes, s->cluster_size));
- while (bytes && aio_task_pool_status(aio) == 0 && !call_state->cancelled) {
+ while (bytes && aio_task_pool_status(aio) == 0 &&
+ !qatomic_read(&call_state->cancelled)) {
BlockCopyTask *task;
int64_t status_bytes;
@@ -761,7 +762,7 @@ static int coroutine_fn
block_copy_common(BlockCopyCallState *call_state)
do {
ret = block_copy_dirty_clusters(call_state);
- if (ret == 0 && !call_state->cancelled) {
+ if (ret == 0 && !qatomic_read(&call_state->cancelled)) {
WITH_QEMU_LOCK_GUARD(&s->lock) {
/*
* Check that there is no task we still need to
@@ -792,9 +793,9 @@ static int coroutine_fn
block_copy_common(BlockCopyCallState *call_state)
* 2. We have waited for some intersecting block-copy request
* It may have failed and produced new dirty bits.
*/
- } while (ret > 0 && !call_state->cancelled);
+ } while (ret > 0 && !qatomic_read(&call_state->cancelled));
- call_state->finished = true;
+ qatomic_store_release(&call_state->finished, true);
if (call_state->cb) {
call_state->cb(call_state->cb_opaque);
@@ -857,35 +858,37 @@ void block_copy_call_free(BlockCopyCallState *call_state)
return;
}
- assert(call_state->finished);
+ assert(qatomic_load_acquire(&call_state->finished));
g_free(call_state);
}
bool block_copy_call_finished(BlockCopyCallState *call_state)
{
- return call_state->finished;
+ return qatomic_load_acquire(&call_state->finished);
}
bool block_copy_call_succeeded(BlockCopyCallState *call_state)
{
- return call_state->finished && !call_state->cancelled &&
- call_state->ret == 0;
+ return qatomic_load_acquire(&call_state->finished) &&
+ !qatomic_read(&call_state->cancelled) &&
+ call_state->ret == 0;
}
bool block_copy_call_failed(BlockCopyCallState *call_state)
{
- return call_state->finished && !call_state->cancelled &&
- call_state->ret < 0;
+ return qatomic_load_acquire(&call_state->finished) &&
+ !qatomic_read(&call_state->cancelled) &&
+ call_state->ret < 0;
}
bool block_copy_call_cancelled(BlockCopyCallState *call_state)
{
- return call_state->cancelled;
+ return qatomic_read(&call_state->cancelled);
}
int block_copy_call_status(BlockCopyCallState *call_state, bool *error_is_read)
{
- assert(call_state->finished);
+ assert(qatomic_load_acquire(&call_state->finished));
if (error_is_read) {
*error_is_read = call_state->error_is_read;
}
@@ -894,7 +897,7 @@ int block_copy_call_status(BlockCopyCallState *call_state,
bool *error_is_read)
void block_copy_call_cancel(BlockCopyCallState *call_state)
{
- call_state->cancelled = true;
+ qatomic_set(&call_state->cancelled, true);
block_copy_kick(call_state);
}
--
2.31.1
- Re: [PATCH v4 3/6] block-copy: improve comments of BlockCopyTask and BlockCopyState types and functions, (continued)
Re: [PATCH v4 3/6] block-copy: improve comments of BlockCopyTask and BlockCopyState types and functions, Vladimir Sementsov-Ogievskiy, 2021/06/19
Re: [PATCH v4 3/6] block-copy: improve comments of BlockCopyTask and BlockCopyState types and functions, Vladimir Sementsov-Ogievskiy, 2021/06/19
[PATCH v4 4/6] block-copy: move progress_set_remaining in block_copy_task_end, Emanuele Giuseppe Esposito, 2021/06/14
[PATCH v4 5/6] block-copy: add a CoMutex, Emanuele Giuseppe Esposito, 2021/06/14
[PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState,
Emanuele Giuseppe Esposito <=
- Re: [PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState, Vladimir Sementsov-Ogievskiy, 2021/06/19
- Re: [PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState, Paolo Bonzini, 2021/06/22
- Re: [PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState, Vladimir Sementsov-Ogievskiy, 2021/06/22
- Re: [PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState, Paolo Bonzini, 2021/06/22
- Re: [PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState, Vladimir Sementsov-Ogievskiy, 2021/06/22
- Re: [PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState, Emanuele Giuseppe Esposito, 2021/06/22
- Re: [PATCH v4 6/6] block-copy: atomic .cancelled and .finished fields in BlockCopyCallState, Paolo Bonzini, 2021/06/23