[PATCH 4/4] mm: Fix demotion gfp by preserving initial gfp reclaim policy

Alexandre Ghiti posted 4 patches 3 weeks, 6 days ago
[PATCH 4/4] mm: Fix demotion gfp by preserving initial gfp reclaim policy
Posted by Alexandre Ghiti 3 weeks, 6 days ago
When the src folio is a hugetlb page, htlb_modify_alloc_mask() will
unconditionally enable reclaim. But we have to preserve initial gfp
flags which, in the case of demotion, prevent direct reclaim.

Reported-by: Gregory Price <gourry@gourry.net>
Closes: https://lore.kernel.org/linux-mm/aXkfBF5bdnTZ7t7e@gourry-fedora-PF4VCD3F/
Fixes: 19fc7bed252c ("mm/migrate: introduce a standard migration target allocation function")
Cc: stable@vger.kernel.org
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
 mm/migrate.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index ee533a4d38db..d44a34d37007 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2169,13 +2169,13 @@ int migrate_pages(struct list_head *from, new_folio_t get_new_folio,
 struct folio *alloc_migration_target(struct folio *src, unsigned long private)
 {
 	struct migration_target_control *mtc;
-	gfp_t gfp_mask;
+	gfp_t gfp_mask, gfp_entry;
 	unsigned int order = 0;
 	int nid;
 	enum zone_type zidx;
 
 	mtc = (struct migration_target_control *)private;
-	gfp_mask = mtc->gfp_mask;
+	gfp_mask = gfp_entry = mtc->gfp_mask;
 	nid = mtc->nid;
 	if (nid == NUMA_NO_NODE)
 		nid = folio_nid(src);
@@ -2184,6 +2184,8 @@ struct folio *alloc_migration_target(struct folio *src, unsigned long private)
 		struct hstate *h = folio_hstate(src);
 
 		gfp_mask = htlb_modify_alloc_mask(h, gfp_mask);
+		gfp_mask = (gfp_mask & ~__GFP_RECLAIM) | (gfp_entry & __GFP_RECLAIM);
+
 		return alloc_hugetlb_folio_nodemask(h, nid,
 						mtc->nmask, gfp_mask,
 						htlb_allow_alloc_fallback(mtc->reason));
-- 
2.53.0