[PATCH v2 2/4] mm: allow shared folios to be promoted to a fast tier

From: Gregory Price

Date: Thu Sep 10 2026 - 20:30:28 EST


From: "Gregory Price (Meta)" <gourry@xxxxxxxxxx>

NUMA balancing rejects shared copy-on-write folios and executable
file folios mapped by multiple processes to avoid placement bouncing.
These checks also block promotion from slow memory.

Allow such folios to participate when moving from a slow tier to a fast
tier. Keep the existing restrictions for ordinary placement.

Fixes: c574bbe91703 ("NUMA balancing: optimize page placement for memory tiering system")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Gregory Price (Meta) <gourry@xxxxxxxxxx>
---
mm/mempolicy.c | 8 ++++++--
mm/migrate.c | 6 ++++--
2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index a082ccfa09ec..19b599bc2dd1 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -863,8 +863,12 @@ bool folio_can_map_prot_numa(struct folio *folio, struct vm_area_struct *vma,
if (!folio || folio_is_zone_device(folio) || folio_test_ksm(folio))
return false;

- /* Also skip shared copy-on-write folios */
- if (vma_is_cow_mapping(vma) && folio_maybe_mapped_shared(folio))
+ /*
+ * Shared copy-on-write folios are poor NUMA placement candidates, but
+ * a hot folio on a slow tier still needs a hint fault for promotion.
+ */
+ if (vma_is_cow_mapping(vma) && folio_maybe_mapped_shared(folio) &&
+ !folio_use_access_time(folio))
return false;

/* Folios are pinned and can't be migrated */
diff --git a/mm/migrate.c b/mm/migrate.c
index a369d0c95c38..afd9c97d2389 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2697,12 +2697,14 @@ int migrate_misplaced_folio_prepare(struct folio *folio,
/*
* Do not migrate file folios that are mapped in multiple
* processes with execute permissions as they are probably
- * shared libraries.
+ * shared libraries, unless this is a promotion from a slow tier.
*
* See folio_maybe_mapped_shared() on possible imprecision
* when we cannot easily detect if a folio is shared.
*/
- if ((vma->vm_flags & VM_EXEC) && folio_maybe_mapped_shared(folio))
+ if ((vma->vm_flags & VM_EXEC) &&
+ folio_maybe_mapped_shared(folio) &&
+ (!folio_use_access_time(folio) || !node_is_toptier(node)))
return -EACCES;

/*
--
2.55.0