qemu/aio-posix-fix-race-between-epoll-upgrade-and-aio_set.patch
Fei Xu 2ddec1532b QEMU update to version 6.2.0-72(master)
- migration/xbzrle: fix out-of-bounds write with axv512
- migration/xbzrle: use ctz64 to avoid undefined result
- Update bench-code for addressing CI problem
- AVX512 support for xbzrle_encode_buffer
- configure, meson: move AVX tests to meson
- target/i386: KVM: allow fast string operations if host supports them
- target/i386: add FSRM to TCG
- hw/nvme: fix memory leak in nvme_dsm
- aio-posix: fix race between epoll upgrade and aio_set_fd_handler()
- target/i386: Add SGX aex-notify and EDECCSSA support
- hw/usb/imx: Fix out of bounds access in imx_usbphy_read()
- target/i386: Set maximum APIC ID to KVM prior to vCPU creation
- target/i386: Fix sanity check on max APIC ID / X2APIC enablement

Signed-off-by: Fei Xu <xufei30@huawei.com>
2023-05-18 14:19:42 +08:00

83 lines
2.7 KiB
Diff

From 4ab8e11adf5878d1f298a682b37d7de4632a3a8b Mon Sep 17 00:00:00 2001
From: wangmeiyang <wangmeiyang@xfusion.com>
Date: Fri, 28 Apr 2023 15:22:07 +0800
Subject: [PATCH] aio-posix: fix race between epoll upgrade and
aio_set_fd_handler()
If another thread calls aio_set_fd_handler() while the IOThread event
loop is upgrading from ppoll(2) to epoll(7) then we might miss new
AioHandlers. The epollfd will not monitor the new AioHandler's fd,
resulting in hangs.
Take the AioHandler list lock while upgrading to epoll. This prevents
AioHandlers from changing while epoll is being set up. If we cannot lock
because we're in a nested event loop, then don't upgrade to epoll (it
will happen next time we're not in a nested call).
The downside to taking the lock is that the aio_set_fd_handler() thread
has to wait until the epoll upgrade is finished, which involves many
epoll_ctl(2) system calls. However, this scenario is rare and I couldn't
think of another solution that is still simple.
origin commit: https://gitlab.com/qemu-project/qemu/-/commit/e62da98527fa35fe5f532cded01a33edf9fbe7b2
Signed-off-by: Meiyang Wang <wangmeiyang@xfusion.com>
Reported-by: Qing Wang <qinwang@redhat.com>
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2090998
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Fam Zheng <fam@euphon.net>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20230323144859.1338495-1-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
util/fdmon-epoll.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/util/fdmon-epoll.c b/util/fdmon-epoll.c
index e11a8a022e..1683aa1105 100644
--- a/util/fdmon-epoll.c
+++ b/util/fdmon-epoll.c
@@ -127,6 +127,8 @@ static bool fdmon_epoll_try_enable(AioContext *ctx)
bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
{
+ bool ok;
+
if (ctx->epollfd < 0) {
return false;
}
@@ -136,14 +138,23 @@ bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
return false;
}
- if (npfd >= EPOLL_ENABLE_THRESHOLD) {
- if (fdmon_epoll_try_enable(ctx)) {
- return true;
- } else {
- fdmon_epoll_disable(ctx);
- }
+ if (npfd < EPOLL_ENABLE_THRESHOLD) {
+ return false;
+ }
+
+ /* The list must not change while we add fds to epoll */
+ if (!qemu_lockcnt_dec_if_lock(&ctx->list_lock)) {
+ return false;
+ }
+
+ ok = fdmon_epoll_try_enable(ctx);
+
+ qemu_lockcnt_inc_and_unlock(&ctx->list_lock);
+
+ if (!ok) {
+ fdmon_epoll_disable(ctx);
}
- return false;
+ return ok;
}
void fdmon_epoll_setup(AioContext *ctx)
--
2.27.0