Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
To: Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	David Hildenbrand <david@kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	Vlastimil Babka <vbabka@kernel.org>,
	Lorenzo Stoakes <ljs@kernel.org>, Jan Kara <jack@suse.cz>,
	Hugh Dickins <hughd@google.com>,
	Christian Brauner <brauner@kernel.org>,
	Alexander Viro <viro@zeniv.linux.org.uk>
Cc: "Kiryl Shutsemau (Meta)" <kas@kernel.org>,
	Miklos Szeredi <miklos@szeredi.hu>,
	Miaohe Lin <linmiaohe@huawei.com>,
	Naoya Horiguchi <nao.horiguchi@gmail.com>,
	Oscar Salvador <osalvador@suse.de>,
	"Liam R . Howlett" <liam@infradead.org>,
	Mike Rapoport <rppt@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>,
	Brendan Jackman <brendan.jackman@linux.dev>,
	Johannes Weiner <hannes@cmpxchg.org>, Zi Yan <ziy@nvidia.com>,
	Baolin Wang <baolin.wang@linux.alibaba.com>,
	Nico Pache <nico.pache@linux.dev>,
	Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
	Barry Song <baohua@kernel.org>, Lance Yang <lance.yang@linux.dev>,
	Usama Arif <usama.arif@linux.dev>,
	Kairui Song <kasong@tencent.com>, Qi Zheng <qi.zheng@linux.dev>,
	Shakeel Butt <shakeel.butt@linux.dev>,
	Axel Rasmussen <axelrasmussen@google.com>,
	Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
	Baoquan He <baoquan.he@linux.dev>,
	"Paul E . McKenney" <paulmck@kernel.org>,
	Pedro Falcato <pfalcato@suse.de>, Harry Yoo <harry@kernel.org>,
	Luis Chamberlain <mcgrof@kernel.org>,
	Ilya Gladyshev <ilya.gladyshev@linux.dev>,
	Jaegeuk Kim <jaegeuk@kernel.org>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, fuse-devel@lists.linux.dev,
	kernel-team@meta.com
Subject: [RFC PATCH 16/18] mm/shmem: count accesses to a folio the way filemap_read() does
Date: Mon, 19 Oct 2026 16:49:09 +0100	[thread overview]
Message-ID: <20261019154913.1765974-17-kas@kernel.org> (raw)
In-Reply-To: <20261019154913.1765974-1-kas@kernel.org>

shmem_file_read_iter() marks a folio accessed only when a read starts at
the beginning of the folio.  Small reads that start anywhere else never
count, so a folio that is read over and over at one offset ages as if it
were never read.

Count accesses with filemap_read_accessed(), as filemap_read() does: a
read marks the folio accessed unless it goes on in the folio that the
previous read through the file ended in.  Reading the same bytes again
through one open file counts once, as for other files, where it used to
count each time it started at the beginning of the folio.  The end of
the previous read is kept in f_ra.prev_pos, as for other files.

This also sets PG_rcu_free on the tmpfs folios that reads keep coming
back to.  On a shmem folio the PG_readahead bit is PG_reclaim, and shmem
does no readahead, so do not let that bit keep the flag off.  A write
marks a tmpfs folio accessed too, so a folio written in several pieces
can get the flag on its first read.

Assisted-by: LLM
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
---
 mm/filemap.c  |  9 +++++----
 mm/internal.h |  1 +
 mm/shmem.c    | 11 ++++++-----
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/mm/filemap.c b/mm/filemap.c
index ace6b1fd6b9e..4b5b7ba78f39 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2778,8 +2778,10 @@ static void filemap_mark_hot(struct folio *folio)
 	if (!IS_ENABLED(CONFIG_PAGE_RCU_FREE))
 		return;
 	if (folio_test_rcu_free(folio) || !folio_test_uptodate(folio) ||
-	    folio_test_readahead(folio) || folio_test_dropbehind(folio) ||
-	    folio_test_unevictable(folio))
+	    folio_test_dropbehind(folio) || folio_test_unevictable(folio))
+		return;
+	/* shmem does no readahead: there the bit is PG_reclaim */
+	if (folio_test_readahead(folio) && !folio_test_swapbacked(folio))
 		return;
 	if (folio_test_set_rcu_free(folio))
 		return;
@@ -2802,8 +2804,7 @@ static void filemap_mark_hot(struct folio *folio)
  * LRU records, or when this open file goes back to data that it has just
  * read.
  */
