diff options
| author | Jens Axboe <axboe@kernel.dk> | 2025-04-24 10:28:14 -0600 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-05-02 08:01:49 +0200 |
| commit | 46b21322b92351da47326c56b2678470ed01c8f3 (patch) | |
| tree | a201a1ebb6c10bc253f12b6001e3f195b1ad1e02 /io_uring | |
| parent | a42d48ee795838c7e18723a1158878dd60967498 (diff) | |
| download | linux-46b21322b92351da47326c56b2678470ed01c8f3.tar.gz linux-46b21322b92351da47326c56b2678470ed01c8f3.tar.bz2 linux-46b21322b92351da47326c56b2678470ed01c8f3.zip | |
io_uring: fix 'sync' handling of io_fallback_tw()
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>
Diffstat (limited to 'io_uring')
| -rw-r--r-- | io_uring/io_uring.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 7370f763346f..d9c02e6b7b92 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1080,21 +1080,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); } } |
