On 05/02/2021 08:34, Hao Xu wrote: > This might happen if we do epoll_wait on a uring fd while reading/writing > the former epoll fd in a sqe in the former uring instance. > So let's don't flush cqring overflow list, just do a simple check. I haven't tested it but tried out identical before. Reviewed-by: Pavel Begunkov <asml.silence@xxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx # 5.5+ > > Reported-by: Abaci <abaci@xxxxxxxxxxxxxxxxx> > Fixes: 6c503150ae33 ("io_uring: patch up IOPOLL overflow_flush sync") > Signed-off-by: Hao Xu <haoxu@xxxxxxxxxxxxxxxxx> > --- > fs/io_uring.c | 17 +++++++++++++++-- > 1 file changed, 15 insertions(+), 2 deletions(-) > > diff --git a/fs/io_uring.c b/fs/io_uring.c > index 38c6cbe1ab38..5f42ad6f2155 100644 > --- a/fs/io_uring.c > +++ b/fs/io_uring.c > @@ -8718,8 +8718,21 @@ static __poll_t io_uring_poll(struct file *file, poll_table *wait) > smp_rmb(); > if (!io_sqring_full(ctx)) > mask |= EPOLLOUT | EPOLLWRNORM; > - io_cqring_overflow_flush(ctx, false, NULL, NULL); > - if (io_cqring_events(ctx)) > + > + /* > + * Don't flush cqring overflow list here, just do a simple check. > + * Otherwise there could possible be ABBA deadlock: > + * CPU0 CPU1 > + * ---- ---- > + * lock(&ctx->uring_lock); > + * lock(&ep->mtx); > + * lock(&ctx->uring_lock); > + * lock(&ep->mtx); > + * > + * Users may get EPOLLIN meanwhile seeing nothing in cqring, this > + * pushs them to do the flush. > + */ > + if (io_cqring_events(ctx) || test_bit(0, &ctx->cq_check_overflow)) > mask |= EPOLLIN | EPOLLRDNORM; > > return mask; > -- Pavel Begunkov