Skip to content

Commit d56d938

Browse files
isilenceaxboe
authored andcommitted
io_uring: do ctx initiated file note removal
Another preparation patch. When full quiesce is done on ctx exit, use task_work infra to remove corresponding to the ctx io_uring->xa entries. For that we use the back tctx map. Also use ->in_idle to prevent removing it while we traversing ->xa on cancellation, just ignore it. Signed-off-by: Pavel Begunkov <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 13bf43f commit d56d938

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

fs/io_uring.c

+46-2
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,7 @@ static const struct io_op_def io_op_defs[] = {
987987
[IORING_OP_UNLINKAT] = {},
988988
};
989989

990+
static void io_uring_del_task_file(unsigned long index);
990991
static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx,
991992
struct task_struct *task,
992993
struct files_struct *files);
@@ -8536,10 +8537,33 @@ static bool io_run_ctx_fallback(struct io_ring_ctx *ctx)
85368537
return executed;
85378538
}
85388539

8540+
struct io_tctx_exit {
8541+
struct callback_head task_work;
8542+
struct completion completion;
8543+
unsigned long index;
8544+
};
8545+
8546+
static void io_tctx_exit_cb(struct callback_head *cb)
8547+
{
8548+
struct io_uring_task *tctx = current->io_uring;
8549+
struct io_tctx_exit *work;
8550+
8551+
work = container_of(cb, struct io_tctx_exit, task_work);
8552+
/*
8553+
* When @in_idle, we're in cancellation and it's racy to remove the
8554+
* node. It'll be removed by the end of cancellation, just ignore it.
8555+
*/
8556+
if (!atomic_read(&tctx->in_idle))
8557+
io_uring_del_task_file(work->index);
8558+
complete(&work->completion);
8559+
}
8560+
85398561
static void io_ring_exit_work(struct work_struct *work)
85408562
{
8541-
struct io_ring_ctx *ctx = container_of(work, struct io_ring_ctx,
8542-
exit_work);
8563+
struct io_ring_ctx *ctx = container_of(work, struct io_ring_ctx, exit_work);
8564+
struct io_tctx_exit exit;
8565+
struct io_tctx_node *node;
8566+
int ret;
85438567

85448568
/*
85458569
* If we're doing polled IO and end up having requests being
@@ -8550,6 +8574,26 @@ static void io_ring_exit_work(struct work_struct *work)
85508574
do {
85518575
io_uring_try_cancel_requests(ctx, NULL, NULL);
85528576
} while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20));
8577+
8578+
mutex_lock(&ctx->uring_lock);
8579+
while (!list_empty(&ctx->tctx_list)) {
8580+
node = list_first_entry(&ctx->tctx_list, struct io_tctx_node,
8581+
ctx_node);
8582+
exit.index = (unsigned long)node->file;
8583+
init_completion(&exit.completion);
8584+
init_task_work(&exit.task_work, io_tctx_exit_cb);
8585+
ret = task_work_add(node->task, &exit.task_work, TWA_SIGNAL);
8586+
if (WARN_ON_ONCE(ret))
8587+
continue;
8588+
wake_up_process(node->task);
8589+
8590+
mutex_unlock(&ctx->uring_lock);
8591+
wait_for_completion(&exit.completion);
8592+
cond_resched();
8593+
mutex_lock(&ctx->uring_lock);
8594+
}
8595+
mutex_unlock(&ctx->uring_lock);
8596+
85538597
io_ring_ctx_free(ctx);
85548598
}
85558599

0 commit comments

Comments
 (0)