io_uring: index io_uring->xa by ctx not file

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>
This commit is contained in:
Pavel Begunkov 2021-03-06 11:02:15 +00:00 committed by Jens Axboe
parent eebd2e37e6
commit baf186c4d3
2 changed files with 12 additions and 14 deletions

View 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;

View 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;