Skip to content

Commit 5f3f26f

Browse files
committed
io_uring: fix SQPOLL thread handling over exec
Just like the changes for io-wq, ensure that we re-fork the SQPOLL thread if the owner execs. Mark the ctx sq thread as sqo_exec if it dies, and the ring as needing a wakeup which will force the task to enter the kernel. When it does, setup the new thread and proceed as usual. Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 4fb6ac3 commit 5f3f26f

1 file changed

Lines changed: 34 additions & 1 deletion

File tree

fs/io_uring.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ struct io_ring_ctx {
339339
unsigned int eventfd_async: 1;
340340
unsigned int restricted: 1;
341341
unsigned int sqo_dead: 1;
342+
unsigned int sqo_exec: 1;
342343

343344
/*
344345
* Ring buffer of indices into array of io_uring_sqe, which is
@@ -6796,6 +6797,10 @@ static int io_sq_thread(void *data)
67966797
complete_all(&sqd->completion);
67976798
mutex_lock(&sqd->lock);
67986799
sqd->thread = NULL;
6800+
list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) {
6801+
ctx->sqo_exec = 1;
6802+
io_ring_set_wakeup_flag(ctx);
6803+
}
67996804
mutex_unlock(&sqd->lock);
68006805

68016806
complete(&sqd->exited);
@@ -7840,6 +7845,25 @@ void __io_uring_free(struct task_struct *tsk)
78407845
tsk->io_uring = NULL;
78417846
}
78427847

7848+
static int io_sq_thread_fork(struct io_sq_data *sqd, struct io_ring_ctx *ctx)
7849+
{
7850+
int ret;
7851+
7852+
clear_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state);
7853+
reinit_completion(&sqd->completion);
7854+
ctx->sqo_dead = ctx->sqo_exec = 0;
7855+
sqd->task_pid = current->pid;
7856+
current->flags |= PF_IO_WORKER;
7857+
ret = io_wq_fork_thread(io_sq_thread, sqd);
7858+
current->flags &= ~PF_IO_WORKER;
7859+
if (ret < 0) {
7860+
sqd->thread = NULL;
7861+
return ret;
7862+
}
7863+
wait_for_completion(&sqd->completion);
7864+
return io_uring_alloc_task_context(sqd->thread, ctx);
7865+
}
7866+
78437867
static int io_sq_offload_create(struct io_ring_ctx *ctx,
78447868
struct io_uring_params *p)
78457869
{
@@ -9128,6 +9152,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
91289152
if (ctx->flags & IORING_SETUP_SQPOLL) {
91299153
io_cqring_overflow_flush(ctx, false, NULL, NULL);
91309154

9155+
if (unlikely(ctx->sqo_exec)) {
9156+
ret = io_sq_thread_fork(ctx->sq_data, ctx);
9157+
if (ret)
9158+
goto out;
9159+
ctx->sqo_exec = 0;
9160+
}
91319161
ret = -EOWNERDEAD;
91329162
if (unlikely(ctx->sqo_dead))
91339163
goto out;
@@ -9229,8 +9259,11 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
92299259
*/
92309260
has_lock = mutex_trylock(&ctx->uring_lock);
92319261

9232-
if (has_lock && (ctx->flags & IORING_SETUP_SQPOLL))
9262+
if (has_lock && (ctx->flags & IORING_SETUP_SQPOLL)) {
92339263
sq = ctx->sq_data;
9264+
if (!sq->thread)
9265+
sq = NULL;
9266+
}
92349267

92359268
seq_printf(m, "SqThread:\t%d\n", sq ? task_pid_nr(sq->thread) : -1);
92369269
seq_printf(m, "SqThreadCpu:\t%d\n", sq ? task_cpu(sq->thread) : -1);

0 commit comments

Comments
 (0)