mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 03:50:53 +07:00
io-wq: fix hang after cancelling pending hashed work
Don't forget to update wqe->hash_tail after cancelling a pending work
item, if it was hashed.
Cc: stable@vger.kernel.org # 5.7+
Reported-by: Dmitry Shulyak <yashulyak@gmail.com>
Fixes: 86f3cd1b58
("io-wq: handle hashed writes in chains")
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
fd7d6de224
commit
204361a77f
21
fs/io-wq.c
21
fs/io-wq.c
@ -925,6 +925,24 @@ static bool io_wq_worker_cancel(struct io_worker *worker, void *data)
|
||||
return match->nr_running && !match->cancel_all;
|
||||
}
|
||||
|
||||
static inline void io_wqe_remove_pending(struct io_wqe *wqe,
|
||||
struct io_wq_work *work,
|
||||
struct io_wq_work_node *prev)
|
||||
{
|
||||
unsigned int hash = io_get_work_hash(work);
|
||||
struct io_wq_work *prev_work = NULL;
|
||||
|
||||
if (io_wq_is_hashed(work) && work == wqe->hash_tail[hash]) {
|
||||
if (prev)
|
||||
prev_work = container_of(prev, struct io_wq_work, list);
|
||||
if (prev_work && io_get_work_hash(prev_work) == hash)
|
||||
wqe->hash_tail[hash] = prev_work;
|
||||
else
|
||||
wqe->hash_tail[hash] = NULL;
|
||||
}
|
||||
wq_list_del(&wqe->work_list, &work->list, prev);
|
||||
}
|
||||
|
||||
static void io_wqe_cancel_pending_work(struct io_wqe *wqe,
|
||||
struct io_cb_cancel_data *match)
|
||||
{
|
||||
@ -938,8 +956,7 @@ static void io_wqe_cancel_pending_work(struct io_wqe *wqe,
|
||||
work = container_of(node, struct io_wq_work, list);
|
||||
if (!match->fn(work, match->data))
|
||||
continue;
|
||||
|
||||
wq_list_del(&wqe->work_list, node, prev);
|
||||
io_wqe_remove_pending(wqe, work, prev);
|
||||
spin_unlock_irqrestore(&wqe->lock, flags);
|
||||
io_run_cancel(work, wqe);
|
||||
match->nr_pending++;
|
||||
|
Loading…
Reference in New Issue
Block a user