Skip to content

Commit fc04c39

Browse files
isilenceaxboe
authored andcommitted
io-wq: fix IO_WQ_WORK_NO_CANCEL cancellation
To cancel a work, io-wq sets IO_WQ_WORK_CANCEL and executes the callback. However, IO_WQ_WORK_NO_CANCEL works will just execute and may return next work, which will be ignored and lost. Cancel the whole link. Signed-off-by: Pavel Begunkov <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 98d54f8 commit fc04c39

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

fs/io-wq.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,17 @@ static bool io_wq_can_queue(struct io_wqe *wqe, struct io_wqe_acct *acct,
747747
return true;
748748
}
749749

750+
static void io_run_cancel(struct io_wq_work *work)
751+
{
752+
do {
753+
struct io_wq_work *old_work = work;
754+
755+
work->flags |= IO_WQ_WORK_CANCEL;
756+
work->func(&work);
757+
work = (work == old_work) ? NULL : work;
758+
} while (work);
759+
}
760+
750761
static void io_wqe_enqueue(struct io_wqe *wqe, struct io_wq_work *work)
751762
{
752763
struct io_wqe_acct *acct = io_work_get_acct(wqe, work);
@@ -760,8 +771,7 @@ static void io_wqe_enqueue(struct io_wqe *wqe, struct io_wq_work *work)
760771
* It's close enough to not be an issue, fork() has the same delay.
761772
*/
762773
if (unlikely(!io_wq_can_queue(wqe, acct, work))) {
763-
work->flags |= IO_WQ_WORK_CANCEL;
764-
work->func(&work);
774+
io_run_cancel(work);
765775
return;
766776
}
767777

@@ -900,8 +910,7 @@ static enum io_wq_cancel io_wqe_cancel_cb_work(struct io_wqe *wqe,
900910
spin_unlock_irqrestore(&wqe->lock, flags);
901911

902912
if (found) {
903-
work->flags |= IO_WQ_WORK_CANCEL;
904-
work->func(&work);
913+
io_run_cancel(work);
905914
return IO_WQ_CANCEL_OK;
906915
}
907916

@@ -976,8 +985,7 @@ static enum io_wq_cancel io_wqe_cancel_work(struct io_wqe *wqe,
976985
spin_unlock_irqrestore(&wqe->lock, flags);
977986

978987
if (found) {
979-
work->flags |= IO_WQ_WORK_CANCEL;
980-
work->func(&work);
988+
io_run_cancel(work);
981989
return IO_WQ_CANCEL_OK;
982990
}
983991

0 commit comments

Comments
 (0)