Commit c80ca470 authored by Jens Axboe's avatar Jens Axboe
Browse files

io-wq: cancel task_work on exit only targeting the current 'wq'



With using task_work_cancel(), we're potentially canceling task_work
that isn't related to this specific io_wq. Use the newly added
task_work_cancel_match() to ensure that we only remove and cancel work
items that are specific to this io_wq.

Fixes: 685fe7fe ("io-wq: eliminate the need for a manager thread")
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent c7aab1a7
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -986,6 +986,16 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
	return ERR_PTR(ret);
}

static bool io_task_work_match(struct callback_head *cb, void *data)
{
	struct create_worker_data *cwd;

	if (cb->func != create_worker_cb)
		return false;
	cwd = container_of(cb, struct create_worker_data, work);
	return cwd->wqe->wq == data;
}

static void io_wq_exit_workers(struct io_wq *wq)
{
	struct callback_head *cb;
@@ -996,7 +1006,7 @@ static void io_wq_exit_workers(struct io_wq *wq)
	if (!wq->task)
		return;

	while ((cb = task_work_cancel(wq->task, create_worker_cb)) != NULL) {
	while ((cb = task_work_cancel_match(wq->task, io_task_work_match, wq)) != NULL) {
		struct create_worker_data *cwd;

		cwd = container_of(cb, struct create_worker_data, work);