提交 939325bb 编写于 作者: M Matthew Wilcox (Oracle) 提交者: Zheng Zengkai

filemap: Correct the conditions for marking a folio as accessed

mainline inclusion
from mainline-5.19-rc4
commit 5ccc944d
category: bugfix
bugzilla: 186896, https://gitee.com/src-openeuler/kernel/issues/I5GZC8
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=5ccc944dce3df5fd2fd683a7df4fd49d1068eba2

-------------------------------------------------

We had an off-by-one error which meant that we never marked the first page
in a read as accessed.  This was visible as a slowdown when re-reading
a file as pages were being evicted from cache too soon.  In reviewing
this code, we noticed a second bug where a multi-page folio would be
marked as accessed multiple times when doing reads that were less than
the size of the folio.

Abstract the comparison of whether two file positions are in the same
folio into a new function, fixing both of these bugs.
Reported-by: NYu Kuai <yukuai3@huawei.com>
Reviewed-by: NKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: NMatthew Wilcox (Oracle) <willy@infradead.org>

Conflict: folios is not supported yet
Signed-off-by: NYu Kuai <yukuai3@huawei.com>
Reviewed-by: NKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 75b7fe66
......@@ -2437,6 +2437,13 @@ static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
goto find_page;
}
static inline bool pos_same_page(loff_t pos1, loff_t pos2, struct page *page)
{
unsigned int shift = page_shift(page);
return (pos1 >> shift == pos2 >> shift);
}
/**
* generic_file_buffered_read - generic file read routine
* @iocb: the iocb to read
......@@ -2527,11 +2534,10 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
writably_mapped = mapping_writably_mapped(mapping);
/*
* When a sequential read accesses a page several times, only
* When a read accesses a page several times, only
* mark it as accessed the first time.
*/
if (iocb->ki_pos >> PAGE_SHIFT !=
ra->prev_pos >> PAGE_SHIFT)
if (pos_same_page(iocb->ki_pos, ra->prev_pos -1, pages[0]))
mark_page_accessed(pages[0]);
for (i = 1; i < pg_nr; i++)
mark_page_accessed(pages[i]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册