Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mm/page_alloc: free allocated PFNs if the range does not match
@ 2026-06-30  1:35 Zi Yan
  2026-06-30  2:06 ` Andrew Morton
  2026-06-30  7:44 ` Vlastimil Babka (SUSE)
  0 siblings, 2 replies; 7+ messages in thread
From: Zi Yan @ 2026-06-30  1:35 UTC (permalink / raw)
  To: Andrew Morton, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Mike Rapoport, Yu Zhao
  Cc: linux-mm, linux-kernel, Zi Yan, stable

When using __GFP_COMP in alloc_contig_frozen_range(), if the allocated
range does not match the requested one, the code errors out with EINVAL
without freeing the allocated PFNs and causes free page leaks. Fix it by
calling release_free_list() in the error path.

The issue is reported by Sashiko[1].

Fixes: e98337d11bbd ("mm/contig_alloc: support __GFP_COMP")
Link: https://sashiko.dev/#/patchset/20260628-keep-subpage-private-zero-at-free-v1-0-f4ce3930d10f@nvidia.com [1]
Signed-off-by: Zi Yan <ziy@nvidia.com>
Cc: stable@vger.kernel.org
---
Sashiko reports that if alloc_contig_range() with __GFP_COMP cannot
allocate PFNs with the given range, it returns EINVAL without freeing the
allocated PFNs and causes free memory leaks. Fix it by properly freeing the
isolated free pages and adjusting WARN message for clarification.
---
 mm/compaction.c | 2 +-
 mm/internal.h   | 1 +
 mm/page_alloc.c | 6 ++++--
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index b776f35ad020..4e3f06ff9304 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -88,7 +88,7 @@ static struct page *mark_allocated_noprof(struct page *page, unsigned int order,
 }
 #define mark_allocated(...)	alloc_hooks(mark_allocated_noprof(__VA_ARGS__))
 
-static unsigned long release_free_list(struct list_head *freepages)
+unsigned long release_free_list(struct list_head *freepages)
 {
 	int order;
 	unsigned long high_pfn = 0;
diff --git a/mm/internal.h b/mm/internal.h
index 181e79f1d6a2..6f9e5c2a6065 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -821,6 +821,7 @@ static inline void clear_zone_contiguous(struct zone *zone)
 }
 
 extern int __isolate_free_page(struct page *page, unsigned int order);
+extern unsigned long release_free_list(struct list_head *freepages);
 extern void __putback_isolated_page(struct page *page, unsigned int order,
 				    int mt);
 extern void memblock_free_pages(unsigned long pfn, unsigned int order);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ee902a468c2f..c1a35adb40f1 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -7235,9 +7235,11 @@ int alloc_contig_frozen_range_noprof(unsigned long start, unsigned long end,
 		check_new_pages(head, order);
 		prep_new_page(head, order, gfp_mask, 0);
 	} else {
+		release_free_list(cc.freepages);
 		ret = -EINVAL;
-		WARN(true, "PFN range: requested [%lu, %lu), allocated [%lu, %lu)\n",
-		     start, end, outer_start, outer_end);
+		WARN(true,
+		     "PFN range: allocated [%lu, %lu) does not match requested [%lu, %lu), freeing allocated PFNs\n",
+		     outer_start, outer_end, start, end);
 	}
 done:
 	undo_isolate_page_range(start, end);

---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260629-free-pfn-on-alloc-contig-range-error-path-acc001232468

Best regards,
-- 
Yan, Zi



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-06-30 15:07 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-30  1:35 [PATCH] mm/page_alloc: free allocated PFNs if the range does not match Zi Yan
2026-06-30  2:06 ` Andrew Morton
2026-06-30  2:23   ` Zi Yan
2026-06-30  7:44 ` Vlastimil Babka (SUSE)
2026-06-30 13:39   ` David Hildenbrand (Arm)
2026-06-30 14:47     ` Lance Yang
2026-06-30 15:06     ` Zi Yan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox