]> git.ipfire.org Git - thirdparty/kernel/linux.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)
committerJens Axboe <axboe@kernel.dk>
Thu, 24 Apr 2025 16:32:43 +0000 (10:32 -0600)
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>
io_uring/io_uring.c

index eedb47c8c79e0a963023f5135668f874285838c5..a2b256e96d5da388495a20cee9539d82ca1378ef 100644 (file)
@@ -1083,21 +1083,22 @@ static __cold void __io_fallback_tw(struct llist_node *node, 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);
        }
 }