Skip to content

Commit f152165

Browse files
committed
Merge tag 'io_uring-5.16-2021-12-10' of git://git.kernel.dk/linux-block
Pull io_uring fixes from Jens Axboe: "A few fixes that are all bound for stable: - Two syzbot reports for io-wq that turned out to be separate fixes, but ultimately very closely related - io_uring task_work running on cancelations" * tag 'io_uring-5.16-2021-12-10' of git://git.kernel.dk/linux-block: io-wq: check for wq exit after adding new worker task_work io_uring: ensure task_work gets run as part of cancelations io-wq: remove spurious bit clear on task_work addition
2 parents bd66be5 + 71a8538 commit f152165

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

fs/io-wq.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static bool io_acct_cancel_pending_work(struct io_wqe *wqe,
142142
struct io_wqe_acct *acct,
143143
struct io_cb_cancel_data *match);
144144
static void create_worker_cb(struct callback_head *cb);
145+
static void io_wq_cancel_tw_create(struct io_wq *wq);
145146

146147
static bool io_worker_get(struct io_worker *worker)
147148
{
@@ -357,12 +358,22 @@ static bool io_queue_worker_create(struct io_worker *worker,
357358
test_and_set_bit_lock(0, &worker->create_state))
358359
goto fail_release;
359360

361+
atomic_inc(&wq->worker_refs);
360362
init_task_work(&worker->create_work, func);
361363
worker->create_index = acct->index;
362364
if (!task_work_add(wq->task, &worker->create_work, TWA_SIGNAL)) {
363-
clear_bit_unlock(0, &worker->create_state);
365+
/*
366+
* EXIT may have been set after checking it above, check after
367+
* adding the task_work and remove any creation item if it is
368+
* now set. wq exit does that too, but we can have added this
369+
* work item after we canceled in io_wq_exit_workers().
370+
*/
371+
if (test_bit(IO_WQ_BIT_EXIT, &wq->state))
372+
io_wq_cancel_tw_create(wq);
373+
io_worker_ref_put(wq);
364374
return true;
365375
}
376+
io_worker_ref_put(wq);
366377
clear_bit_unlock(0, &worker->create_state);
367378
fail_release:
368379
io_worker_release(worker);
@@ -1198,20 +1209,26 @@ void io_wq_exit_start(struct io_wq *wq)
11981209
set_bit(IO_WQ_BIT_EXIT, &wq->state);
11991210
}
12001211

1201-
static void io_wq_exit_workers(struct io_wq *wq)
1212+
static void io_wq_cancel_tw_create(struct io_wq *wq)
12021213
{
12031214
struct callback_head *cb;
1204-
int node;
1205-
1206-
if (!wq->task)
1207-
return;
12081215

12091216
while ((cb = task_work_cancel_match(wq->task, io_task_work_match, wq)) != NULL) {
12101217
struct io_worker *worker;
12111218

12121219
worker = container_of(cb, struct io_worker, create_work);
12131220
io_worker_cancel_cb(worker);
12141221
}
1222+
}
1223+
1224+
static void io_wq_exit_workers(struct io_wq *wq)
1225+
{
1226+
int node;
1227+
1228+
if (!wq->task)
1229+
return;
1230+
1231+
io_wq_cancel_tw_create(wq);
12151232

12161233
rcu_read_lock();
12171234
for_each_node(node) {

fs/io_uring.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9824,7 +9824,7 @@ static __cold void io_uring_drop_tctx_refs(struct task_struct *task)
98249824

98259825
/*
98269826
* Find any io_uring ctx that this task has registered or done IO on, and cancel
9827-
* requests. @sqd should be not-null IIF it's an SQPOLL thread cancellation.
9827+
* requests. @sqd should be not-null IFF it's an SQPOLL thread cancellation.
98289828
*/
98299829
static __cold void io_uring_cancel_generic(bool cancel_all,
98309830
struct io_sq_data *sqd)
@@ -9866,8 +9866,10 @@ static __cold void io_uring_cancel_generic(bool cancel_all,
98669866
cancel_all);
98679867
}
98689868

9869-
prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE);
9869+
prepare_to_wait(&tctx->wait, &wait, TASK_INTERRUPTIBLE);
9870+
io_run_task_work();
98709871
io_uring_drop_tctx_refs(current);
9872+
98719873
/*
98729874
* If we've seen completions, retry without waiting. This
98739875
* avoids a race where a completion comes in before we did

0 commit comments

Comments
 (0)