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: 685fe7feed ("io-wq: eliminate the need for a manager thread")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
12
fs/io-wq.c
12
fs/io-wq.c
@@ -986,6 +986,16 @@ err_wq:
|
|||||||
return ERR_PTR(ret);
|
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)
|
static void io_wq_exit_workers(struct io_wq *wq)
|
||||||
{
|
{
|
||||||
struct callback_head *cb;
|
struct callback_head *cb;
|
||||||
@@ -996,7 +1006,7 @@ static void io_wq_exit_workers(struct io_wq *wq)
|
|||||||
if (!wq->task)
|
if (!wq->task)
|
||||||
return;
|
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;
|
struct create_worker_data *cwd;
|
||||||
|
|
||||||
cwd = container_of(cb, struct create_worker_data, work);
|
cwd = container_of(cb, struct create_worker_data, work);
|
||||||
|
|||||||
Reference in New Issue
Block a user