]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
io_uring: fix 'sync' handling of io_fallback_tw()
authorJens Axboe <axboe@kernel.dk>
Thu, 24 Apr 2025 16:28:14 +0000 (10:28 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2025 05:50:47 +0000 (07:50 +0200)
commit edd43f4d6f50ec3de55a0c9e9df6348d1da51965 upstream.

A previous commit added a 'sync' parameter to io_fallback_tw(), which if
true, means the caller wants to wait on the fallback thread handling it.
But the logic is somewhat messed up, ensure that ctxs are swapped and
flushed appropriately.

Cc: stable@vger.kernel.org
Fixes: dfbe5561ae93 ("io_uring: flush offloaded and delayed task_work on exit")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
io_uring/io_uring.c

index efa7849b82c184ebb9ab44bcdc3b00c15aa965e7..9883fd16cde4437122577175fc305ec9e4fd549e 100644 (file)
@@ -1247,21 +1247,22 @@ static __cold void io_fallback_tw(struct io_uring_task *tctx, bool sync)
        while (node) {
                req = container_of(node, struct io_kiocb, io_task_work.node);
                node = node->next;
-               if (sync && last_ctx != req->ctx) {
+               if (last_ctx != req->ctx) {
                        if (last_ctx) {
-                               flush_delayed_work(&last_ctx->fallback_work);
+                               if (sync)
+                                       flush_delayed_work(&last_ctx->fallback_work);
                                percpu_ref_put(&last_ctx->refs);
                        }
                        last_ctx = req->ctx;
                        percpu_ref_get(&last_ctx->refs);
                }
-               if (llist_add(&req->io_task_work.node,
-                             &req->ctx->fallback_llist))
-                       schedule_delayed_work(&req->ctx->fallback_work, 1);
+               if (llist_add(&req->io_task_work.node, &last_ctx->fallback_llist))
+                       schedule_delayed_work(&last_ctx->fallback_work, 1);
        }
 
        if (last_ctx) {
-               flush_delayed_work(&last_ctx->fallback_work);
+               if (sync)
+                       flush_delayed_work(&last_ctx->fallback_work);
                percpu_ref_put(&last_ctx->refs);
        }
 }