[PATCH 2/2] mm/readahead: Fix readahead miss detection with FAULT_FLAG_RETRY_NOWAIT

From: Jan Kara
Date: Thu Feb 01 2024 - 11:28:23 EST


When the page fault happens with FAULT_FLAG_RETRY_NOWAIT (which is
common) we will bail out of the page fault after issuing reads and retry
the fault. That will then find the created pages in filemap_map_pages()
and hence will be treated as cache hit canceling out the cache miss in
do_sync_mmap_readahead(). Increment mmap_miss by two in
do_sync_mmap_readahead() in case FAULT_FLAG_RETRY_NOWAIT is set to
account for the following expected hit. If the page gets evicted even
before we manage to retry the fault, we are under so heavy memory
pressure that increasing mmap_miss by two is fine.

Reported-by: Liu Shixin <liushixin2@xxxxxxxxxx>
Fixes: d065bd810b6d ("mm: retry page fault when blocking on disk transfer")
Signed-off-by: Jan Kara <jack@xxxxxxx>
---
mm/filemap.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/mm/filemap.c b/mm/filemap.c
index 0b843f99407c..2dda5dc04517 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3132,8 +3132,14 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)

/* Avoid banging the cache line if not needed */
mmap_miss = READ_ONCE(ra->mmap_miss);
+ /*
+ * Increment mmap_miss by 2 if we are going to bail out of fault after
+ * issuing IO as we will then go back and map the cached page which is
+ * accounted as a cache hit.
+ */
+ mmap_miss += 1 + !!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT);
if (mmap_miss < MMAP_LOTSAMISS * 10)
- WRITE_ONCE(ra->mmap_miss, ++mmap_miss);
+ WRITE_ONCE(ra->mmap_miss, mmap_miss);

/*
* Do we miss much more than hit in this file? If so,
--
2.35.3


--3ct7qtyk6r2k3prh--