aio_wait_kick: add missing memory barrier

It seems that aio_wait_kick always required a memory barrier
or atomic operation in the caller, but nobody actually
took care of doing it.

Let's put the barrier in the function instead, and pair it
with another one in AIO_WAIT_WHILE. Read aio_wait_kick()
comment for further explanation.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Message-Id: <20220524173054.12651-1-eesposit@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Emanuele Giuseppe Esposito 2022-05-24 13:30:54 -04:00 committed by Kevin Wolf
parent 9b38fc56c0
commit 7455ff1aa0
2 changed files with 17 additions and 1 deletions

View File

@ -81,6 +81,8 @@ extern AioWait global_aio_wait;
AioContext *ctx_ = (ctx); \ AioContext *ctx_ = (ctx); \
/* Increment wait_->num_waiters before evaluating cond. */ \ /* Increment wait_->num_waiters before evaluating cond. */ \
qatomic_inc(&wait_->num_waiters); \ qatomic_inc(&wait_->num_waiters); \
/* Paired with smp_mb in aio_wait_kick(). */ \
smp_mb(); \
if (ctx_ && in_aio_context_home_thread(ctx_)) { \ if (ctx_ && in_aio_context_home_thread(ctx_)) { \
while ((cond)) { \ while ((cond)) { \
aio_poll(ctx_, true); \ aio_poll(ctx_, true); \

View File

@ -35,7 +35,21 @@ static void dummy_bh_cb(void *opaque)
void aio_wait_kick(void) void aio_wait_kick(void)
{ {
/* The barrier (or an atomic op) is in the caller. */ /*
* Paired with smp_mb in AIO_WAIT_WHILE. Here we have:
* write(condition);
* aio_wait_kick() {
* smp_mb();
* read(num_waiters);
* }
*
* And in AIO_WAIT_WHILE:
* write(num_waiters);
* smp_mb();
* read(condition);
*/
smp_mb();
if (qatomic_read(&global_aio_wait.num_waiters)) { if (qatomic_read(&global_aio_wait.num_waiters)) {
aio_bh_schedule_oneshot(qemu_get_aio_context(), dummy_bh_cb, NULL); aio_bh_schedule_oneshot(qemu_get_aio_context(), dummy_bh_cb, NULL);
} }