On 26/01/2021 23:35, Pavel Begunkov wrote: > Joseph reports following deadlock: > > CPU0: > ... > io_kill_linked_timeout // &ctx->completion_lock > io_commit_cqring > __io_queue_deferred > __io_queue_async_work > io_wq_enqueue > io_wqe_enqueue // &wqe->lock > > CPU1: > ... > __io_uring_files_cancel > io_wq_cancel_cb > io_wqe_cancel_pending_work // &wqe->lock > io_cancel_task_cb // &ctx->completion_lock > > Only __io_queue_deferred() calls queue_async_work() while holding > ctx->completion_lock, enqueue drained requests via io_req_task_queue() > instead. Joseph, can you try it out? would much appreciate > > Cc: stable@xxxxxxxxxxxxxxx # 5.9+ > Reported-by: Joseph Qi <joseph.qi@xxxxxxxxxxxxxxxxx> > Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> > --- > fs/io_uring.c | 10 ++-------- > 1 file changed, 2 insertions(+), 8 deletions(-) > > diff --git a/fs/io_uring.c b/fs/io_uring.c > index bb0270eeb8cb..c218deaf73a9 100644 > --- a/fs/io_uring.c > +++ b/fs/io_uring.c > @@ -1026,6 +1026,7 @@ static int io_setup_async_rw(struct io_kiocb *req, const struct iovec *iovec, > const struct iovec *fast_iov, > struct iov_iter *iter, bool force); > static void io_req_drop_files(struct io_kiocb *req); > +static void io_req_task_queue(struct io_kiocb *req); > > static struct kmem_cache *req_cachep; > > @@ -1634,18 +1635,11 @@ static void __io_queue_deferred(struct io_ring_ctx *ctx) > do { > struct io_defer_entry *de = list_first_entry(&ctx->defer_list, > struct io_defer_entry, list); > - struct io_kiocb *link; > > if (req_need_defer(de->req, de->seq)) > break; > list_del_init(&de->list); > - /* punt-init is done before queueing for defer */ > - link = __io_queue_async_work(de->req); > - if (link) { > - __io_queue_linked_timeout(link); > - /* drop submission reference */ > - io_put_req_deferred(link, 1); > - } > + io_req_task_queue(de->req); > kfree(de); > } while (!list_empty(&ctx->defer_list)); > } > -- Pavel Begunkov