Restore Kent's optimisation for I/O sizes between 64kB and 1MB. Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- mm/filemap.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index f41de0759e86..2b4d8ed241bd 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2427,7 +2427,7 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, struct file_ra_state *ra = &filp->f_ra; struct address_space *mapping = filp->f_mapping; struct inode *inode = mapping->host; - struct pagevec pvec; + struct pagevec pvec_stack, *pvec = NULL; int i, error = 0; bool writably_mapped; loff_t isize, end_offset; @@ -2436,6 +2436,10 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, return 0; iov_iter_truncate(iter, inode->i_sb->s_maxbytes); + if (iter->count / PAGE_SIZE > PAGEVEC_SIZE) + pvec = pagevec_alloc(iter->count / PAGE_SIZE + 1, GFP_KERNEL); + if (!pvec) + pvec = &pvec_stack; do { cond_resched(); @@ -2447,7 +2451,7 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, if ((iocb->ki_flags & IOCB_WAITQ) && already_read) iocb->ki_flags |= IOCB_NOWAIT; - error = filemap_get_pages(iocb, iter, &pvec); + error = filemap_get_pages(iocb, iter, pvec); if (error < 0) break; @@ -2476,10 +2480,10 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, */ if (iocb->ki_pos >> PAGE_SHIFT != ra->prev_pos >> PAGE_SHIFT) - mark_page_accessed(pvec.pages[0]); + mark_page_accessed(pvec->pages[0]); - for (i = 0; i < pagevec_count(&pvec); i++) { - struct page *page = pvec.pages[i]; + for (i = 0; i < pagevec_count(pvec); i++) { + struct page *page = pvec->pages[i]; size_t page_size = thp_size(page); size_t offset = iocb->ki_pos & (page_size - 1); size_t bytes = min_t(loff_t, end_offset - iocb->ki_pos, @@ -2514,7 +2518,7 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, } } put_pages: - pagevec_release(&pvec); + pagevec_release(pvec); } while (iov_iter_count(iter) && iocb->ki_pos < isize && !error); file_accessed(filp); -- 2.28.0