Commit baf186c4 authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Jens Axboe
Browse files

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: default avatarPavel Begunkov <asml.silence@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent eebd2e37
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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;