-static void filemap_read_accessed(struct folio *folio, loff_t pos,
-				  loff_t last_pos)
+void filemap_read_accessed(struct folio *folio, loff_t pos, loff_t last_pos)
 {
 	bool hot;
 
diff --git a/mm/internal.h b/mm/internal.h
index 38b1165212c9..18391dc50418 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -1248,6 +1248,7 @@ struct migration_target_control {
  */
 size_t splice_folio_into_pipe(struct pipe_inode_info *pipe,
 			      struct folio *folio, loff_t fpos, size_t size);
+void filemap_read_accessed(struct folio *folio, loff_t pos, loff_t last_pos);
 
 static inline bool vma_is_single_threaded_private(struct vm_area_struct *vma)
 {
diff --git a/mm/shmem.c b/mm/shmem.c
index 848316eaa7f4..43ddb50974a5 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3309,6 +3309,7 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(file);
 	struct address_space *mapping = inode->i_mapping;
+	loff_t last_pos = file->f_ra.prev_pos;
 	pgoff_t index;
 	unsigned long offset;
 	int error = 0;
@@ -3378,11 +3379,7 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 					flush_dcache_page(page);
 			}
 
-			/*
-			 * Mark the folio accessed if we read the beginning.
-			 */
-			if (!offset)
-				folio_mark_accessed(folio);
+			filemap_read_accessed(folio, iocb->ki_pos, last_pos);
 			/*
 			 * Ok, we have the page, and it's up-to-date, so
 			 * now we can copy it to user space...
@@ -3410,6 +3407,7 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 
 		retval += ret;
 		iocb->ki_pos += ret;
+		last_pos = iocb->ki_pos;
 
 		if (!iov_iter_count(to))
 			break;
@@ -3421,6 +3419,9 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 	}
 
 	file_accessed(file);
+	/* Readers sharing the file would bounce the line for nothing */
+	if (file->f_ra.prev_pos != last_pos)
+		file->f_ra.prev_pos = last_pos;
 	return retval ? retval : error;
 }
 
-- 
2.54.0



  parent reply	other threads:[~2026-10-19 15:51 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 15:48 [RFC PATCH 00/18] mm: read the page cache without folio references Kiryl Shutsemau (Meta)
2026-10-19 15:48 ` [RFC PATCH 01/18] mm: free PG_rcu_free folios only after an RCU grace period Kiryl Shutsemau (Meta)
2026-10-19 15:48 ` [RFC PATCH 02/18] splice: don't steal page cache folios Kiryl Shutsemau (Meta)
2026-10-19 15:48 ` [RFC PATCH 03/18] fuse: don't move a folio with PG_rcu_free into a fuse file Kiryl Shutsemau (Meta)
2026-10-19 15:48 ` [RFC PATCH 04/18] mm: count the pages waiting for a grace period Kiryl Shutsemau (Meta)
2026-10-19 15:48 ` [RFC PATCH 05/18] mm: expedite the grace period when a CPU has many deferred frees Kiryl Shutsemau (Meta)
2026-10-19 15:48 ` [RFC PATCH 06/18] mm: free the pages waiting for a grace period before OOM Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 07/18] mm: free the pages waiting for a grace period before isolation fails Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 08/18] mm/memory-failure: handle folios with PG_rcu_free Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 09/18] mm: have folio_mark_accessed() return whether the folio is hot Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 10/18] mm/filemap: mark a folio accessed in one place in filemap_read() Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 11/18] mm/filemap: set PG_rcu_free on the folios that reads keep coming back to Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 12/18] mm/filemap: don't defer the free of folios of an inode being evicted Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 13/18] mm/filemap: store the end of a read in f_ra only when it changes Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 14/18] mm/filemap: read from the page cache without folio references Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 15/18] mm/filemap: read large folios " Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` Kiryl Shutsemau (Meta) [this message]
2026-10-19 15:49 ` [RFC PATCH 17/18] mm/shmem: read " Kiryl Shutsemau (Meta)
2026-10-19 15:49 ` [RFC PATCH 18/18] mm/filemap: add a debugfs switch for lockless page cache reads Kiryl Shutsemau (Meta)
2026-10-19 21:20 ` [RFC PATCH 00/18] mm: read the page cache without folio references Harry Yoo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261019154913.1765974-17-kas@kernel.org \
    --to=kas@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=baoquan.he@linux.dev \
    --cc=brauner@kernel.org \
    --cc=brendan.jackman@linux.dev \
    --cc=david@kernel.org \
    --cc=dev.jain@arm.com \
    --cc=fuse-devel@lists.linux.dev \
    --cc=hannes@cmpxchg.org \
    --cc=harry@kernel.org \
    --cc=hughd@google.com \
    --cc=ilya.gladyshev@linux.dev \
    --cc=jack@suse.cz \
    --cc=jaegeuk@kernel.org \
    --cc=kasong@tencent.com \
    --cc=kernel-team@meta.com \
    --cc=lance.yang@linux.dev \
    --cc=liam@infradead.org \
    --cc=linmiaohe@huawei.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mcgrof@kernel.org \
    --cc=mhocko@suse.com \
    --cc=miklos@szeredi.hu \
    --cc=nao.horiguchi@gmail.com \
    --cc=nico.pache@linux.dev \
    --cc=osalvador@suse.de \
    --cc=paulmck@kernel.org \
    --cc=pfalcato@suse.de \
    --cc=qi.zheng@linux.dev \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=shakeel.butt@linux.dev \
    --cc=surenb@google.com \
    --cc=torvalds@linux-foundation.org \
    --cc=usama.arif@linux.dev \
    --cc=vbabka@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=weixugc@google.com \
    --cc=willy@infradead.org \
    --cc=yuanchu@google.com \
    --cc=ziy@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox