mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
async: access bottom half flags with qatomic_read
Running test-aio-multithread under TSAN reveals data races on bh->flags.
Because bottom halves may be scheduled or canceled asynchronously,
without taking a lock, adjust aio_compute_bh_timeout() and aio_ctx_check()
to use a relaxed read to access the flags.
Use an acquire load to ensure that anything that was written prior to
qemu_bh_schedule() is visible.
Closes: https://gitlab.com/qemu-project/qemu/-/issues/2749
Closes: https://gitlab.com/qemu-project/qemu/-/issues/851
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5142397c79)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
committed by
Michael Tokarev
parent
f316e90a82
commit
4e58c5bf0c
11
util/async.c
11
util/async.c
@@ -256,8 +256,9 @@ static int64_t aio_compute_bh_timeout(BHList *head, int timeout)
|
||||
QEMUBH *bh;
|
||||
|
||||
QSLIST_FOREACH_RCU(bh, head, next) {
|
||||
if ((bh->flags & (BH_SCHEDULED | BH_DELETED)) == BH_SCHEDULED) {
|
||||
if (bh->flags & BH_IDLE) {
|
||||
int flags = qatomic_load_acquire(&bh->flags);
|
||||
if ((flags & (BH_SCHEDULED | BH_DELETED)) == BH_SCHEDULED) {
|
||||
if (flags & BH_IDLE) {
|
||||
/* idle bottom halves will be polled at least
|
||||
* every 10ms */
|
||||
timeout = 10000000;
|
||||
@@ -335,14 +336,16 @@ aio_ctx_check(GSource *source)
|
||||
aio_notify_accept(ctx);
|
||||
|
||||
QSLIST_FOREACH_RCU(bh, &ctx->bh_list, next) {
|
||||
if ((bh->flags & (BH_SCHEDULED | BH_DELETED)) == BH_SCHEDULED) {
|
||||
int flags = qatomic_load_acquire(&bh->flags);
|
||||
if ((flags & (BH_SCHEDULED | BH_DELETED)) == BH_SCHEDULED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QSIMPLEQ_FOREACH(s, &ctx->bh_slice_list, next) {
|
||||
QSLIST_FOREACH_RCU(bh, &s->bh_list, next) {
|
||||
if ((bh->flags & (BH_SCHEDULED | BH_DELETED)) == BH_SCHEDULED) {
|
||||
int flags = qatomic_load_acquire(&bh->flags);
|
||||
if ((flags & (BH_SCHEDULED | BH_DELETED)) == BH_SCHEDULED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user