[PATCH v4 5/6] mm/huge_memory: get frozen folio refcount with folio_expected_ref_count()

From: Zi Yan
Date: Thu Jul 17 2025 - 22:31:17 EST


Instead of open coding the refcount calculation, use
folio_expected_ref_count() to calculate frozen folio refcount.
Because:

1. __folio_split() does not split a folio with PG_private, so no elevated
refcount from PG_private;
2. a frozen folio in __folio_split() is fully unmapped, so folio_mapcount()
in folio_expected_ref_count() is always 0;
3. (mapping || swap_cache) ? folio_nr_pages(folio) is taken care of by
folio_expected_ref_count() too.

Suggested-by: David Hildenbrand <david@xxxxxxxxxx>
Signed-off-by: Zi Yan <ziy@xxxxxxxxxx>
Acked-by: Balbir Singh <balbirs@xxxxxxxxxx>
Acked-by: David Hildenbrand <david@xxxxxxxxxx>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@xxxxxxxxxx>
---
mm/huge_memory.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index d6ff5e8c89d7..4db67970ae69 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3737,6 +3737,7 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
if (folio_ref_freeze(folio, 1 + extra_pins)) {
struct address_space *swap_cache = NULL;
struct lruvec *lruvec;
+ int expected_refs;

if (folio_order(folio) > 1 &&
!list_empty(&folio->_deferred_list)) {
@@ -3800,11 +3801,8 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
new_folio = next) {
next = folio_next(new_folio);

- folio_ref_unfreeze(
- new_folio,
- 1 + ((mapping || swap_cache) ?
- folio_nr_pages(new_folio) :
- 0));
+ expected_refs = folio_expected_ref_count(new_folio) + 1;
+ folio_ref_unfreeze(new_folio, expected_refs);

lru_add_split_folio(folio, new_folio, lruvec, list);

@@ -3834,8 +3832,8 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
* Otherwise, a parallel folio_try_get() can grab @folio
* and its caller can see stale page cache entries.
*/
- folio_ref_unfreeze(folio, 1 +
- ((mapping || swap_cache) ? folio_nr_pages(folio) : 0));
+ expected_refs = folio_expected_ref_count(folio) + 1;
+ folio_ref_unfreeze(folio, expected_refs);

unlock_page_lruvec(lruvec);

--
2.47.2