io_uring: combine lock/unlock sections on exit
authorPavel Begunkov <asml.silence@gmail.com>
Thu, 1 Apr 2021 14:43:50 +0000 (15:43 +0100)
committerJens Axboe <axboe@kernel.dk>
Mon, 12 Apr 2021 01:30:34 +0000 (19:30 -0600)
io_ring_exit_work() already does uring_lock lock/unlock, no need to
repeat it for lock waiting trick in io_ring_ctx_free(). Move the waiting
with comments and spinlocking into io_ring_exit_work.

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

index 373fe2b9e1f28847e62fa7e96575790418e88db1..edb5b9d0fd1a8d746deb4aa0462757933d871ad7 100644 (file)
@@ -8478,16 +8478,6 @@ static void io_req_caches_free(struct io_ring_ctx *ctx)
 
 static void io_ring_ctx_free(struct io_ring_ctx *ctx)
 {
-       /*
-        * Some may use context even when all refs and requests have been put,
-        * and they are free to do so while still holding uring_lock or
-        * completion_lock, see __io_req_task_submit(). Wait for them to finish.
-        */
-       mutex_lock(&ctx->uring_lock);
-       mutex_unlock(&ctx->uring_lock);
-       spin_lock_irq(&ctx->completion_lock);
-       spin_unlock_irq(&ctx->completion_lock);
-
        io_sq_thread_finish(ctx);
        io_sqe_buffers_unregister(ctx);
 
@@ -8638,6 +8628,12 @@ static void io_ring_exit_work(struct work_struct *work)
                WARN_ON_ONCE(time_after(jiffies, timeout));
        } while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20));
 
+       /*
+        * Some may use context even when all refs and requests have been put,
+        * and they are free to do so while still holding uring_lock or
+        * completion_lock, see __io_req_task_submit(). Apart from other work,
+        * this lock/unlock section also waits them to finish.
+        */
        mutex_lock(&ctx->uring_lock);
        while (!list_empty(&ctx->tctx_list)) {
                WARN_ON_ONCE(time_after(jiffies, timeout));
@@ -8658,6 +8654,8 @@ static void io_ring_exit_work(struct work_struct *work)
                mutex_lock(&ctx->uring_lock);
        }
        mutex_unlock(&ctx->uring_lock);
+       spin_lock_irq(&ctx->completion_lock);
+       spin_unlock_irq(&ctx->completion_lock);
 
        io_ring_ctx_free(ctx);
 }