Once we've copied some data for an iocb that is marked with IOCB_WAITQ, we should no longer attempt to async lock a new page. Instead make sure we return the copied amount, and let the caller retry, instead of returning -EIOCBQUEUED for a new page. This should only be possible with read-ahead disabled on the below device, and multiple threads racing on the same file. Haven't been able to reproduce on anything else. Cc: stable@xxxxxxxxxxxxxxx # v5.9 Fixes: 1a0a7853b901 ("mm: support async buffered reads in generic_file_buffered_read()") Reported-by: Kent Overstreet <kent.overstreet@xxxxxxxxx> Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> --- V2 - Place the NOWAIT marker when we increment 'written' (Willy) mm/filemap.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mm/filemap.c b/mm/filemap.c index 1a6beaf69f49..508048bfd2a5 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2329,6 +2329,15 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb, put_page(page); written += ret; + + /* + * If we've already successfully copied some data, then we + * can no longer safely return -EIOCBQUEUED. Hence mark + * an async read NOWAIT at that point. + */ + if (iocb->ki_flags & IOCB_WAITQ) + iocb->ki_flags |= IOCB_NOWAIT; + if (!iov_iter_count(iter)) goto out; if (ret < nr) { -- 2.28.0 -- Jens Axboe