aboutsummaryrefslogtreecommitdiff
path: root/kernel/freezer.c
diff options
context:
space:
mode:
authorGravatar Pavel Begunkov <asml.silence@gmail.com> 2021-03-11 23:29:38 +0000
committerGravatar Jens Axboe <axboe@kernel.dk> 2021-03-12 09:42:55 -0700
commit521d6a737a31c08dbab204a95cd4fb5bee725f0f (patch)
tree9feb717d60e0ad38801c287e80fb9224ff831f72 /kernel/freezer.c
parentio_uring: prevent racy sqd->thread checks (diff)
downloadlinux-521d6a737a31c08dbab204a95cd4fb5bee725f0f.tar.gz
linux-521d6a737a31c08dbab204a95cd4fb5bee725f0f.tar.bz2
linux-521d6a737a31c08dbab204a95cd4fb5bee725f0f.zip
io_uring: cancel sqpoll via task_work
1) The first problem is io_uring_cancel_sqpoll() -> io_uring_cancel_task_requests() basically doing park(); park(); and so hanging. 2) Another one is more subtle, when the master task is doing cancellations, but SQPOLL task submits in-between the end of the cancellation but before finish() requests taking a ref to the ctx, and so eternally locking it up. 3) Yet another is a dying SQPOLL task doing io_uring_cancel_sqpoll() and same io_uring_cancel_sqpoll() from the owner task, they race for tctx->wait events. And there probably more of them. Instead do SQPOLL cancellations from within SQPOLL task context via task_work, see io_sqpoll_cancel_sync(). With that we don't need temporal park()/unpark() during cancellation, which is ugly, subtle and anyway doesn't allow to do io_run_task_work() properly. io_uring_cancel_sqpoll() is called only from SQPOLL task context and under sqd locking, so all parking is removed from there. And so, io_sq_thread_[un]park() and io_sq_thread_stop() are not used now by SQPOLL task, and that spare us from some headache. Also remove ctx->sqd_list early to avoid 2). And kill tctx->sqpoll, which is not used anymore. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'kernel/freezer.c')
0 files changed, 0 insertions, 0 deletions