Skip to content

Commit afcc401

Browse files
committed
io-wq: provide an io_wq_put_and_exit() helper
If we put the io-wq from io_uring, we really want it to exit. Provide a helper that does that for us. Couple that with not having the manager hold a reference to the 'wq' and the normal SQPOLL exit will tear down the io-wq context appropriate. On the io-wq side, our wq context is per task, so only the task itself is manipulating ->manager and hence it's safe to check and clear without any extra locking. We just need to ensure that the manager task stays around, in case it exits. Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 8629397 commit afcc401

3 files changed

Lines changed: 21 additions & 11 deletions

File tree

fs/io-wq.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ static int io_wq_manager(void *data)
749749
sprintf(buf, "iou-mgr-%d", wq->task_pid);
750750
set_task_comm(current, buf);
751751
current->flags |= PF_IO_WORKER;
752-
wq->manager = current;
752+
wq->manager = get_task_struct(current);
753753

754754
complete(&wq->started);
755755

@@ -771,9 +771,7 @@ static int io_wq_manager(void *data)
771771
/* we might not ever have created any workers */
772772
if (atomic_read(&wq->worker_refs))
773773
wait_for_completion(&wq->worker_done);
774-
wq->manager = NULL;
775774
complete(&wq->exited);
776-
io_wq_put(wq);
777775
do_exit(0);
778776
}
779777

@@ -816,8 +814,6 @@ static int io_wq_fork_manager(struct io_wq *wq)
816814
return 0;
817815

818816
reinit_completion(&wq->worker_done);
819-
clear_bit(IO_WQ_BIT_EXIT, &wq->state);
820-
refcount_inc(&wq->refs);
821817
current->flags |= PF_IO_WORKER;
822818
ret = io_wq_fork_thread(io_wq_manager, wq);
823819
current->flags &= ~PF_IO_WORKER;
@@ -1089,17 +1085,24 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
10891085
return ERR_PTR(ret);
10901086
}
10911087

1088+
static void io_wq_destroy_manager(struct io_wq *wq)
1089+
{
1090+
if (wq->manager) {
1091+
wake_up_process(wq->manager);
1092+
wait_for_completion(&wq->exited);
1093+
put_task_struct(wq->manager);
1094+
wq->manager = NULL;
1095+
}
1096+
}
1097+
10921098
static void io_wq_destroy(struct io_wq *wq)
10931099
{
10941100
int node;
10951101

10961102
cpuhp_state_remove_instance_nocalls(io_wq_online, &wq->cpuhp_node);
10971103

10981104
set_bit(IO_WQ_BIT_EXIT, &wq->state);
1099-
if (wq->manager) {
1100-
wake_up_process(wq->manager);
1101-
wait_for_completion(&wq->exited);
1102-
}
1105+
io_wq_destroy_manager(wq);
11031106

11041107
spin_lock_irq(&wq->hash->wait.lock);
11051108
for_each_node(node) {
@@ -1112,7 +1115,6 @@ static void io_wq_destroy(struct io_wq *wq)
11121115
io_wq_put_hash(wq->hash);
11131116
kfree(wq->wqes);
11141117
kfree(wq);
1115-
11161118
}
11171119

11181120
void io_wq_put(struct io_wq *wq)
@@ -1121,6 +1123,13 @@ void io_wq_put(struct io_wq *wq)
11211123
io_wq_destroy(wq);
11221124
}
11231125

1126+
void io_wq_put_and_exit(struct io_wq *wq)
1127+
{
1128+
set_bit(IO_WQ_BIT_EXIT, &wq->state);
1129+
io_wq_destroy_manager(wq);
1130+
io_wq_put(wq);
1131+
}
1132+
11241133
static bool io_wq_worker_affinity(struct io_worker *worker, void *data)
11251134
{
11261135
struct task_struct *task = worker->task;

fs/io-wq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ struct io_wq_data {
114114

115115
struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data);
116116
void io_wq_put(struct io_wq *wq);
117+
void io_wq_put_and_exit(struct io_wq *wq);
117118

118119
void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work);
119120
void io_wq_hash_work(struct io_wq_work *work, void *val);

fs/io_uring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8857,7 +8857,7 @@ void __io_uring_files_cancel(struct files_struct *files)
88578857
if (files) {
88588858
io_uring_remove_task_files(tctx);
88598859
if (tctx->io_wq) {
8860-
io_wq_put(tctx->io_wq);
8860+
io_wq_put_and_exit(tctx->io_wq);
88618861
tctx->io_wq = NULL;
88628862
}
88638863
}

0 commit comments

Comments
 (0)