@samitouri / QOSamiQemu / commits / 1d6610099b

block/nfs: Do not enter coroutine from CB

The reasoning I gave for why it would be safe to call aio_co_wake() despite holding the mutex was wrong: It is true that the current request will not re-acquire the mutex, but a subsequent request in the same coroutine can. Because the mutex is a non-coroutine mutex, this will result in a deadlock. Therefore, we must either not enter the coroutine here (only scheduling it), or release the mutex around aio_co_wake(). I opt for the former, as it is the behavior prior to the offending commit, and so seems safe to do. Fixes: deb35c129b859b9bec70fd42f856a0b7c1dc6e61 ("nfs: Run co BH CB in the coroutine’s AioContext") Buglink: https://gitlab.com/qemu-project/qemu/-/issues/2622#note_2965097035 Cc: qemu-stable@nongnu.org Signed-off-by: Hanna Czenczek <hreitz@redhat.com> Message-ID: <20260102153246.154207-1-hreitz@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Hanna Czenczek committed Jan 2, 2026 at 16:32 UTC 1d6610099bd7fc159626a38e60a3c84343ff67f7
1 file changed +10 -9
block/nfs.c
+10 -9
@@ -249,14 +249,15 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
249 }
250
251 /*
252 - * Safe to call: nfs_service(), which called us, is only run from the FD
253 - * handlers, never from the request coroutine. The request coroutine in
254 - * turn will yield unconditionally.
255 - * No need to release the lock, even if we directly enter the coroutine, as
256 - * the lock is never re-taken after yielding. (Note: If we do enter the
257 - * coroutine, @task will probably be dangling once aio_co_wake() returns.)
252 + * Using aio_co_wake() here could re-enter the coroutine directly, while we
253 + * still hold the mutex. The current request will not attempt to re-take
254 + * the mutex, so that is fine; but if the same coroutine then goes on to
255 + * submit another request, that new request will try to re-take the mutex,
256 + * resulting in a deadlock.
257 + * To prevent that, only schedule the coroutine so it will be entered later,
258 + * with the mutex released.
259 */
259 - aio_co_wake(task->co);
260 + aio_co_schedule(qemu_coroutine_get_aio_context(task->co), task->co);
261 }
262
263 static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, int64_t offset,
@@ -716,8 +717,8 @@ nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
717 if (task->ret < 0) {
718 error_report("NFS Error: %s", nfs_get_error(nfs));
719 }
719 - /* Safe to call, see nfs_co_generic_cb() */
720 - aio_co_wake(task->co);
720 + /* Must not use aio_co_wake(), see nfs_co_generic_cb() */
721 + aio_co_schedule(qemu_coroutine_get_aio_context(task->co), task->co);
722 }
723
724 static int64_t coroutine_fn nfs_co_get_allocated_file_size(BlockDriverState *bs)