Thread (11 messages) 11 messages, 5 authors, 2025-06-10

Re: [RFC] mm: use folio_expected_ref_count() helper for reference counting

From: Shivank Garg <hidden>
Date: 2025-06-10 05:50:24
Also in: linux-mm, linux-perf-users, lkml


On 6/10/2025 7:56 AM, Alistair Popple wrote:
On Mon, Jun 09, 2025 at 05:08:07PM +0000, Shivank Garg wrote:
quoted
Replace open-coded folio reference count calculations with the
folio_expected_ref_count() helper to improve code maintainability
and reduce duplication.
I wonder if there is any opportunity for reducing duplication more broadly?
The migration code has similar helpers (folio_expected_refs) as does
khugepaged (is_refcount_suitable) and vmscan (is_page_cache_freeable).
The folio_expected_refs() and is_refcount_suitable() consolidation was 
recently merged:
- 86ebd50224c0 ("mm: add folio_expected_ref_count() for reference count calculation")
- 0b43b8bc8ef8 ("mm/khugepaged: clean up refcount check using folio_expected_ref_count()")
do_huge_pmd_wp_page() also has an open-coded version of these checks and there
are probably others around the place to.

These could all be converted to a helper that returns all the "extra" references
after taking into account things like mapping, swapcache, etc. depending on folio.> 
quoted
No functional changes intended.

Signed-off-by: Shivank Garg <redacted>
---
 kernel/events/uprobes.c | 5 +++--
 mm/memfd.c              | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 4c965ba77f9f..c978c8c27340 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -434,10 +434,11 @@ static int __uprobe_write_opcode(struct vm_area_struct *vma,
 	/*
 	 * When unregistering, we may only zap a PTE if uffd is disabled and
 	 * there are no unexpected folio references ...
+	 * Expected refs: mappings + swapcache.
+	 * We hold one additional reference (+1).
 	 */
 	if (is_register || userfaultfd_missing(vma) ||
-	    (folio_ref_count(folio) != folio_mapcount(folio) + 1 +
-	     folio_test_swapcache(folio) * folio_nr_pages(folio)))
+	    (folio_ref_count(folio) != folio_expected_ref_count(folio) + 1))
 		goto remap;
 
 	/*
diff --git a/mm/memfd.c b/mm/memfd.c
index ab367e61553d..4ed5506221b7 100644
--- a/mm/memfd.c
+++ b/mm/memfd.c
@@ -32,8 +32,8 @@
 
 static bool memfd_folio_has_extra_refs(struct folio *folio)
 {
-	return folio_ref_count(folio) - folio_mapcount(folio) !=
-	       folio_nr_pages(folio);
+	/* Expected refs: pagecache + mappings */
+	return folio_ref_count(folio) != folio_expected_ref_count(folio);
 }
 
 static void memfd_tag_pins(struct xa_state *xas)
-- 
2.43.0
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help