qemu/util
Denis V. Lunev e554413bd2 coroutine: fix lost wakeup in qemu_co_sleep_wake()
cache_clean_timer_del_and_wait() cancels the cache-cleaner coroutine
by setting s->cache_clean_interval = 0 and calling qemu_co_sleep_wake()
to cut short its qemu_co_sleep_ns_wakeable(). qemu_co_sleep_wake() is
fire-and-forget: it reads w->to_wake and silently returns when it is
NULL. A sleeper that is between two iterations -- has just released
s->lock but has not yet set w->to_wake inside qemu_co_sleep() -- loses
the wake:

  iothread0 timer coroutine           main thread (qcow2 close)
  -------------------------           -------------------------
  while-body (holding s->lock):
    read interval = 600
    wait_ns = 600 * NS
    release s->lock
                                      take s->lock
                                      interval = 0
                                      qemu_co_sleep_wake(w):
                                        w->to_wake == NULL -> skip
                                        return
                                      qemu_co_queue_wait(exit, s->lock):
                                        release s->lock
                                        yield
  qemu_co_sleep_ns_wakeable:
    aio_timer_init(+600 s)
    qemu_co_sleep:
      cas scheduled NULL -> "qsns"
      w->to_wake = co
      yield  [sleeps 600 s]

cache_clean_timer_del_and_wait() then blocks on cache_clean_timer_exit
until the original 600 s expiry fires, and qcow2_close() holds BQL the
whole time so the VM stalls behind it.

block_copy_kick() has the same shape. Fix the primitive once instead
of working around it in each caller.

Use a tri-state for QemuCoSleep::to_wake:

  NULL     - idle
  co       - sleeper parked
  PENDING  - wake delivered, no sleeper yet (sticky)

qemu_co_sleep_wake() xchgs PENDING into to_wake: a real sleeper is
woken, NULL/PENDING is left untouched so the wake stays sticky.
qemu_co_sleep() cmpxchg-publishes itself as the sleeper; if a wake
was delivered before it got there or races the publish, the cmpxchg
observes PENDING and returns without yielding. On normal resume
qemu_co_sleep() clears the PENDING the waker left behind so the next
sleep starts clean.

A double-fire (real wake plus timer callback) is harmless: the first
xchg returns the coroutine and wakes it; the second returns PENDING
and is a no-op. Cancellation latency through qemu_co_sleep_wake() is
now bounded by aio_co_wake() rather than by the sleep duration.

Fixes: f86dde9a15 ("qcow2: Fix cache_clean_timer")
Signed-off-by: Denis V. Lunev <den@openvz.org>
Cc: Hanna Czenczek <hreitz@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20260610115850.2410566-2-den@openvz.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2026-08-03 10:42:29 +02:00
..
aio-posix.c qapi/iothread: introduce poll-weight parameter for aio-poll 2026-04-29 11:31:44 -04:00
aio-posix.h aio-poll: refine iothread polling using weighted handler intervals 2026-04-29 11:31:44 -04:00
aio-wait.c block: rename block/aio-wait.h to qemu/aio-wait.h 2025-12-27 10:11:12 +01:00
aio-win32.c qapi/iothread: introduce poll-weight parameter for aio-poll 2026-04-29 11:31:44 -04:00
aiocb.c block: extract include/qemu/aiocb.h out of include/block/aio.h 2025-12-27 10:11:12 +01:00
async.c qapi/iothread: introduce poll-weight parameter for aio-poll 2026-04-29 11:31:44 -04:00
base64.c nomaintainer: Fix Lesser GPL version number 2020-11-15 17:04:40 +01:00
bitmap.c bswap: Include missing 'qemu/bswap.h' header 2026-01-22 10:48:45 +01:00
bitops.c replace TABs with spaces 2023-03-20 12:43:50 +01:00
block-helpers.c block: Adjust check_block_size() signature 2024-10-18 15:03:35 +02:00
block-helpers.h block: Adjust check_block_size() signature 2024-10-18 15:03:35 +02:00
buffer.c nomaintainer: Fix Lesser GPL version number 2020-11-15 17:04:40 +01:00
bufferiszero.c util/bufferiszero: Split out host include files 2024-06-19 12:47:11 -07:00
cacheflush.c buildsys: Stop checking for ESA/390 host 2026-06-05 12:30:33 +02:00
chardev_open.c util/char_dev: Add open_cdev() 2023-12-19 19:03:38 +01:00
compatfd.c util: replace pipe()+cloexec with g_unix_open_pipe() 2022-05-03 15:18:14 +04:00
coroutine-sigaltstack.c osdep: set _FORTIFY_SOURCE=2 when optimization is enabled 2023-10-04 09:52:06 -04:00
coroutine-ucontext.c coroutine-ucontext: Save fake stack for pooled coroutine 2024-01-22 11:00:12 -05:00
coroutine-wasm.c util: Add coroutine backend for emscripten 2025-05-06 16:02:04 +02:00
coroutine-windows.c build: move coroutine backend selection to meson 2023-05-18 08:53:52 +02:00
cpuinfo-aarch64.c misc: Clean up includes 2026-01-22 11:23:31 +00:00
cpuinfo-i386.c cpuinfo/i386: Detect GFNI as an AVX extension 2025-09-04 09:49:23 +02:00
cpuinfo-loongarch.c util/loongarch64: Detect LASX vector support 2024-06-19 10:55:12 -07:00
cpuinfo-ppc.c util/cpuinfo: Make use of elf_aux_info(3) on OpenBSD 2024-07-30 07:59:23 +10:00
cpuinfo-riscv.c util/cpuinfo-riscv: Detect Zbs 2025-01-16 20:57:17 -08:00
crc-ccitt.c util: Add CRC16 (CCITT) calculation routines 2021-01-24 20:10:54 +01:00
crc32.c util: export CRC32[C] lookup tables 2026-04-29 11:41:00 +10:00
crc32c.c util: export CRC32[C] lookup tables 2026-04-29 11:41:00 +10:00
cutils.c util/cutils: drop qemu_strnlen() in favor of strnlen() 2026-06-18 14:27:21 +02:00
datadir.c util: move datadir.c from system/ 2026-04-22 12:51:51 +04:00
dbus.c util: add dbus helper unit 2020-01-06 18:41:32 +04:00
defer-call.c util/defer-call: move defer_call() to util/ 2023-10-31 15:41:42 +01:00
drm.c util/drm: make portable by avoiding struct dirent d_type 2020-07-13 14:36:10 +01:00
envlist.c util/envlist: fix prefix-match in envlist_unsetenv() name lookup 2026-06-03 12:45:06 -04:00
error-report.c util: use dynamic cast in error vreport 2026-07-07 11:16:24 +02:00
error.c error: Kill @error_warn 2025-10-01 08:33:24 +02:00
event.c qemu-thread: Use futex for QemuEvent on Windows 2025-06-06 14:32:55 +02:00
event_notifier-posix.c treewide: use qemu_set_blocking instead of g_unix_set_fd_nonblocking 2025-09-19 12:46:07 +01:00
event_notifier-win32.c Remove qemu-common.h include from most units 2022-04-06 14:31:55 +02:00
fdmon-epoll.c aio-posix: integrate fdmon into glib event loop 2025-11-11 22:04:53 +01:00
fdmon-io_uring.c fdmon-io_uring: check CQ ring directly in gsource_check 2026-02-23 08:50:04 -05:00
fdmon-poll.c aio-posix: integrate fdmon into glib event loop 2025-11-11 22:04:53 +01:00
fifo8.c util/fifo8: Make all read-only methods const-correct 2026-03-08 23:08:42 +01:00
filemonitor-inotify.c util/filemonitor-inotify: Use QEMU_LOCK_GUARD() 2026-07-07 17:10:24 +02:00
filemonitor-stub.c nomaintainer: Fix Lesser GPL version number 2020-11-15 17:04:40 +01:00
getauxval.c util/cpuinfo: Make use of elf_aux_info(3) on OpenBSD 2024-07-30 07:59:23 +10:00
guest-random.c util/guest-random: Clean up global variable shadowing 2023-10-06 13:27:48 +02:00
hbitmap.c bswap: Use 'qemu/bswap.h' instead of 'qemu/host-utils.h' 2026-01-22 10:48:45 +01:00
hexdump.c util/hexdump: fix QEMU_HEXDUMP_LINE_WIDTH logic 2025-11-03 11:59:32 +01:00
host-utils.c host-utils: Implemented signed 256-by-128 division 2022-06-20 08:38:58 -03:00
id.c net: Use id_generate() in the network subsystem, too 2021-03-09 21:47:45 +01:00
int128.c include/qemu/int128: Use Int128 structure for TCI 2023-02-04 06:19:42 -10:00
interval-tree.c util/interval-tree: Check root for null in interval_tree_iter_first 2023-08-09 09:26:32 -07:00
iov.c util/iov: Do not assert offset is in iov 2025-03-10 17:07:16 +08:00
iova-tree.c vhost-iova-tree, svq: Implement GPA->IOVA & partial IOVA->HVA trees 2025-02-21 07:18:42 -05:00
keyval.c qapi: Move include/qapi/qmp/ to include/qobject/ 2025-02-10 15:33:16 +01:00
lockcnt.c qemu-thread: Use futex if available for QemuLockCnt 2025-06-06 14:32:55 +02:00
log.c util/log: add missing error reporting in qemu_log_trylock_with_err 2026-03-05 17:40:24 +00:00
main-loop.c qom: replace 'can_be_deleted' with 'prepare_delete' 2026-07-07 11:16:22 +02:00
memalign.c osdep: Move memalign-related functions to their own header 2022-03-07 13:16:49 +00:00
memfd.c physmem: fd-based shared memory 2025-01-29 11:43:04 -03:00
meson.build common-user: Move selfmap from util 2026-07-10 14:39:58 -07:00
mmap-alloc.c util/mmap-alloc: qemu_fd_getfs() 2023-04-24 11:29:00 +02:00
module.c utils/module: fix memleak in module_load() 2026-07-07 17:10:24 +02:00
notify.c util: make notifer_remove() safer 2026-06-24 15:41:14 +04:00
nvdimm-utils.c Clean up includes 2020-12-10 17:16:44 +01:00
osdep.c treewide: replace qemu_hw_version() with QEMU_HW_VERSION 2026-03-25 18:22:27 +01:00
oslib-posix.c util/oslib-posix: increase memprealloc thread count to 32 2026-03-05 17:40:24 +00:00
oslib-win32.c util: Move qemu_ftruncate64 from block/file-win32.c to oslib-win32.c 2025-12-30 20:38:41 +01:00
path.c util: Remove unused sys/param.h 2026-04-23 12:27:27 +02:00
qdist.c util: spelling fixes 2023-08-31 19:47:43 +02:00
qemu-co-shared-resource.c util/co-shared-resource: Remove unused co_try_get_from_shres 2024-09-30 10:53:18 +03:00
qemu-co-timeout.c block: rename block/aio.h to qemu/aio.h 2025-12-27 10:11:12 +01:00
qemu-config.c qapi: Move include/qapi/qmp/ to include/qobject/ 2025-02-10 15:33:16 +01:00
qemu-coroutine-io.c aio: remove aio_disable_external() API 2023-05-30 17:37:26 +02:00
qemu-coroutine-lock.c qemu-coroutine-lock: fix has_waiters() 2026-03-09 09:03:42 +01:00
qemu-coroutine-sleep.c coroutine: fix lost wakeup in qemu_co_sleep_wake() 2026-08-03 10:42:29 +02:00
qemu-coroutine.c block: rename block/aio.h to qemu/aio.h 2025-12-27 10:11:12 +01:00
qemu-option.c char: error out if given unhandled size options 2026-05-09 10:24:30 +04:00
qemu-print.c qemu-print: Document qemu_fprintf(), qemu_vfprintf() failure 2026-05-05 12:52:26 +02:00
qemu-progress.c include: move progress API to qemu-progress.h 2022-04-06 14:31:43 +02:00
qemu-sockets.c util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive 2025-05-22 11:24:41 +01:00
qemu-thread-common.h bql: Fix bql_locked status with condvar APIs 2025-11-03 11:59:32 +01:00
qemu-thread-posix.c util: fix use of pthread_get_name_np on OpenBSD 2026-04-27 08:39:44 +02:00
qemu-thread-win32.c thread-win32: replace CRITICAL_SECTION with SRWLOCK 2026-04-23 12:27:27 +02:00
qemu-timer-common.c semihosting: Implement SYS_ELAPSED and SYS_TICKFREQ 2021-01-18 10:05:06 +00:00
qemu-timer.c target/s390x: Fix infinite loop during replay 2026-01-12 13:56:28 +01:00
qht.c cleanup: Drop pointless return at end of function 2025-04-24 09:33:42 +02:00
qsp.c include/qemu/atomic: Drop aligned_{u}int64_t 2026-01-17 10:46:51 +11:00
qtree.c tcg: use QTree instead of GTree 2023-03-28 15:23:10 -07:00
range.c util/range.c: spelling fix: inbetween 2023-11-15 12:06:05 +03:00
rcu.c Reapply "rcu: Unify force quiescent state" 2026-02-27 14:48:04 +01:00
readline.c util/readline: Fix out-of-bounds access in readline_insert_char(). 2026-04-08 13:33:25 +01:00
reserved-region.c util/reserved-region: Add new ReservedRegion helpers 2023-11-03 09:20:31 +01:00
s390x_pci_mmio.c util: Add functions for s390x mmio read/write 2025-05-08 10:03:07 -04:00
sys_membarrier.c
systemd.c systemd: Also clear LISTEN_FDNAMES during systemd socket activation 2023-05-03 14:00:08 -05:00
thread-context.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
thread-pool.c thread-pool: Allow at least 1 thread in thread_pool_adjust_max_threads_to_work() 2026-06-22 17:08:48 -04:00
throttle.c block: rename block/aio.h to qemu/aio.h 2025-12-27 10:11:12 +01:00
timed-average.c license: Simplify GPL-2.0-or-later license descriptions 2024-09-20 10:11:59 +03:00
trace-events util: move datadir.c from system/ 2026-04-22 12:51:51 +04:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
transactions.c transactions: Invoke clean() after everything else 2021-11-16 09:43:44 +01:00
unicode.c
userfaultfd.c util/userfaultfd: Remove unused uffd_poll_events 2024-10-08 15:28:55 -04:00
uuid.c util/uuid: Add UUID_STR_LEN definition 2023-11-03 09:20:31 +01:00
vfio-helpers.c util/vfio-helper: Fix endianness in PCI config read/write functions 2026-01-13 08:29:59 +01:00
vhost-user-server.c block: rename block/aio-wait.h to qemu/aio-wait.h 2025-12-27 10:11:12 +01:00
yank.c qapi: Fix dangling references to docs/devel/qapi-code-gen.txt 2024-01-26 07:04:53 +01:00