io_uring: index io_uring->xa by ctx not file
authorPavel Begunkov <asml.silence@gmail.com>
Sat, 6 Mar 2021 11:02:15 +0000 (11:02 +0000)
committerJens Axboe <axboe@kernel.dk>
Sun, 7 Mar 2021 21:12:43 +0000 (14:12 -0700)
We don't use task file notes anymore, and no need left in indexing
task->io_uring->xa by file, and replace it with ctx. It's better
design-wise, especially since we keep a dangling file, and so have to
keep an eye on not dereferencing it.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c
include/linux/io_uring.h

index f448213..01a7fa4 100644 (file)
@@ -809,7 +809,6 @@ struct io_kiocb {
 struct io_tctx_node {
        struct list_head        ctx_node;
        struct task_struct      *task;
-       struct file             *file;
        struct io_ring_ctx      *ctx;
 };
 
@@ -8540,7 +8539,7 @@ static bool io_run_ctx_fallback(struct io_ring_ctx *ctx)
 struct io_tctx_exit {
        struct callback_head            task_work;
        struct completion               completion;
-       unsigned long                   index;
+       struct io_ring_ctx              *ctx;
 };
 
 static void io_tctx_exit_cb(struct callback_head *cb)
@@ -8554,7 +8553,7 @@ static void io_tctx_exit_cb(struct callback_head *cb)
         * node. It'll be removed by the end of cancellation, just ignore it.
         */
        if (!atomic_read(&tctx->in_idle))
-               io_uring_del_task_file(work->index);
+               io_uring_del_task_file((unsigned long)work->ctx);
        complete(&work->completion);
 }
 
@@ -8579,7 +8578,7 @@ static void io_ring_exit_work(struct work_struct *work)
        while (!list_empty(&ctx->tctx_list)) {
                node = list_first_entry(&ctx->tctx_list, struct io_tctx_node,
                                        ctx_node);
-               exit.index = (unsigned long)node->file;
+               exit.ctx = ctx;
                init_completion(&exit.completion);
                init_task_work(&exit.task_work, io_tctx_exit_cb);
                ret = task_work_add(node->task, &exit.task_work, TWA_SIGNAL);
@@ -8798,7 +8797,7 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx,
 /*
  * Note that this task has used io_uring. We use it for cancelation purposes.
  */
-static int io_uring_add_task_file(struct io_ring_ctx *ctx, struct file *file)
+static int io_uring_add_task_file(struct io_ring_ctx *ctx)
 {
        struct io_uring_task *tctx = current->io_uring;
        struct io_tctx_node *node;
@@ -8810,18 +8809,17 @@ static int io_uring_add_task_file(struct io_ring_ctx *ctx, struct file *file)
                        return ret;
                tctx = current->io_uring;
        }
-       if (tctx->last != file) {
-               void *old = xa_load(&tctx->xa, (unsigned long)file);
+       if (tctx->last != ctx) {
+               void *old = xa_load(&tctx->xa, (unsigned long)ctx);
 
                if (!old) {
                        node = kmalloc(sizeof(*node), GFP_KERNEL);
                        if (!node)
                                return -ENOMEM;
                        node->ctx = ctx;
-                       node->file = file;
                        node->task = current;
 
-                       ret = xa_err(xa_store(&tctx->xa, (unsigned long)file,
+                       ret = xa_err(xa_store(&tctx->xa, (unsigned long)ctx,
                                                node, GFP_KERNEL));
                        if (ret) {
                                kfree(node);
@@ -8832,7 +8830,7 @@ static int io_uring_add_task_file(struct io_ring_ctx *ctx, struct file *file)
                        list_add(&node->ctx_node, &ctx->tctx_list);
                        mutex_unlock(&ctx->uring_lock);
                }
-               tctx->last = file;
+               tctx->last = ctx;
        }
 
        /*
@@ -8867,7 +8865,7 @@ static void io_uring_del_task_file(unsigned long index)
        list_del(&node->ctx_node);
        mutex_unlock(&node->ctx->uring_lock);
 
-       if (tctx->last == node->file)
+       if (tctx->last == node->ctx)
                tctx->last = NULL;
        kfree(node);
 }
@@ -9166,7 +9164,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
                }
                submitted = to_submit;
        } else if (to_submit) {
-               ret = io_uring_add_task_file(ctx, f.file);
+               ret = io_uring_add_task_file(ctx);
                if (unlikely(ret))
                        goto out;
                mutex_lock(&ctx->uring_lock);
@@ -9375,7 +9373,7 @@ static int io_uring_install_fd(struct io_ring_ctx *ctx, struct file *file)
        if (fd < 0)
                return fd;
 
-       ret = io_uring_add_task_file(ctx, file);
+       ret = io_uring_add_task_file(ctx);
        if (ret) {
                put_unused_fd(fd);
                return ret;
index 7cb7bd0..9761a0e 100644 (file)
@@ -18,7 +18,7 @@ struct io_uring_task {
        /* submission side */
        struct xarray           xa;
        struct wait_queue_head  wait;
-       struct file             *last;
+       void                    *last;
        void                    *io_wq;
        struct percpu_counter   inflight;
        atomic_t                in_idle;