io_uring: io_free_req() via tw
authorPavel Begunkov <asml.silence@gmail.com>
Tue, 4 Apr 2023 12:39:48 +0000 (13:39 +0100)
committerJens Axboe <axboe@kernel.dk>
Tue, 4 Apr 2023 15:30:39 +0000 (09:30 -0600)
io_free_req() is not often used but nevertheless problematic as there is
no way to know the current context, it may be used from the submission
path or even by an irq handler. Push it to a fresh context using
task_work.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/3a92fe80bb068757e51aaa0b105cfbe8f5dfee9e.1680576071.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/io_uring.c

index 596af20cddb4b1261fbf17f5bf928a25c88b1db6..98320f4b0bca3e80c656a6b6cca769f3c570356e 100644 (file)
@@ -1116,7 +1116,7 @@ static inline void io_dismantle_req(struct io_kiocb *req)
                io_put_file(req->file);
 }
 
-__cold void io_free_req(struct io_kiocb *req)
+static __cold void io_free_req_tw(struct io_kiocb *req, struct io_tw_state *ts)
 {
        struct io_ring_ctx *ctx = req->ctx;
 
@@ -1130,6 +1130,12 @@ __cold void io_free_req(struct io_kiocb *req)
        spin_unlock(&ctx->completion_lock);
 }
 
+__cold void io_free_req(struct io_kiocb *req)
+{
+       req->io_task_work.func = io_free_req_tw;
+       io_req_task_work_add(req);
+}
+
 static void __io_req_find_next_prep(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;