[PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.

Zi Yan posted 6 patches 6 months, 2 weeks ago
There is a newer version of this series
[PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by Zi Yan 6 months, 2 weeks ago
migratetype is no longer overwritten during pageblock isolation,
start_isolate_page_range(), has_unmovable_pages(), and
set_migratetype_isolate() no longer need which migratetype to restore
during isolation failure.

For has_unmoable_pages(), it needs to know if the isolation is for CMA
allocation, so adding CMA_ALLOCATION to provide the information. At the
same time change isolation flags to enum pb_isolate_mode
(PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
isolation failures.

alloc_contig_range() no longer needs migratetype. Replace it with
enum acr_flags_t to tell if an allocation is for CMA. So does
__alloc_contig_migrate_range().

Signed-off-by: Zi Yan <ziy@nvidia.com>
---
 drivers/virtio/virtio_mem.c    |  2 +-
 include/linux/gfp.h            |  9 ++++-
 include/linux/page-isolation.h | 20 ++++++++--
 include/trace/events/kmem.h    | 14 ++++---
 mm/cma.c                       |  2 +-
 mm/memory_hotplug.c            |  6 +--
 mm/page_alloc.c                | 27 ++++++-------
 mm/page_isolation.c            | 70 +++++++++++++++-------------------
 8 files changed, 82 insertions(+), 68 deletions(-)

diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
index 56d0dbe62163..6bce70b139b2 100644
--- a/drivers/virtio/virtio_mem.c
+++ b/drivers/virtio/virtio_mem.c
@@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
 		if (atomic_read(&vm->config_changed))
 			return -EAGAIN;
 
-		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
+		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
 					GFP_KERNEL);
 		if (rc == -ENOMEM)
 			/* whoops, out of memory */
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index be160e8d8bcb..51990d571e3e 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
 extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
 
 #ifdef CONFIG_CONTIG_ALLOC
+
+enum acr_flags_t {
+	ACR_CMA,	// CMA allocation
+	ACR_OTHER,	// other allocation
+};
+
 /* The below functions must be run on a range from a single zone. */
 extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
-			      unsigned migratetype, gfp_t gfp_mask);
+				     enum acr_flags_t alloc_flags,
+				     gfp_t gfp_mask);
 #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
 
 extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index 7a681a49e73c..3e2f960e166c 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
 }
 #endif
 
-#define MEMORY_OFFLINE	0x1
-#define REPORT_FAILURE	0x2
+/*
+ * Pageblock isolation modes:
+ * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
+ *				 e.g., skip over PageHWPoison() pages and
+ *				 PageOffline() pages. Unmovable pages will be
+ *				 reported in this mode.
+ * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
+ * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
+ */
+enum pb_isolate_mode {
+	PB_ISOLATE_MODE_MEM_OFFLINE,
+	PB_ISOLATE_MODE_CMA_ALLOC,
+	PB_ISOLATE_MODE_OTHER,
+};
 
 void __meminit init_pageblock_migratetype(struct page *page,
 					  enum migratetype migratetype,
@@ -49,10 +61,10 @@ bool pageblock_isolate_and_move_free_pages(struct zone *zone, struct page *page)
 bool pageblock_unisolate_and_move_free_pages(struct zone *zone, struct page *page);
 
 int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
-			     int migratetype, int flags);
+			     enum pb_isolate_mode mode);
 
 void undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn);
 
 int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
-			int isol_flags);
+			enum pb_isolate_mode mode);
 #endif
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index f74925a6cf69..7c4e2e703a23 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -304,6 +304,7 @@ TRACE_EVENT(mm_page_alloc_extfrag,
 		__entry->change_ownership)
 );
 
+#ifdef CONFIG_CONTIG_ALLOC
 TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 
 	TP_PROTO(unsigned long start,
@@ -311,9 +312,9 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		 unsigned long nr_migrated,
 		 unsigned long nr_reclaimed,
 		 unsigned long nr_mapped,
-		 int migratetype),
+		 enum acr_flags_t alloc_flags),
 
-	TP_ARGS(start, end, nr_migrated, nr_reclaimed, nr_mapped, migratetype),
+	TP_ARGS(start, end, nr_migrated, nr_reclaimed, nr_mapped, alloc_flags),
 
 	TP_STRUCT__entry(
 		__field(unsigned long, start)
@@ -321,7 +322,7 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		__field(unsigned long, nr_migrated)
 		__field(unsigned long, nr_reclaimed)
 		__field(unsigned long, nr_mapped)
-		__field(int, migratetype)
+		__field(enum acr_flags_t, alloc_flags)
 	),
 
 	TP_fast_assign(
@@ -330,17 +331,18 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		__entry->nr_migrated = nr_migrated;
 		__entry->nr_reclaimed = nr_reclaimed;
 		__entry->nr_mapped = nr_mapped;
-		__entry->migratetype = migratetype;
+		__entry->alloc_flags = alloc_flags;
 	),
 
-	TP_printk("start=0x%lx end=0x%lx migratetype=%d nr_migrated=%lu nr_reclaimed=%lu nr_mapped=%lu",
+	TP_printk("start=0x%lx end=0x%lx alloc_flags=%d nr_migrated=%lu nr_reclaimed=%lu nr_mapped=%lu",
 		  __entry->start,
 		  __entry->end,
-		  __entry->migratetype,
+		  __entry->alloc_flags,
 		  __entry->nr_migrated,
 		  __entry->nr_reclaimed,
 		  __entry->nr_mapped)
 );
+#endif
 
 TRACE_EVENT(mm_setup_per_zone_wmarks,
 
diff --git a/mm/cma.c b/mm/cma.c
index 397567883a10..9ee8fad797bc 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -822,7 +822,7 @@ static int cma_range_alloc(struct cma *cma, struct cma_memrange *cmr,
 
 		pfn = cmr->base_pfn + (bitmap_no << cma->order_per_bit);
 		mutex_lock(&cma->alloc_mutex);
-		ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, gfp);
+		ret = alloc_contig_range(pfn, pfn + count, ACR_CMA, gfp);
 		mutex_unlock(&cma->alloc_mutex);
 		if (ret == 0) {
 			page = pfn_to_page(pfn);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index ab66acd3e6b3..19cad4460cee 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -2009,8 +2009,7 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages,
 
 	/* set above range as isolated */
 	ret = start_isolate_page_range(start_pfn, end_pfn,
-				       MIGRATE_MOVABLE,
-				       MEMORY_OFFLINE | REPORT_FAILURE);
+				       PB_ISOLATE_MODE_MEM_OFFLINE);
 	if (ret) {
 		reason = "failure to isolate range";
 		goto failed_removal_pcplists_disabled;
@@ -2069,7 +2068,8 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages,
 			goto failed_removal_isolated;
 		}
 
-		ret = test_pages_isolated(start_pfn, end_pfn, MEMORY_OFFLINE);
+		ret = test_pages_isolated(start_pfn, end_pfn,
+					  PB_ISOLATE_MODE_MEM_OFFLINE);
 
 	} while (ret);
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a248faf30ee0..c28e5c2105e5 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6697,11 +6697,12 @@ static void alloc_contig_dump_pages(struct list_head *page_list)
 
 /*
  * [start, end) must belong to a single zone.
- * @migratetype: using migratetype to filter the type of migration in
+ * @alloc_flags: using acr_flags_t to filter the type of migration in
  *		trace_mm_alloc_contig_migrate_range_info.
  */
 static int __alloc_contig_migrate_range(struct compact_control *cc,
-		unsigned long start, unsigned long end, int migratetype)
+					unsigned long start, unsigned long end,
+					enum acr_flags_t alloc_flags)
 {
 	/* This function is based on compact_zone() from compaction.c. */
 	unsigned int nr_reclaimed;
@@ -6773,7 +6774,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
 		putback_movable_pages(&cc->migratepages);
 	}
 
-	trace_mm_alloc_contig_migrate_range_info(start, end, migratetype,
+	trace_mm_alloc_contig_migrate_range_info(start, end, alloc_flags,
 						 total_migrated,
 						 total_reclaimed,
 						 total_mapped);
@@ -6844,10 +6845,7 @@ static int __alloc_contig_verify_gfp_mask(gfp_t gfp_mask, gfp_t *gfp_cc_mask)
  * alloc_contig_range() -- tries to allocate given range of pages
  * @start:	start PFN to allocate
  * @end:	one-past-the-last PFN to allocate
- * @migratetype:	migratetype of the underlying pageblocks (either
- *			#MIGRATE_MOVABLE or #MIGRATE_CMA).  All pageblocks
- *			in range must have the same migratetype and it must
- *			be either of the two.
+ * @alloc_flags:	allocation information
  * @gfp_mask:	GFP mask. Node/zone/placement hints are ignored; only some
  *		action and reclaim modifiers are supported. Reclaim modifiers
  *		control allocation behavior during compaction/migration/reclaim.
@@ -6864,7 +6862,7 @@ static int __alloc_contig_verify_gfp_mask(gfp_t gfp_mask, gfp_t *gfp_cc_mask)
  * need to be freed with free_contig_range().
  */
 int alloc_contig_range_noprof(unsigned long start, unsigned long end,
-		       unsigned migratetype, gfp_t gfp_mask)
+			      enum acr_flags_t alloc_flags, gfp_t gfp_mask)
 {
 	unsigned long outer_start, outer_end;
 	int ret = 0;
@@ -6879,6 +6877,9 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 		.alloc_contig = true,
 	};
 	INIT_LIST_HEAD(&cc.migratepages);
+	enum pb_isolate_mode mode = (alloc_flags == ACR_CMA) ?
+					    PB_ISOLATE_MODE_CMA_ALLOC :
+					    PB_ISOLATE_MODE_OTHER;
 
 	gfp_mask = current_gfp_context(gfp_mask);
 	if (__alloc_contig_verify_gfp_mask(gfp_mask, (gfp_t *)&cc.gfp_mask))
@@ -6905,7 +6906,7 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 	 * put back to page allocator so that buddy can use them.
 	 */
 
-	ret = start_isolate_page_range(start, end, migratetype, 0);
+	ret = start_isolate_page_range(start, end, mode);
 	if (ret)
 		goto done;
 
@@ -6921,7 +6922,7 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 	 * allocated.  So, if we fall through be sure to clear ret so that
 	 * -EBUSY is not accidentally used or returned to caller.
 	 */
-	ret = __alloc_contig_migrate_range(&cc, start, end, migratetype);
+	ret = __alloc_contig_migrate_range(&cc, start, end, alloc_flags);
 	if (ret && ret != -EBUSY)
 		goto done;
 
@@ -6955,7 +6956,7 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 	outer_start = find_large_buddy(start);
 
 	/* Make sure the range is really isolated. */
-	if (test_pages_isolated(outer_start, end, 0)) {
+	if (test_pages_isolated(outer_start, end, mode)) {
 		ret = -EBUSY;
 		goto done;
 	}
@@ -6998,8 +6999,8 @@ static int __alloc_contig_pages(unsigned long start_pfn,
 {
 	unsigned long end_pfn = start_pfn + nr_pages;
 
-	return alloc_contig_range_noprof(start_pfn, end_pfn, MIGRATE_MOVABLE,
-				   gfp_mask);
+	return alloc_contig_range_noprof(start_pfn, end_pfn, ACR_OTHER,
+					 gfp_mask);
 }
 
 static bool pfn_range_valid_contig(struct zone *z, unsigned long start_pfn,
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index 1edfef408faf..ece3bfc56bcd 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -31,7 +31,7 @@
  *
  */
 static struct page *has_unmovable_pages(unsigned long start_pfn, unsigned long end_pfn,
-				int migratetype, int flags)
+				enum pb_isolate_mode mode)
 {
 	struct page *page = pfn_to_page(start_pfn);
 	struct zone *zone = page_zone(page);
@@ -46,7 +46,7 @@ static struct page *has_unmovable_pages(unsigned long start_pfn, unsigned long e
 		 * isolate CMA pageblocks even when they are not movable in fact
 		 * so consider them movable here.
 		 */
-		if (is_migrate_cma(migratetype))
+		if (mode == PB_ISOLATE_MODE_CMA_ALLOC)
 			return NULL;
 
 		return page;
@@ -117,7 +117,7 @@ static struct page *has_unmovable_pages(unsigned long start_pfn, unsigned long e
 		 * The HWPoisoned page may be not in buddy system, and
 		 * page_count() is not 0.
 		 */
-		if ((flags & MEMORY_OFFLINE) && PageHWPoison(page))
+		if ((mode == PB_ISOLATE_MODE_MEM_OFFLINE) && PageHWPoison(page))
 			continue;
 
 		/*
@@ -130,7 +130,7 @@ static struct page *has_unmovable_pages(unsigned long start_pfn, unsigned long e
 		 * move these pages that still have a reference count > 0.
 		 * (false negatives in this function only)
 		 */
-		if ((flags & MEMORY_OFFLINE) && PageOffline(page))
+		if ((mode == PB_ISOLATE_MODE_MEM_OFFLINE) && PageOffline(page))
 			continue;
 
 		if (__PageMovable(page) || PageLRU(page))
@@ -151,7 +151,7 @@ static struct page *has_unmovable_pages(unsigned long start_pfn, unsigned long e
  * present in [start_pfn, end_pfn). The pageblock must intersect with
  * [start_pfn, end_pfn).
  */
-static int set_migratetype_isolate(struct page *page, int migratetype, int isol_flags,
+static int set_migratetype_isolate(struct page *page, enum pb_isolate_mode mode,
 			unsigned long start_pfn, unsigned long end_pfn)
 {
 	struct zone *zone = page_zone(page);
@@ -186,7 +186,7 @@ static int set_migratetype_isolate(struct page *page, int migratetype, int isol_
 				  end_pfn);
 
 	unmovable = has_unmovable_pages(check_unmovable_start, check_unmovable_end,
-			migratetype, isol_flags);
+			mode);
 	if (!unmovable) {
 		if (!pageblock_isolate_and_move_free_pages(zone, page)) {
 			spin_unlock_irqrestore(&zone->lock, flags);
@@ -198,7 +198,7 @@ static int set_migratetype_isolate(struct page *page, int migratetype, int isol_
 	}
 
 	spin_unlock_irqrestore(&zone->lock, flags);
-	if (isol_flags & REPORT_FAILURE) {
+	if (mode == PB_ISOLATE_MODE_MEM_OFFLINE) {
 		/*
 		 * printk() with zone->lock held will likely trigger a
 		 * lockdep splat, so defer it here.
@@ -292,11 +292,10 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages)
  * isolate_single_pageblock() -- tries to isolate a pageblock that might be
  * within a free or in-use page.
  * @boundary_pfn:		pageblock-aligned pfn that a page might cross
- * @flags:			isolation flags
+ * @mode:			isolation mode
  * @isolate_before:	isolate the pageblock before the boundary_pfn
  * @skip_isolation:	the flag to skip the pageblock isolation in second
  *			isolate_single_pageblock()
- * @migratetype:	migrate type to set in error recovery.
  *
  * Free and in-use pages can be as big as MAX_PAGE_ORDER and contain more than one
  * pageblock. When not all pageblocks within a page are isolated at the same
@@ -311,8 +310,9 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages)
  * either. The function handles this by splitting the free page or migrating
  * the in-use page then splitting the free page.
  */
-static int isolate_single_pageblock(unsigned long boundary_pfn, int flags,
-		bool isolate_before, bool skip_isolation, int migratetype)
+static int isolate_single_pageblock(unsigned long boundary_pfn,
+			enum pb_isolate_mode mode, bool isolate_before,
+			bool skip_isolation)
 {
 	unsigned long start_pfn;
 	unsigned long isolate_pageblock;
@@ -338,12 +338,11 @@ static int isolate_single_pageblock(unsigned long boundary_pfn, int flags,
 				      zone->zone_start_pfn);
 
 	if (skip_isolation) {
-		int mt __maybe_unused = get_pageblock_migratetype(pfn_to_page(isolate_pageblock));
-
-		VM_BUG_ON(!is_migrate_isolate(mt));
+		VM_BUG_ON(!get_pageblock_isolate(pfn_to_page(isolate_pageblock)));
 	} else {
-		ret = set_migratetype_isolate(pfn_to_page(isolate_pageblock), migratetype,
-				flags, isolate_pageblock, isolate_pageblock + pageblock_nr_pages);
+		ret = set_migratetype_isolate(pfn_to_page(isolate_pageblock),
+				mode, isolate_pageblock,
+				isolate_pageblock + pageblock_nr_pages);
 
 		if (ret)
 			return ret;
@@ -441,14 +440,7 @@ static int isolate_single_pageblock(unsigned long boundary_pfn, int flags,
  * start_isolate_page_range() - mark page range MIGRATE_ISOLATE
  * @start_pfn:		The first PFN of the range to be isolated.
  * @end_pfn:		The last PFN of the range to be isolated.
- * @migratetype:	Migrate type to set in error recovery.
- * @flags:		The following flags are allowed (they can be combined in
- *			a bit mask)
- *			MEMORY_OFFLINE - isolate to offline (!allocate) memory
- *					 e.g., skip over PageHWPoison() pages
- *					 and PageOffline() pages.
- *			REPORT_FAILURE - report details about the failure to
- *			isolate the range
+ * @mode:		isolation mode
  *
  * Making page-allocation-type to be MIGRATE_ISOLATE means free pages in
  * the range will never be allocated. Any free pages and pages freed in the
@@ -481,7 +473,7 @@ static int isolate_single_pageblock(unsigned long boundary_pfn, int flags,
  * Return: 0 on success and -EBUSY if any part of range cannot be isolated.
  */
 int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
-			     int migratetype, int flags)
+			     enum pb_isolate_mode mode)
 {
 	unsigned long pfn;
 	struct page *page;
@@ -492,8 +484,8 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
 	bool skip_isolation = false;
 
 	/* isolate [isolate_start, isolate_start + pageblock_nr_pages) pageblock */
-	ret = isolate_single_pageblock(isolate_start, flags, false,
-			skip_isolation, migratetype);
+	ret = isolate_single_pageblock(isolate_start, mode, false,
+			skip_isolation);
 	if (ret)
 		return ret;
 
@@ -501,8 +493,7 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
 		skip_isolation = true;
 
 	/* isolate [isolate_end - pageblock_nr_pages, isolate_end) pageblock */
-	ret = isolate_single_pageblock(isolate_end, flags, true,
-			skip_isolation, migratetype);
+	ret = isolate_single_pageblock(isolate_end, mode, true, skip_isolation);
 	if (ret) {
 		unset_migratetype_isolate(pfn_to_page(isolate_start));
 		return ret;
@@ -513,8 +504,8 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
 	     pfn < isolate_end - pageblock_nr_pages;
 	     pfn += pageblock_nr_pages) {
 		page = __first_valid_page(pfn, pageblock_nr_pages);
-		if (page && set_migratetype_isolate(page, migratetype, flags,
-					start_pfn, end_pfn)) {
+		if (page && set_migratetype_isolate(page, mode, start_pfn,
+					end_pfn)) {
 			undo_isolate_page_range(isolate_start, pfn);
 			unset_migratetype_isolate(
 				pfn_to_page(isolate_end - pageblock_nr_pages));
@@ -556,7 +547,7 @@ void undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
  */
 static unsigned long
 __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
-				  int flags)
+				  enum pb_isolate_mode mode)
 {
 	struct page *page;
 
@@ -569,11 +560,12 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
 			 * simple way to verify that as VM_BUG_ON(), though.
 			 */
 			pfn += 1 << buddy_order(page);
-		else if ((flags & MEMORY_OFFLINE) && PageHWPoison(page))
+		else if ((mode == PB_ISOLATE_MODE_MEM_OFFLINE) &&
+			 PageHWPoison(page))
 			/* A HWPoisoned page cannot be also PageBuddy */
 			pfn++;
-		else if ((flags & MEMORY_OFFLINE) && PageOffline(page) &&
-			 !page_count(page))
+		else if ((mode == PB_ISOLATE_MODE_MEM_OFFLINE) &&
+			 PageOffline(page) && !page_count(page))
 			/*
 			 * The responsible driver agreed to skip PageOffline()
 			 * pages when offlining memory by dropping its
@@ -591,11 +583,11 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
  * test_pages_isolated - check if pageblocks in range are isolated
  * @start_pfn:		The first PFN of the isolated range
  * @end_pfn:		The first PFN *after* the isolated range
- * @isol_flags:		Testing mode flags
+ * @mode:		Testing mode
  *
  * This tests if all in the specified range are free.
  *
- * If %MEMORY_OFFLINE is specified in @flags, it will consider
+ * If %PB_ISOLATE_MODE_MEM_OFFLINE specified in @mode, it will consider
  * poisoned and offlined pages free as well.
  *
  * Caller must ensure the requested range doesn't span zones.
@@ -603,7 +595,7 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
  * Returns 0 if true, -EBUSY if one or more pages are in use.
  */
 int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
-			int isol_flags)
+			enum pb_isolate_mode mode)
 {
 	unsigned long pfn, flags;
 	struct page *page;
@@ -639,7 +631,7 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
 	/* Check all pages are free or marked as ISOLATED */
 	zone = page_zone(page);
 	spin_lock_irqsave(&zone->lock, flags);
-	pfn = __test_page_isolated_in_pageblock(start_pfn, end_pfn, isol_flags);
+	pfn = __test_page_isolated_in_pageblock(start_pfn, end_pfn, mode);
 	spin_unlock_irqrestore(&zone->lock, flags);
 
 	ret = pfn < end_pfn ? -EBUSY : 0;
-- 
2.47.2
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by David Hildenbrand 6 months, 2 weeks ago
On 30.05.25 18:22, Zi Yan wrote:
> migratetype is no longer overwritten during pageblock isolation,
> start_isolate_page_range(), has_unmovable_pages(), and
> set_migratetype_isolate() no longer need which migratetype to restore
> during isolation failure.
> 
> For has_unmoable_pages(), it needs to know if the isolation is for CMA
> allocation, so adding CMA_ALLOCATION to provide the information. At the
> same time change isolation flags to enum pb_isolate_mode
> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
> isolation failures.
> 
> alloc_contig_range() no longer needs migratetype. Replace it with
> enum acr_flags_t to tell if an allocation is for CMA. So does
> __alloc_contig_migrate_range().
> 
> Signed-off-by: Zi Yan <ziy@nvidia.com>
> ---
>   drivers/virtio/virtio_mem.c    |  2 +-
>   include/linux/gfp.h            |  9 ++++-
>   include/linux/page-isolation.h | 20 ++++++++--
>   include/trace/events/kmem.h    | 14 ++++---
>   mm/cma.c                       |  2 +-
>   mm/memory_hotplug.c            |  6 +--
>   mm/page_alloc.c                | 27 ++++++-------
>   mm/page_isolation.c            | 70 +++++++++++++++-------------------
>   8 files changed, 82 insertions(+), 68 deletions(-)
> 
> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
> index 56d0dbe62163..6bce70b139b2 100644
> --- a/drivers/virtio/virtio_mem.c
> +++ b/drivers/virtio/virtio_mem.c
> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>   		if (atomic_read(&vm->config_changed))
>   			return -EAGAIN;
>   
> -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>   					GFP_KERNEL);
>   		if (rc == -ENOMEM)
>   			/* whoops, out of memory */
> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
> index be160e8d8bcb..51990d571e3e 100644
> --- a/include/linux/gfp.h
> +++ b/include/linux/gfp.h
> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>   extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>   
>   #ifdef CONFIG_CONTIG_ALLOC
> +
> +enum acr_flags_t {
> +	ACR_CMA,	// CMA allocation
> +	ACR_OTHER,	// other allocation
> +};

Hm, enum != flags.

If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied 
if not set.

And ACR_CMA would then have to be "1" etc.

> +
>   /* The below functions must be run on a range from a single zone. */
>   extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
> -			      unsigned migratetype, gfp_t gfp_mask);
> +				     enum acr_flags_t alloc_flags,
> +				     gfp_t gfp_mask);
>   #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>   
>   extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
> index 7a681a49e73c..3e2f960e166c 100644
> --- a/include/linux/page-isolation.h
> +++ b/include/linux/page-isolation.h
> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>   }
>   #endif
>   
> -#define MEMORY_OFFLINE	0x1
> -#define REPORT_FAILURE	0x2
> +/*
> + * Pageblock isolation modes:
> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
> + *				 e.g., skip over PageHWPoison() pages and
> + *				 PageOffline() pages. Unmovable pages will be
> + *				 reported in this mode.
> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
> + */
> +enum pb_isolate_mode {
> +	PB_ISOLATE_MODE_MEM_OFFLINE,
> +	PB_ISOLATE_MODE_CMA_ALLOC,
> +	PB_ISOLATE_MODE_OTHER,
> +};

It's late on friady, but it looks like we are duplicating things here.

Let me think about that once my brain is recharged :)

-- 
Cheers,

David / dhildenb
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by Zi Yan 6 months, 2 weeks ago
On 30 May 2025, at 15:56, David Hildenbrand wrote:

> On 30.05.25 18:22, Zi Yan wrote:
>> migratetype is no longer overwritten during pageblock isolation,
>> start_isolate_page_range(), has_unmovable_pages(), and
>> set_migratetype_isolate() no longer need which migratetype to restore
>> during isolation failure.
>>
>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>> same time change isolation flags to enum pb_isolate_mode
>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>> isolation failures.
>>
>> alloc_contig_range() no longer needs migratetype. Replace it with
>> enum acr_flags_t to tell if an allocation is for CMA. So does
>> __alloc_contig_migrate_range().
>>
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>> ---
>>   drivers/virtio/virtio_mem.c    |  2 +-
>>   include/linux/gfp.h            |  9 ++++-
>>   include/linux/page-isolation.h | 20 ++++++++--
>>   include/trace/events/kmem.h    | 14 ++++---
>>   mm/cma.c                       |  2 +-
>>   mm/memory_hotplug.c            |  6 +--
>>   mm/page_alloc.c                | 27 ++++++-------
>>   mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>   8 files changed, 82 insertions(+), 68 deletions(-)
>>
>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>> index 56d0dbe62163..6bce70b139b2 100644
>> --- a/drivers/virtio/virtio_mem.c
>> +++ b/drivers/virtio/virtio_mem.c
>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>   		if (atomic_read(&vm->config_changed))
>>   			return -EAGAIN;
>>  -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>   					GFP_KERNEL);
>>   		if (rc == -ENOMEM)
>>   			/* whoops, out of memory */
>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>> index be160e8d8bcb..51990d571e3e 100644
>> --- a/include/linux/gfp.h
>> +++ b/include/linux/gfp.h
>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>   extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>    #ifdef CONFIG_CONTIG_ALLOC
>> +
>> +enum acr_flags_t {
>> +	ACR_CMA,	// CMA allocation
>> +	ACR_OTHER,	// other allocation
>> +};
>
> Hm, enum != flags.
>
> If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied if not set.
>
> And ACR_CMA would then have to be "1" etc.

I have a fixup to change acr_flags_t to acr_mode.

>
>> +
>>   /* The below functions must be run on a range from a single zone. */
>>   extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>> -			      unsigned migratetype, gfp_t gfp_mask);
>> +				     enum acr_flags_t alloc_flags,
>> +				     gfp_t gfp_mask);
>>   #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>>    extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
>> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
>> index 7a681a49e73c..3e2f960e166c 100644
>> --- a/include/linux/page-isolation.h
>> +++ b/include/linux/page-isolation.h
>> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>>   }
>>   #endif
>>  -#define MEMORY_OFFLINE	0x1
>> -#define REPORT_FAILURE	0x2
>> +/*
>> + * Pageblock isolation modes:
>> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
>> + *				 e.g., skip over PageHWPoison() pages and
>> + *				 PageOffline() pages. Unmovable pages will be
>> + *				 reported in this mode.
>> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
>> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
>> + */
>> +enum pb_isolate_mode {
>> +	PB_ISOLATE_MODE_MEM_OFFLINE,
>> +	PB_ISOLATE_MODE_CMA_ALLOC,
>> +	PB_ISOLATE_MODE_OTHER,
>> +};
>
> It's late on friady, but it looks like we are duplicating things here.
>
> Let me think about that once my brain is recharged :)

Sure. Take your time.

Best Regards,
Yan, Zi
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by David Hildenbrand 6 months, 2 weeks ago
On 30.05.25 21:58, Zi Yan wrote:
> On 30 May 2025, at 15:56, David Hildenbrand wrote:
> 
>> On 30.05.25 18:22, Zi Yan wrote:
>>> migratetype is no longer overwritten during pageblock isolation,
>>> start_isolate_page_range(), has_unmovable_pages(), and
>>> set_migratetype_isolate() no longer need which migratetype to restore
>>> during isolation failure.
>>>
>>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>>> same time change isolation flags to enum pb_isolate_mode
>>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>>> isolation failures.
>>>
>>> alloc_contig_range() no longer needs migratetype. Replace it with
>>> enum acr_flags_t to tell if an allocation is for CMA. So does
>>> __alloc_contig_migrate_range().
>>>
>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>> ---
>>>    drivers/virtio/virtio_mem.c    |  2 +-
>>>    include/linux/gfp.h            |  9 ++++-
>>>    include/linux/page-isolation.h | 20 ++++++++--
>>>    include/trace/events/kmem.h    | 14 ++++---
>>>    mm/cma.c                       |  2 +-
>>>    mm/memory_hotplug.c            |  6 +--
>>>    mm/page_alloc.c                | 27 ++++++-------
>>>    mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>>    8 files changed, 82 insertions(+), 68 deletions(-)
>>>
>>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>>> index 56d0dbe62163..6bce70b139b2 100644
>>> --- a/drivers/virtio/virtio_mem.c
>>> +++ b/drivers/virtio/virtio_mem.c
>>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>>    		if (atomic_read(&vm->config_changed))
>>>    			return -EAGAIN;
>>>   -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>>    					GFP_KERNEL);
>>>    		if (rc == -ENOMEM)
>>>    			/* whoops, out of memory */
>>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>>> index be160e8d8bcb..51990d571e3e 100644
>>> --- a/include/linux/gfp.h
>>> +++ b/include/linux/gfp.h
>>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>>    extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>>     #ifdef CONFIG_CONTIG_ALLOC
>>> +
>>> +enum acr_flags_t {
>>> +	ACR_CMA,	// CMA allocation
>>> +	ACR_OTHER,	// other allocation
>>> +};
>>
>> Hm, enum != flags.
>>
>> If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied if not set.
>>
>> And ACR_CMA would then have to be "1" etc.
> 
> I have a fixup to change acr_flags_t to acr_mode.
> 
>>
>>> +
>>>    /* The below functions must be run on a range from a single zone. */
>>>    extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>>> -			      unsigned migratetype, gfp_t gfp_mask);
>>> +				     enum acr_flags_t alloc_flags,
>>> +				     gfp_t gfp_mask);
>>>    #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>>>     extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
>>> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
>>> index 7a681a49e73c..3e2f960e166c 100644
>>> --- a/include/linux/page-isolation.h
>>> +++ b/include/linux/page-isolation.h
>>> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>>>    }
>>>    #endif
>>>   -#define MEMORY_OFFLINE	0x1
>>> -#define REPORT_FAILURE	0x2
>>> +/*
>>> + * Pageblock isolation modes:
>>> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
>>> + *				 e.g., skip over PageHWPoison() pages and
>>> + *				 PageOffline() pages. Unmovable pages will be
>>> + *				 reported in this mode.
>>> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
>>> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
>>> + */
>>> +enum pb_isolate_mode {
>>> +	PB_ISOLATE_MODE_MEM_OFFLINE,
>>> +	PB_ISOLATE_MODE_CMA_ALLOC,
>>> +	PB_ISOLATE_MODE_OTHER,
>>> +};
>>
>> It's late on friady, but it looks like we are duplicating things here.
>>
>> Let me think about that once my brain is recharged :)
> 
> Sure. Take your time.

Could we abstract both settings and use a single one? Then, we could 
simply reject if MEM_OFFLINE is passed into alloc_contig_range().

alloc_contig_pages and page isolation, hmmmm, MEM_OFFLINE is kind-of an 
allocation. CMA is an allocation.

Just an idea, not sure ...

-- 
Cheers,

David / dhildenb
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by Zi Yan 6 months, 2 weeks ago
On 30 May 2025, at 16:08, David Hildenbrand wrote:

> On 30.05.25 21:58, Zi Yan wrote:
>> On 30 May 2025, at 15:56, David Hildenbrand wrote:
>>
>>> On 30.05.25 18:22, Zi Yan wrote:
>>>> migratetype is no longer overwritten during pageblock isolation,
>>>> start_isolate_page_range(), has_unmovable_pages(), and
>>>> set_migratetype_isolate() no longer need which migratetype to restore
>>>> during isolation failure.
>>>>
>>>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>>>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>>>> same time change isolation flags to enum pb_isolate_mode
>>>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>>>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>>>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>>>> isolation failures.
>>>>
>>>> alloc_contig_range() no longer needs migratetype. Replace it with
>>>> enum acr_flags_t to tell if an allocation is for CMA. So does
>>>> __alloc_contig_migrate_range().
>>>>
>>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>>> ---
>>>>    drivers/virtio/virtio_mem.c    |  2 +-
>>>>    include/linux/gfp.h            |  9 ++++-
>>>>    include/linux/page-isolation.h | 20 ++++++++--
>>>>    include/trace/events/kmem.h    | 14 ++++---
>>>>    mm/cma.c                       |  2 +-
>>>>    mm/memory_hotplug.c            |  6 +--
>>>>    mm/page_alloc.c                | 27 ++++++-------
>>>>    mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>>>    8 files changed, 82 insertions(+), 68 deletions(-)
>>>>
>>>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>>>> index 56d0dbe62163..6bce70b139b2 100644
>>>> --- a/drivers/virtio/virtio_mem.c
>>>> +++ b/drivers/virtio/virtio_mem.c
>>>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>>>    		if (atomic_read(&vm->config_changed))
>>>>    			return -EAGAIN;
>>>>   -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>>>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>>>    					GFP_KERNEL);
>>>>    		if (rc == -ENOMEM)
>>>>    			/* whoops, out of memory */
>>>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>>>> index be160e8d8bcb..51990d571e3e 100644
>>>> --- a/include/linux/gfp.h
>>>> +++ b/include/linux/gfp.h
>>>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>>>    extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>>>     #ifdef CONFIG_CONTIG_ALLOC
>>>> +
>>>> +enum acr_flags_t {
>>>> +	ACR_CMA,	// CMA allocation
>>>> +	ACR_OTHER,	// other allocation
>>>> +};
>>>
>>> Hm, enum != flags.
>>>
>>> If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied if not set.
>>>
>>> And ACR_CMA would then have to be "1" etc.
>>
>> I have a fixup to change acr_flags_t to acr_mode.
>>
>>>
>>>> +
>>>>    /* The below functions must be run on a range from a single zone. */
>>>>    extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>>>> -			      unsigned migratetype, gfp_t gfp_mask);
>>>> +				     enum acr_flags_t alloc_flags,
>>>> +				     gfp_t gfp_mask);
>>>>    #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>>>>     extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
>>>> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
>>>> index 7a681a49e73c..3e2f960e166c 100644
>>>> --- a/include/linux/page-isolation.h
>>>> +++ b/include/linux/page-isolation.h
>>>> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>>>>    }
>>>>    #endif
>>>>   -#define MEMORY_OFFLINE	0x1
>>>> -#define REPORT_FAILURE	0x2
>>>> +/*
>>>> + * Pageblock isolation modes:
>>>> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
>>>> + *				 e.g., skip over PageHWPoison() pages and
>>>> + *				 PageOffline() pages. Unmovable pages will be
>>>> + *				 reported in this mode.
>>>> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
>>>> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
>>>> + */
>>>> +enum pb_isolate_mode {
>>>> +	PB_ISOLATE_MODE_MEM_OFFLINE,
>>>> +	PB_ISOLATE_MODE_CMA_ALLOC,
>>>> +	PB_ISOLATE_MODE_OTHER,
>>>> +};
>>>
>>> It's late on friady, but it looks like we are duplicating things here.
>>>
>>> Let me think about that once my brain is recharged :)
>>
>> Sure. Take your time.
>
> Could we abstract both settings and use a single one? Then, we could simply reject if MEM_OFFLINE is passed into alloc_contig_range().
>
> alloc_contig_pages and page isolation, hmmmm, MEM_OFFLINE is kind-of an allocation. CMA is an allocation.
>
> Just an idea, not sure ...

I think so.

This is the fixup of removing acr_flags_t. It is on top of the original
patch. Take your time. I guess I will send V7 with all fixups next week.

The one strange part is that in virtio_mem_fake_offline,
PB_ISOLATE_MODE_OTHER is used instead of PB_ISOLATE_MODE_MEM_OFFLINE.
I guess you do not want to report failures there.

From b4bed6ec8bd07df40952bff2009905ae4093b3be Mon Sep 17 00:00:00 2001
From: Zi Yan <ziy@nvidia.com>
Date: Fri, 30 May 2025 13:58:11 -0400
Subject: [PATCH] remove acr_flags_t and use enum pb_isolate_mode instead.

Signed-off-by: Zi Yan <ziy@nvidia.com>
---
 drivers/virtio/virtio_mem.c    |  4 ++--
 include/linux/gfp.h            | 19 ++++++++++++++-----
 include/linux/page-isolation.h | 15 ---------------
 include/trace/events/kmem.h    | 12 ++++++------
 mm/cma.c                       |  3 ++-
 mm/page_alloc.c                | 24 ++++++++++++------------
 6 files changed, 36 insertions(+), 41 deletions(-)

diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
index 6bce70b139b2..535680a54ff5 100644
--- a/drivers/virtio/virtio_mem.c
+++ b/drivers/virtio/virtio_mem.c
@@ -1243,8 +1243,8 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
 		if (atomic_read(&vm->config_changed))
 			return -EAGAIN;

-		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
-					GFP_KERNEL);
+		rc = alloc_contig_range(pfn, pfn + nr_pages,
+					PB_ISOLATE_MODE_OTHER, GFP_KERNEL);
 		if (rc == -ENOMEM)
 			/* whoops, out of memory */
 			return rc;
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 51990d571e3e..17b92888d6de 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -423,15 +423,24 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
 extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);

 #ifdef CONFIG_CONTIG_ALLOC
-
-enum acr_flags_t {
-	ACR_CMA,	// CMA allocation
-	ACR_OTHER,	// other allocation
+/*
+ * Pageblock isolation modes:
+ * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
+ *				 e.g., skip over PageHWPoison() pages and
+ *				 PageOffline() pages. Unmovable pages will be
+ *				 reported in this mode.
+ * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
+ * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
+ */
+enum pb_isolate_mode {
+	PB_ISOLATE_MODE_MEM_OFFLINE,
+	PB_ISOLATE_MODE_CMA_ALLOC,
+	PB_ISOLATE_MODE_OTHER,
 };

 /* The below functions must be run on a range from a single zone. */
 extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
-				     enum acr_flags_t alloc_flags,
+				     enum pb_isolate_mode isol_mode,
 				     gfp_t gfp_mask);
 #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))

diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index 3e2f960e166c..7ed60a339a02 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -38,21 +38,6 @@ static inline void set_pageblock_isolate(struct page *page)
 }
 #endif

-/*
- * Pageblock isolation modes:
- * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
- *				 e.g., skip over PageHWPoison() pages and
- *				 PageOffline() pages. Unmovable pages will be
- *				 reported in this mode.
- * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
- * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
- */
-enum pb_isolate_mode {
-	PB_ISOLATE_MODE_MEM_OFFLINE,
-	PB_ISOLATE_MODE_CMA_ALLOC,
-	PB_ISOLATE_MODE_OTHER,
-};
-
 void __meminit init_pageblock_migratetype(struct page *page,
 					  enum migratetype migratetype,
 					  bool isolate);
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 7c4e2e703a23..e0bcbc43a548 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -312,9 +312,9 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		 unsigned long nr_migrated,
 		 unsigned long nr_reclaimed,
 		 unsigned long nr_mapped,
-		 enum acr_flags_t alloc_flags),
+		 enum pb_isolate_mode isol_mode),

-	TP_ARGS(start, end, nr_migrated, nr_reclaimed, nr_mapped, alloc_flags),
+	TP_ARGS(start, end, nr_migrated, nr_reclaimed, nr_mapped, isol_mode),

 	TP_STRUCT__entry(
 		__field(unsigned long, start)
@@ -322,7 +322,7 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		__field(unsigned long, nr_migrated)
 		__field(unsigned long, nr_reclaimed)
 		__field(unsigned long, nr_mapped)
-		__field(enum acr_flags_t, alloc_flags)
+		__field(enum pb_isolate_mode, isol_mode)
 	),

 	TP_fast_assign(
@@ -331,13 +331,13 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		__entry->nr_migrated = nr_migrated;
 		__entry->nr_reclaimed = nr_reclaimed;
 		__entry->nr_mapped = nr_mapped;
-		__entry->alloc_flags = alloc_flags;
+		__entry->isol_mode = isol_mode;
 	),

-	TP_printk("start=0x%lx end=0x%lx alloc_flags=%d nr_migrated=%lu nr_reclaimed=%lu nr_mapped=%lu",
+	TP_printk("start=0x%lx end=0x%lx isol_mode=%d nr_migrated=%lu nr_reclaimed=%lu nr_mapped=%lu",
 		  __entry->start,
 		  __entry->end,
-		  __entry->alloc_flags,
+		  __entry->isol_mode,
 		  __entry->nr_migrated,
 		  __entry->nr_reclaimed,
 		  __entry->nr_mapped)
diff --git a/mm/cma.c b/mm/cma.c
index 9ee8fad797bc..23aa35193122 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -822,7 +822,8 @@ static int cma_range_alloc(struct cma *cma, struct cma_memrange *cmr,

 		pfn = cmr->base_pfn + (bitmap_no << cma->order_per_bit);
 		mutex_lock(&cma->alloc_mutex);
-		ret = alloc_contig_range(pfn, pfn + count, ACR_CMA, gfp);
+		ret = alloc_contig_range(pfn, pfn + count,
+					 PB_ISOLATE_MODE_CMA_ALLOC, gfp);
 		mutex_unlock(&cma->alloc_mutex);
 		if (ret == 0) {
 			page = pfn_to_page(pfn);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index dd761f5e6310..619b1a9de9b7 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6696,12 +6696,12 @@ static void alloc_contig_dump_pages(struct list_head *page_list)

 /*
  * [start, end) must belong to a single zone.
- * @alloc_flags: using acr_flags_t to filter the type of migration in
+ * @isol_mode: using pb_isolate_mode filter the type of migration in
  *		trace_mm_alloc_contig_migrate_range_info.
  */
 static int __alloc_contig_migrate_range(struct compact_control *cc,
 					unsigned long start, unsigned long end,
-					enum acr_flags_t alloc_flags)
+					enum pb_isolate_mode isol_mode)
 {
 	/* This function is based on compact_zone() from compaction.c. */
 	unsigned int nr_reclaimed;
@@ -6773,7 +6773,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
 		putback_movable_pages(&cc->migratepages);
 	}

-	trace_mm_alloc_contig_migrate_range_info(start, end, alloc_flags,
+	trace_mm_alloc_contig_migrate_range_info(start, end, isol_mode,
 						 total_migrated,
 						 total_reclaimed,
 						 total_mapped);
@@ -6844,7 +6844,7 @@ static int __alloc_contig_verify_gfp_mask(gfp_t gfp_mask, gfp_t *gfp_cc_mask)
  * alloc_contig_range() -- tries to allocate given range of pages
  * @start:	start PFN to allocate
  * @end:	one-past-the-last PFN to allocate
- * @alloc_flags:	allocation information
+ * @isol_mode:	allocation information used for pageblock isolation
  * @gfp_mask:	GFP mask. Node/zone/placement hints are ignored; only some
  *		action and reclaim modifiers are supported. Reclaim modifiers
  *		control allocation behavior during compaction/migration/reclaim.
@@ -6861,7 +6861,7 @@ static int __alloc_contig_verify_gfp_mask(gfp_t gfp_mask, gfp_t *gfp_cc_mask)
  * need to be freed with free_contig_range().
  */
 int alloc_contig_range_noprof(unsigned long start, unsigned long end,
-			      enum acr_flags_t alloc_flags, gfp_t gfp_mask)
+			      enum pb_isolate_mode isol_mode, gfp_t gfp_mask)
 {
 	unsigned long outer_start, outer_end;
 	int ret = 0;
@@ -6876,9 +6876,9 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 		.alloc_contig = true,
 	};
 	INIT_LIST_HEAD(&cc.migratepages);
-	enum pb_isolate_mode mode = (alloc_flags == ACR_CMA) ?
-					    PB_ISOLATE_MODE_CMA_ALLOC :
-					    PB_ISOLATE_MODE_OTHER;
+
+	if (isol_mode == PB_ISOLATE_MODE_MEM_OFFLINE)
+		return -EINVAL;

 	gfp_mask = current_gfp_context(gfp_mask);
 	if (__alloc_contig_verify_gfp_mask(gfp_mask, (gfp_t *)&cc.gfp_mask))
@@ -6905,7 +6905,7 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 	 * put back to page allocator so that buddy can use them.
 	 */

-	ret = start_isolate_page_range(start, end, mode);
+	ret = start_isolate_page_range(start, end, isol_mode);
 	if (ret)
 		goto done;

@@ -6921,7 +6921,7 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 	 * allocated.  So, if we fall through be sure to clear ret so that
 	 * -EBUSY is not accidentally used or returned to caller.
 	 */
-	ret = __alloc_contig_migrate_range(&cc, start, end, alloc_flags);
+	ret = __alloc_contig_migrate_range(&cc, start, end, isol_mode);
 	if (ret && ret != -EBUSY)
 		goto done;

@@ -6955,7 +6955,7 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 	outer_start = find_large_buddy(start);

 	/* Make sure the range is really isolated. */
-	if (test_pages_isolated(outer_start, end, mode)) {
+	if (test_pages_isolated(outer_start, end, isol_mode)) {
 		ret = -EBUSY;
 		goto done;
 	}
@@ -6998,7 +6998,7 @@ static int __alloc_contig_pages(unsigned long start_pfn,
 {
 	unsigned long end_pfn = start_pfn + nr_pages;

-	return alloc_contig_range_noprof(start_pfn, end_pfn, ACR_OTHER,
+	return alloc_contig_range_noprof(start_pfn, end_pfn, PB_ISOLATE_MODE_OTHER,
 					 gfp_mask);
 }

-- 
2.47.2



Best Regards,
Yan, Zi
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by David Hildenbrand 6 months, 2 weeks ago
On 30.05.25 22:46, Zi Yan wrote:
> On 30 May 2025, at 16:08, David Hildenbrand wrote:
> 
>> On 30.05.25 21:58, Zi Yan wrote:
>>> On 30 May 2025, at 15:56, David Hildenbrand wrote:
>>>
>>>> On 30.05.25 18:22, Zi Yan wrote:
>>>>> migratetype is no longer overwritten during pageblock isolation,
>>>>> start_isolate_page_range(), has_unmovable_pages(), and
>>>>> set_migratetype_isolate() no longer need which migratetype to restore
>>>>> during isolation failure.
>>>>>
>>>>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>>>>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>>>>> same time change isolation flags to enum pb_isolate_mode
>>>>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>>>>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>>>>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>>>>> isolation failures.
>>>>>
>>>>> alloc_contig_range() no longer needs migratetype. Replace it with
>>>>> enum acr_flags_t to tell if an allocation is for CMA. So does
>>>>> __alloc_contig_migrate_range().
>>>>>
>>>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>>>> ---
>>>>>     drivers/virtio/virtio_mem.c    |  2 +-
>>>>>     include/linux/gfp.h            |  9 ++++-
>>>>>     include/linux/page-isolation.h | 20 ++++++++--
>>>>>     include/trace/events/kmem.h    | 14 ++++---
>>>>>     mm/cma.c                       |  2 +-
>>>>>     mm/memory_hotplug.c            |  6 +--
>>>>>     mm/page_alloc.c                | 27 ++++++-------
>>>>>     mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>>>>     8 files changed, 82 insertions(+), 68 deletions(-)
>>>>>
>>>>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>>>>> index 56d0dbe62163..6bce70b139b2 100644
>>>>> --- a/drivers/virtio/virtio_mem.c
>>>>> +++ b/drivers/virtio/virtio_mem.c
>>>>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>>>>     		if (atomic_read(&vm->config_changed))
>>>>>     			return -EAGAIN;
>>>>>    -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>>>>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>>>>     					GFP_KERNEL);
>>>>>     		if (rc == -ENOMEM)
>>>>>     			/* whoops, out of memory */
>>>>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>>>>> index be160e8d8bcb..51990d571e3e 100644
>>>>> --- a/include/linux/gfp.h
>>>>> +++ b/include/linux/gfp.h
>>>>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>>>>     extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>>>>      #ifdef CONFIG_CONTIG_ALLOC
>>>>> +
>>>>> +enum acr_flags_t {
>>>>> +	ACR_CMA,	// CMA allocation
>>>>> +	ACR_OTHER,	// other allocation
>>>>> +};
>>>>
>>>> Hm, enum != flags.
>>>>
>>>> If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied if not set.
>>>>
>>>> And ACR_CMA would then have to be "1" etc.
>>>
>>> I have a fixup to change acr_flags_t to acr_mode.
>>>
>>>>
>>>>> +
>>>>>     /* The below functions must be run on a range from a single zone. */
>>>>>     extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>>>>> -			      unsigned migratetype, gfp_t gfp_mask);
>>>>> +				     enum acr_flags_t alloc_flags,
>>>>> +				     gfp_t gfp_mask);
>>>>>     #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>>>>>      extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
>>>>> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
>>>>> index 7a681a49e73c..3e2f960e166c 100644
>>>>> --- a/include/linux/page-isolation.h
>>>>> +++ b/include/linux/page-isolation.h
>>>>> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>>>>>     }
>>>>>     #endif
>>>>>    -#define MEMORY_OFFLINE	0x1
>>>>> -#define REPORT_FAILURE	0x2
>>>>> +/*
>>>>> + * Pageblock isolation modes:
>>>>> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
>>>>> + *				 e.g., skip over PageHWPoison() pages and
>>>>> + *				 PageOffline() pages. Unmovable pages will be
>>>>> + *				 reported in this mode.
>>>>> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
>>>>> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
>>>>> + */
>>>>> +enum pb_isolate_mode {
>>>>> +	PB_ISOLATE_MODE_MEM_OFFLINE,
>>>>> +	PB_ISOLATE_MODE_CMA_ALLOC,
>>>>> +	PB_ISOLATE_MODE_OTHER,
>>>>> +};
>>>>
>>>> It's late on friady, but it looks like we are duplicating things here.
>>>>
>>>> Let me think about that once my brain is recharged :)
>>>
>>> Sure. Take your time.
>>
>> Could we abstract both settings and use a single one? Then, we could simply reject if MEM_OFFLINE is passed into alloc_contig_range().
>>
>> alloc_contig_pages and page isolation, hmmmm, MEM_OFFLINE is kind-of an allocation. CMA is an allocation.
>>
>> Just an idea, not sure ...
> 
> I think so.
> 
> This is the fixup of removing acr_flags_t. It is on top of the original
> patch. Take your time. I guess I will send V7 with all fixups next week.

Only wondering if we should rename "pb_isolate_mode" to something more 
abstract, that covers both use cases clearer.

Hmmm.

> 
> The one strange part is that in virtio_mem_fake_offline,
> PB_ISOLATE_MODE_OTHER is used instead of PB_ISOLATE_MODE_MEM_OFFLINE.
> I guess you do not want to report failures there.

That's the right thing to do. It's not ordinary memory offlining code.

Thanks and enjoy the weekend!

-- 
Cheers,

David / dhildenb
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by Zi Yan 6 months, 2 weeks ago
On 30 May 2025, at 16:55, David Hildenbrand wrote:

> On 30.05.25 22:46, Zi Yan wrote:
>> On 30 May 2025, at 16:08, David Hildenbrand wrote:
>>
>>> On 30.05.25 21:58, Zi Yan wrote:
>>>> On 30 May 2025, at 15:56, David Hildenbrand wrote:
>>>>
>>>>> On 30.05.25 18:22, Zi Yan wrote:
>>>>>> migratetype is no longer overwritten during pageblock isolation,
>>>>>> start_isolate_page_range(), has_unmovable_pages(), and
>>>>>> set_migratetype_isolate() no longer need which migratetype to restore
>>>>>> during isolation failure.
>>>>>>
>>>>>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>>>>>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>>>>>> same time change isolation flags to enum pb_isolate_mode
>>>>>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>>>>>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>>>>>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>>>>>> isolation failures.
>>>>>>
>>>>>> alloc_contig_range() no longer needs migratetype. Replace it with
>>>>>> enum acr_flags_t to tell if an allocation is for CMA. So does
>>>>>> __alloc_contig_migrate_range().
>>>>>>
>>>>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>>>>> ---
>>>>>>     drivers/virtio/virtio_mem.c    |  2 +-
>>>>>>     include/linux/gfp.h            |  9 ++++-
>>>>>>     include/linux/page-isolation.h | 20 ++++++++--
>>>>>>     include/trace/events/kmem.h    | 14 ++++---
>>>>>>     mm/cma.c                       |  2 +-
>>>>>>     mm/memory_hotplug.c            |  6 +--
>>>>>>     mm/page_alloc.c                | 27 ++++++-------
>>>>>>     mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>>>>>     8 files changed, 82 insertions(+), 68 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>>>>>> index 56d0dbe62163..6bce70b139b2 100644
>>>>>> --- a/drivers/virtio/virtio_mem.c
>>>>>> +++ b/drivers/virtio/virtio_mem.c
>>>>>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>>>>>     		if (atomic_read(&vm->config_changed))
>>>>>>     			return -EAGAIN;
>>>>>>    -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>>>>>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>>>>>     					GFP_KERNEL);
>>>>>>     		if (rc == -ENOMEM)
>>>>>>     			/* whoops, out of memory */
>>>>>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>>>>>> index be160e8d8bcb..51990d571e3e 100644
>>>>>> --- a/include/linux/gfp.h
>>>>>> +++ b/include/linux/gfp.h
>>>>>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>>>>>     extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>>>>>      #ifdef CONFIG_CONTIG_ALLOC
>>>>>> +
>>>>>> +enum acr_flags_t {
>>>>>> +	ACR_CMA,	// CMA allocation
>>>>>> +	ACR_OTHER,	// other allocation
>>>>>> +};
>>>>>
>>>>> Hm, enum != flags.
>>>>>
>>>>> If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied if not set.
>>>>>
>>>>> And ACR_CMA would then have to be "1" etc.
>>>>
>>>> I have a fixup to change acr_flags_t to acr_mode.
>>>>
>>>>>
>>>>>> +
>>>>>>     /* The below functions must be run on a range from a single zone. */
>>>>>>     extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>>>>>> -			      unsigned migratetype, gfp_t gfp_mask);
>>>>>> +				     enum acr_flags_t alloc_flags,
>>>>>> +				     gfp_t gfp_mask);
>>>>>>     #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>>>>>>      extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
>>>>>> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
>>>>>> index 7a681a49e73c..3e2f960e166c 100644
>>>>>> --- a/include/linux/page-isolation.h
>>>>>> +++ b/include/linux/page-isolation.h
>>>>>> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>>>>>>     }
>>>>>>     #endif
>>>>>>    -#define MEMORY_OFFLINE	0x1
>>>>>> -#define REPORT_FAILURE	0x2
>>>>>> +/*
>>>>>> + * Pageblock isolation modes:
>>>>>> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
>>>>>> + *				 e.g., skip over PageHWPoison() pages and
>>>>>> + *				 PageOffline() pages. Unmovable pages will be
>>>>>> + *				 reported in this mode.
>>>>>> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
>>>>>> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
>>>>>> + */
>>>>>> +enum pb_isolate_mode {
>>>>>> +	PB_ISOLATE_MODE_MEM_OFFLINE,
>>>>>> +	PB_ISOLATE_MODE_CMA_ALLOC,
>>>>>> +	PB_ISOLATE_MODE_OTHER,
>>>>>> +};
>>>>>
>>>>> It's late on friady, but it looks like we are duplicating things here.
>>>>>
>>>>> Let me think about that once my brain is recharged :)
>>>>
>>>> Sure. Take your time.
>>>
>>> Could we abstract both settings and use a single one? Then, we could simply reject if MEM_OFFLINE is passed into alloc_contig_range().
>>>
>>> alloc_contig_pages and page isolation, hmmmm, MEM_OFFLINE is kind-of an allocation. CMA is an allocation.
>>>
>>> Just an idea, not sure ...
>>
>> I think so.
>>
>> This is the fixup of removing acr_flags_t. It is on top of the original
>> patch. Take your time. I guess I will send V7 with all fixups next week.
>
> Only wondering if we should rename "pb_isolate_mode" to something more abstract, that covers both use cases clearer.
>
> Hmmm.

It is specifying the purpose of either alloc_contig_range() or
test_pages_isolated(), but these two use cases do not have high level
connection AFAICT, except that pageblock isolation is involved
in the implementation. Let’s postpone the naming to the future.
As we discussed, we have two TODOs: 1) remove MIGRATE_ISOLATE,
and 2) simplify alloc_contig_range() to isolate the whole range in
one shot, then do migration. Probably we can think about naming at
that time. :)

>
>>
>> The one strange part is that in virtio_mem_fake_offline,
>> PB_ISOLATE_MODE_OTHER is used instead of PB_ISOLATE_MODE_MEM_OFFLINE.
>> I guess you do not want to report failures there.
>
> That's the right thing to do. It's not ordinary memory offlining code.

Got it.


Best Regards,
Yan, Zi
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by David Hildenbrand 6 months, 2 weeks ago
On 02.06.25 16:18, Zi Yan wrote:
> On 30 May 2025, at 16:55, David Hildenbrand wrote:
> 
>> On 30.05.25 22:46, Zi Yan wrote:
>>> On 30 May 2025, at 16:08, David Hildenbrand wrote:
>>>
>>>> On 30.05.25 21:58, Zi Yan wrote:
>>>>> On 30 May 2025, at 15:56, David Hildenbrand wrote:
>>>>>
>>>>>> On 30.05.25 18:22, Zi Yan wrote:
>>>>>>> migratetype is no longer overwritten during pageblock isolation,
>>>>>>> start_isolate_page_range(), has_unmovable_pages(), and
>>>>>>> set_migratetype_isolate() no longer need which migratetype to restore
>>>>>>> during isolation failure.
>>>>>>>
>>>>>>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>>>>>>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>>>>>>> same time change isolation flags to enum pb_isolate_mode
>>>>>>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>>>>>>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>>>>>>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>>>>>>> isolation failures.
>>>>>>>
>>>>>>> alloc_contig_range() no longer needs migratetype. Replace it with
>>>>>>> enum acr_flags_t to tell if an allocation is for CMA. So does
>>>>>>> __alloc_contig_migrate_range().
>>>>>>>
>>>>>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>>>>>> ---
>>>>>>>      drivers/virtio/virtio_mem.c    |  2 +-
>>>>>>>      include/linux/gfp.h            |  9 ++++-
>>>>>>>      include/linux/page-isolation.h | 20 ++++++++--
>>>>>>>      include/trace/events/kmem.h    | 14 ++++---
>>>>>>>      mm/cma.c                       |  2 +-
>>>>>>>      mm/memory_hotplug.c            |  6 +--
>>>>>>>      mm/page_alloc.c                | 27 ++++++-------
>>>>>>>      mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>>>>>>      8 files changed, 82 insertions(+), 68 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>>>>>>> index 56d0dbe62163..6bce70b139b2 100644
>>>>>>> --- a/drivers/virtio/virtio_mem.c
>>>>>>> +++ b/drivers/virtio/virtio_mem.c
>>>>>>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>>>>>>      		if (atomic_read(&vm->config_changed))
>>>>>>>      			return -EAGAIN;
>>>>>>>     -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>>>>>>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>>>>>>      					GFP_KERNEL);
>>>>>>>      		if (rc == -ENOMEM)
>>>>>>>      			/* whoops, out of memory */
>>>>>>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>>>>>>> index be160e8d8bcb..51990d571e3e 100644
>>>>>>> --- a/include/linux/gfp.h
>>>>>>> +++ b/include/linux/gfp.h
>>>>>>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>>>>>>      extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>>>>>>       #ifdef CONFIG_CONTIG_ALLOC
>>>>>>> +
>>>>>>> +enum acr_flags_t {
>>>>>>> +	ACR_CMA,	// CMA allocation
>>>>>>> +	ACR_OTHER,	// other allocation
>>>>>>> +};
>>>>>>
>>>>>> Hm, enum != flags.
>>>>>>
>>>>>> If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied if not set.
>>>>>>
>>>>>> And ACR_CMA would then have to be "1" etc.
>>>>>
>>>>> I have a fixup to change acr_flags_t to acr_mode.
>>>>>
>>>>>>
>>>>>>> +
>>>>>>>      /* The below functions must be run on a range from a single zone. */
>>>>>>>      extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>>>>>>> -			      unsigned migratetype, gfp_t gfp_mask);
>>>>>>> +				     enum acr_flags_t alloc_flags,
>>>>>>> +				     gfp_t gfp_mask);
>>>>>>>      #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>>>>>>>       extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
>>>>>>> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
>>>>>>> index 7a681a49e73c..3e2f960e166c 100644
>>>>>>> --- a/include/linux/page-isolation.h
>>>>>>> +++ b/include/linux/page-isolation.h
>>>>>>> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>>>>>>>      }
>>>>>>>      #endif
>>>>>>>     -#define MEMORY_OFFLINE	0x1
>>>>>>> -#define REPORT_FAILURE	0x2
>>>>>>> +/*
>>>>>>> + * Pageblock isolation modes:
>>>>>>> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
>>>>>>> + *				 e.g., skip over PageHWPoison() pages and
>>>>>>> + *				 PageOffline() pages. Unmovable pages will be
>>>>>>> + *				 reported in this mode.
>>>>>>> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
>>>>>>> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
>>>>>>> + */
>>>>>>> +enum pb_isolate_mode {
>>>>>>> +	PB_ISOLATE_MODE_MEM_OFFLINE,
>>>>>>> +	PB_ISOLATE_MODE_CMA_ALLOC,
>>>>>>> +	PB_ISOLATE_MODE_OTHER,
>>>>>>> +};
>>>>>>
>>>>>> It's late on friady, but it looks like we are duplicating things here.
>>>>>>
>>>>>> Let me think about that once my brain is recharged :)
>>>>>
>>>>> Sure. Take your time.
>>>>
>>>> Could we abstract both settings and use a single one? Then, we could simply reject if MEM_OFFLINE is passed into alloc_contig_range().
>>>>
>>>> alloc_contig_pages and page isolation, hmmmm, MEM_OFFLINE is kind-of an allocation. CMA is an allocation.
>>>>
>>>> Just an idea, not sure ...
>>>
>>> I think so.
>>>
>>> This is the fixup of removing acr_flags_t. It is on top of the original
>>> patch. Take your time. I guess I will send V7 with all fixups next week.
>>
>> Only wondering if we should rename "pb_isolate_mode" to something more abstract, that covers both use cases clearer.
>>
>> Hmmm.
> 
> It is specifying the purpose of either alloc_contig_range() or
> test_pages_isolated(), but these two use cases do not have high level
> connection AFAICT.

Hm, then maybe just keep it as is for now, and have the translation from 
ACP -> isolatetype.

isolation modes should probably be an enum.

acp might long-term benefit from flags, where we would essentially for 
now only have a single flag ("ACP_CMA").

-- 
Cheers,

David / dhildenb
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by Zi Yan 6 months, 2 weeks ago
On 2 Jun 2025, at 12:25, David Hildenbrand wrote:

> On 02.06.25 16:18, Zi Yan wrote:
>> On 30 May 2025, at 16:55, David Hildenbrand wrote:
>>
>>> On 30.05.25 22:46, Zi Yan wrote:
>>>> On 30 May 2025, at 16:08, David Hildenbrand wrote:
>>>>
>>>>> On 30.05.25 21:58, Zi Yan wrote:
>>>>>> On 30 May 2025, at 15:56, David Hildenbrand wrote:
>>>>>>
>>>>>>> On 30.05.25 18:22, Zi Yan wrote:
>>>>>>>> migratetype is no longer overwritten during pageblock isolation,
>>>>>>>> start_isolate_page_range(), has_unmovable_pages(), and
>>>>>>>> set_migratetype_isolate() no longer need which migratetype to restore
>>>>>>>> during isolation failure.
>>>>>>>>
>>>>>>>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>>>>>>>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>>>>>>>> same time change isolation flags to enum pb_isolate_mode
>>>>>>>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>>>>>>>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>>>>>>>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>>>>>>>> isolation failures.
>>>>>>>>
>>>>>>>> alloc_contig_range() no longer needs migratetype. Replace it with
>>>>>>>> enum acr_flags_t to tell if an allocation is for CMA. So does
>>>>>>>> __alloc_contig_migrate_range().
>>>>>>>>
>>>>>>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>>>>>>> ---
>>>>>>>>      drivers/virtio/virtio_mem.c    |  2 +-
>>>>>>>>      include/linux/gfp.h            |  9 ++++-
>>>>>>>>      include/linux/page-isolation.h | 20 ++++++++--
>>>>>>>>      include/trace/events/kmem.h    | 14 ++++---
>>>>>>>>      mm/cma.c                       |  2 +-
>>>>>>>>      mm/memory_hotplug.c            |  6 +--
>>>>>>>>      mm/page_alloc.c                | 27 ++++++-------
>>>>>>>>      mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>>>>>>>      8 files changed, 82 insertions(+), 68 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>>>>>>>> index 56d0dbe62163..6bce70b139b2 100644
>>>>>>>> --- a/drivers/virtio/virtio_mem.c
>>>>>>>> +++ b/drivers/virtio/virtio_mem.c
>>>>>>>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>>>>>>>      		if (atomic_read(&vm->config_changed))
>>>>>>>>      			return -EAGAIN;
>>>>>>>>     -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>>>>>>>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>>>>>>>      					GFP_KERNEL);
>>>>>>>>      		if (rc == -ENOMEM)
>>>>>>>>      			/* whoops, out of memory */
>>>>>>>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>>>>>>>> index be160e8d8bcb..51990d571e3e 100644
>>>>>>>> --- a/include/linux/gfp.h
>>>>>>>> +++ b/include/linux/gfp.h
>>>>>>>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>>>>>>>      extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>>>>>>>       #ifdef CONFIG_CONTIG_ALLOC
>>>>>>>> +
>>>>>>>> +enum acr_flags_t {
>>>>>>>> +	ACR_CMA,	// CMA allocation
>>>>>>>> +	ACR_OTHER,	// other allocation
>>>>>>>> +};
>>>>>>>
>>>>>>> Hm, enum != flags.
>>>>>>>
>>>>>>> If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied if not set.
>>>>>>>
>>>>>>> And ACR_CMA would then have to be "1" etc.
>>>>>>
>>>>>> I have a fixup to change acr_flags_t to acr_mode.
>>>>>>
>>>>>>>
>>>>>>>> +
>>>>>>>>      /* The below functions must be run on a range from a single zone. */
>>>>>>>>      extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>>>>>>>> -			      unsigned migratetype, gfp_t gfp_mask);
>>>>>>>> +				     enum acr_flags_t alloc_flags,
>>>>>>>> +				     gfp_t gfp_mask);
>>>>>>>>      #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>>>>>>>>       extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
>>>>>>>> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
>>>>>>>> index 7a681a49e73c..3e2f960e166c 100644
>>>>>>>> --- a/include/linux/page-isolation.h
>>>>>>>> +++ b/include/linux/page-isolation.h
>>>>>>>> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>>>>>>>>      }
>>>>>>>>      #endif
>>>>>>>>     -#define MEMORY_OFFLINE	0x1
>>>>>>>> -#define REPORT_FAILURE	0x2
>>>>>>>> +/*
>>>>>>>> + * Pageblock isolation modes:
>>>>>>>> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
>>>>>>>> + *				 e.g., skip over PageHWPoison() pages and
>>>>>>>> + *				 PageOffline() pages. Unmovable pages will be
>>>>>>>> + *				 reported in this mode.
>>>>>>>> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
>>>>>>>> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
>>>>>>>> + */
>>>>>>>> +enum pb_isolate_mode {
>>>>>>>> +	PB_ISOLATE_MODE_MEM_OFFLINE,
>>>>>>>> +	PB_ISOLATE_MODE_CMA_ALLOC,
>>>>>>>> +	PB_ISOLATE_MODE_OTHER,
>>>>>>>> +};
>>>>>>>
>>>>>>> It's late on friady, but it looks like we are duplicating things here.
>>>>>>>
>>>>>>> Let me think about that once my brain is recharged :)
>>>>>>
>>>>>> Sure. Take your time.
>>>>>
>>>>> Could we abstract both settings and use a single one? Then, we could simply reject if MEM_OFFLINE is passed into alloc_contig_range().
>>>>>
>>>>> alloc_contig_pages and page isolation, hmmmm, MEM_OFFLINE is kind-of an allocation. CMA is an allocation.
>>>>>
>>>>> Just an idea, not sure ...
>>>>
>>>> I think so.
>>>>
>>>> This is the fixup of removing acr_flags_t. It is on top of the original
>>>> patch. Take your time. I guess I will send V7 with all fixups next week.
>>>
>>> Only wondering if we should rename "pb_isolate_mode" to something more abstract, that covers both use cases clearer.
>>>
>>> Hmmm.
>>
>> It is specifying the purpose of either alloc_contig_range() or
>> test_pages_isolated(), but these two use cases do not have high level
>> connection AFAICT.
>
> Hm, then maybe just keep it as is for now, and have the translation from ACP -> isolatetype.
>
> isolation modes should probably be an enum.
>
> acp might long-term benefit from flags, where we would essentially for now only have a single flag ("ACP_CMA").

OK, let me send a fixup to my V7.

Best Regards,
Yan, Zi
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by David Hildenbrand 6 months, 2 weeks ago
On 02.06.25 18:27, Zi Yan wrote:
> On 2 Jun 2025, at 12:25, David Hildenbrand wrote:
> 
>> On 02.06.25 16:18, Zi Yan wrote:
>>> On 30 May 2025, at 16:55, David Hildenbrand wrote:
>>>
>>>> On 30.05.25 22:46, Zi Yan wrote:
>>>>> On 30 May 2025, at 16:08, David Hildenbrand wrote:
>>>>>
>>>>>> On 30.05.25 21:58, Zi Yan wrote:
>>>>>>> On 30 May 2025, at 15:56, David Hildenbrand wrote:
>>>>>>>
>>>>>>>> On 30.05.25 18:22, Zi Yan wrote:
>>>>>>>>> migratetype is no longer overwritten during pageblock isolation,
>>>>>>>>> start_isolate_page_range(), has_unmovable_pages(), and
>>>>>>>>> set_migratetype_isolate() no longer need which migratetype to restore
>>>>>>>>> during isolation failure.
>>>>>>>>>
>>>>>>>>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>>>>>>>>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>>>>>>>>> same time change isolation flags to enum pb_isolate_mode
>>>>>>>>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>>>>>>>>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>>>>>>>>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>>>>>>>>> isolation failures.
>>>>>>>>>
>>>>>>>>> alloc_contig_range() no longer needs migratetype. Replace it with
>>>>>>>>> enum acr_flags_t to tell if an allocation is for CMA. So does
>>>>>>>>> __alloc_contig_migrate_range().
>>>>>>>>>
>>>>>>>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>>>>>>>> ---
>>>>>>>>>       drivers/virtio/virtio_mem.c    |  2 +-
>>>>>>>>>       include/linux/gfp.h            |  9 ++++-
>>>>>>>>>       include/linux/page-isolation.h | 20 ++++++++--
>>>>>>>>>       include/trace/events/kmem.h    | 14 ++++---
>>>>>>>>>       mm/cma.c                       |  2 +-
>>>>>>>>>       mm/memory_hotplug.c            |  6 +--
>>>>>>>>>       mm/page_alloc.c                | 27 ++++++-------
>>>>>>>>>       mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>>>>>>>>       8 files changed, 82 insertions(+), 68 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>>>>>>>>> index 56d0dbe62163..6bce70b139b2 100644
>>>>>>>>> --- a/drivers/virtio/virtio_mem.c
>>>>>>>>> +++ b/drivers/virtio/virtio_mem.c
>>>>>>>>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>>>>>>>>       		if (atomic_read(&vm->config_changed))
>>>>>>>>>       			return -EAGAIN;
>>>>>>>>>      -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>>>>>>>>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>>>>>>>>       					GFP_KERNEL);
>>>>>>>>>       		if (rc == -ENOMEM)
>>>>>>>>>       			/* whoops, out of memory */
>>>>>>>>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>>>>>>>>> index be160e8d8bcb..51990d571e3e 100644
>>>>>>>>> --- a/include/linux/gfp.h
>>>>>>>>> +++ b/include/linux/gfp.h
>>>>>>>>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>>>>>>>>       extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>>>>>>>>        #ifdef CONFIG_CONTIG_ALLOC
>>>>>>>>> +
>>>>>>>>> +enum acr_flags_t {
>>>>>>>>> +	ACR_CMA,	// CMA allocation
>>>>>>>>> +	ACR_OTHER,	// other allocation
>>>>>>>>> +};
>>>>>>>>
>>>>>>>> Hm, enum != flags.
>>>>>>>>
>>>>>>>> If you want to use flags, then just have ACR_CMA. ACR_OTHER is implied if not set.
>>>>>>>>
>>>>>>>> And ACR_CMA would then have to be "1" etc.
>>>>>>>
>>>>>>> I have a fixup to change acr_flags_t to acr_mode.
>>>>>>>
>>>>>>>>
>>>>>>>>> +
>>>>>>>>>       /* The below functions must be run on a range from a single zone. */
>>>>>>>>>       extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>>>>>>>>> -			      unsigned migratetype, gfp_t gfp_mask);
>>>>>>>>> +				     enum acr_flags_t alloc_flags,
>>>>>>>>> +				     gfp_t gfp_mask);
>>>>>>>>>       #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>>>>>>>>>        extern struct page *alloc_contig_pages_noprof(unsigned long nr_pages, gfp_t gfp_mask,
>>>>>>>>> diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
>>>>>>>>> index 7a681a49e73c..3e2f960e166c 100644
>>>>>>>>> --- a/include/linux/page-isolation.h
>>>>>>>>> +++ b/include/linux/page-isolation.h
>>>>>>>>> @@ -38,8 +38,20 @@ static inline void set_pageblock_isolate(struct page *page)
>>>>>>>>>       }
>>>>>>>>>       #endif
>>>>>>>>>      -#define MEMORY_OFFLINE	0x1
>>>>>>>>> -#define REPORT_FAILURE	0x2
>>>>>>>>> +/*
>>>>>>>>> + * Pageblock isolation modes:
>>>>>>>>> + * PB_ISOLATE_MODE_MEM_OFFLINE - isolate to offline (!allocate) memory
>>>>>>>>> + *				 e.g., skip over PageHWPoison() pages and
>>>>>>>>> + *				 PageOffline() pages. Unmovable pages will be
>>>>>>>>> + *				 reported in this mode.
>>>>>>>>> + * PB_ISOLATE_MODE_CMA_ALLOC   - isolate for CMA allocations
>>>>>>>>> + * PB_ISOLATE_MODE_OTHER       - isolate for other purposes
>>>>>>>>> + */
>>>>>>>>> +enum pb_isolate_mode {
>>>>>>>>> +	PB_ISOLATE_MODE_MEM_OFFLINE,
>>>>>>>>> +	PB_ISOLATE_MODE_CMA_ALLOC,
>>>>>>>>> +	PB_ISOLATE_MODE_OTHER,
>>>>>>>>> +};
>>>>>>>>
>>>>>>>> It's late on friady, but it looks like we are duplicating things here.
>>>>>>>>
>>>>>>>> Let me think about that once my brain is recharged :)
>>>>>>>
>>>>>>> Sure. Take your time.
>>>>>>
>>>>>> Could we abstract both settings and use a single one? Then, we could simply reject if MEM_OFFLINE is passed into alloc_contig_range().
>>>>>>
>>>>>> alloc_contig_pages and page isolation, hmmmm, MEM_OFFLINE is kind-of an allocation. CMA is an allocation.
>>>>>>
>>>>>> Just an idea, not sure ...
>>>>>
>>>>> I think so.
>>>>>
>>>>> This is the fixup of removing acr_flags_t. It is on top of the original
>>>>> patch. Take your time. I guess I will send V7 with all fixups next week.
>>>>
>>>> Only wondering if we should rename "pb_isolate_mode" to something more abstract, that covers both use cases clearer.
>>>>
>>>> Hmmm.
>>>
>>> It is specifying the purpose of either alloc_contig_range() or
>>> test_pages_isolated(), but these two use cases do not have high level
>>> connection AFAICT.
>>
>> Hm, then maybe just keep it as is for now, and have the translation from ACP -> isolatetype.
>>
>> isolation modes should probably be an enum.
>>
>> acp might long-term benefit from flags, where we would essentially for now only have a single flag ("ACP_CMA").
> 
> OK, let me send a fixup to my V7.

Oh, I saw that v7 just now, sorry.

-- 
Cheers,

David / dhildenb
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by Vlastimil Babka 6 months, 2 weeks ago
On 5/30/25 18:22, Zi Yan wrote:
> migratetype is no longer overwritten during pageblock isolation,
> start_isolate_page_range(), has_unmovable_pages(), and
> set_migratetype_isolate() no longer need which migratetype to restore
> during isolation failure.
> 
> For has_unmoable_pages(), it needs to know if the isolation is for CMA
> allocation, so adding CMA_ALLOCATION to provide the information. At the
> same time change isolation flags to enum pb_isolate_mode
> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
> isolation failures.
> 
> alloc_contig_range() no longer needs migratetype. Replace it with
> enum acr_flags_t to tell if an allocation is for CMA. So does
> __alloc_contig_migrate_range().
> 
> Signed-off-by: Zi Yan <ziy@nvidia.com>

Reviewed-by: Vlastimil Babka <vbabka@suse.cz>

> ---
>  drivers/virtio/virtio_mem.c    |  2 +-
>  include/linux/gfp.h            |  9 ++++-
>  include/linux/page-isolation.h | 20 ++++++++--
>  include/trace/events/kmem.h    | 14 ++++---
>  mm/cma.c                       |  2 +-
>  mm/memory_hotplug.c            |  6 +--
>  mm/page_alloc.c                | 27 ++++++-------
>  mm/page_isolation.c            | 70 +++++++++++++++-------------------
>  8 files changed, 82 insertions(+), 68 deletions(-)
> 
> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
> index 56d0dbe62163..6bce70b139b2 100644
> --- a/drivers/virtio/virtio_mem.c
> +++ b/drivers/virtio/virtio_mem.c
> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>  		if (atomic_read(&vm->config_changed))
>  			return -EAGAIN;
>  
> -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>  					GFP_KERNEL);
>  		if (rc == -ENOMEM)
>  			/* whoops, out of memory */
> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
> index be160e8d8bcb..51990d571e3e 100644
> --- a/include/linux/gfp.h
> +++ b/include/linux/gfp.h
> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>  extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>  
>  #ifdef CONFIG_CONTIG_ALLOC
> +
> +enum acr_flags_t {
> +	ACR_CMA,	// CMA allocation
> +	ACR_OTHER,	// other allocation
> +};
> +
>  /* The below functions must be run on a range from a single zone. */
>  extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
> -			      unsigned migratetype, gfp_t gfp_mask);
> +				     enum acr_flags_t alloc_flags,
> +				     gfp_t gfp_mask);

Nit: when used this way I think it's also rather a "mode" than "flags". It's
probably sufficient though, I don't expect we'll be adding more and want to
combine them in a flags way. So it's just about the enum's name.

>  #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))
>
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by Zi Yan 6 months, 2 weeks ago
On 30 May 2025, at 13:15, Vlastimil Babka wrote:

> On 5/30/25 18:22, Zi Yan wrote:
>> migratetype is no longer overwritten during pageblock isolation,
>> start_isolate_page_range(), has_unmovable_pages(), and
>> set_migratetype_isolate() no longer need which migratetype to restore
>> during isolation failure.
>>
>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>> same time change isolation flags to enum pb_isolate_mode
>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>> isolation failures.
>>
>> alloc_contig_range() no longer needs migratetype. Replace it with
>> enum acr_flags_t to tell if an allocation is for CMA. So does
>> __alloc_contig_migrate_range().
>>
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>
> Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
>
>> ---
>>  drivers/virtio/virtio_mem.c    |  2 +-
>>  include/linux/gfp.h            |  9 ++++-
>>  include/linux/page-isolation.h | 20 ++++++++--
>>  include/trace/events/kmem.h    | 14 ++++---
>>  mm/cma.c                       |  2 +-
>>  mm/memory_hotplug.c            |  6 +--
>>  mm/page_alloc.c                | 27 ++++++-------
>>  mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>  8 files changed, 82 insertions(+), 68 deletions(-)
>>
>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>> index 56d0dbe62163..6bce70b139b2 100644
>> --- a/drivers/virtio/virtio_mem.c
>> +++ b/drivers/virtio/virtio_mem.c
>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>  		if (atomic_read(&vm->config_changed))
>>  			return -EAGAIN;
>>
>> -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>  					GFP_KERNEL);
>>  		if (rc == -ENOMEM)
>>  			/* whoops, out of memory */
>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>> index be160e8d8bcb..51990d571e3e 100644
>> --- a/include/linux/gfp.h
>> +++ b/include/linux/gfp.h
>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>  extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>
>>  #ifdef CONFIG_CONTIG_ALLOC
>> +
>> +enum acr_flags_t {
>> +	ACR_CMA,	// CMA allocation
>> +	ACR_OTHER,	// other allocation
>> +};
>> +
>>  /* The below functions must be run on a range from a single zone. */
>>  extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>> -			      unsigned migratetype, gfp_t gfp_mask);
>> +				     enum acr_flags_t alloc_flags,
>> +				     gfp_t gfp_mask);
>
> Nit: when used this way I think it's also rather a "mode" than "flags". It's
> probably sufficient though, I don't expect we'll be adding more and want to
> combine them in a flags way. So it's just about the enum's name.

This is the fixup (variable alloc_flags is renamed to alloc_mode too):

From 9674b741eb93eb74de52fb28c644f523387d1e9f Mon Sep 17 00:00:00 2001
From: Zi Yan <ziy@nvidia.com>
Date: Fri, 30 May 2025 13:58:11 -0400
Subject: [PATCH] rename acr_flags_t to acr_mode.

Signed-off-by: Zi Yan <ziy@nvidia.com>
---
 include/linux/gfp.h         |  4 ++--
 include/trace/events/kmem.h | 12 ++++++------
 mm/page_alloc.c             | 14 +++++++-------
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 51990d571e3e..363771903be3 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -424,14 +424,14 @@ extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);

 #ifdef CONFIG_CONTIG_ALLOC

-enum acr_flags_t {
+enum acr_mode {
 	ACR_CMA,	// CMA allocation
 	ACR_OTHER,	// other allocation
 };

 /* The below functions must be run on a range from a single zone. */
 extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
-				     enum acr_flags_t alloc_flags,
+				     enum acr_mode alloc_mode,
 				     gfp_t gfp_mask);
 #define alloc_contig_range(...)			alloc_hooks(alloc_contig_range_noprof(__VA_ARGS__))

diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 7c4e2e703a23..4ac8fbff224c 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -312,9 +312,9 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		 unsigned long nr_migrated,
 		 unsigned long nr_reclaimed,
 		 unsigned long nr_mapped,
-		 enum acr_flags_t alloc_flags),
+		 enum acr_mode alloc_mode),

-	TP_ARGS(start, end, nr_migrated, nr_reclaimed, nr_mapped, alloc_flags),
+	TP_ARGS(start, end, nr_migrated, nr_reclaimed, nr_mapped, alloc_mode),

 	TP_STRUCT__entry(
 		__field(unsigned long, start)
@@ -322,7 +322,7 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		__field(unsigned long, nr_migrated)
 		__field(unsigned long, nr_reclaimed)
 		__field(unsigned long, nr_mapped)
-		__field(enum acr_flags_t, alloc_flags)
+		__field(enum acr_mode, alloc_mode)
 	),

 	TP_fast_assign(
@@ -331,13 +331,13 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info,
 		__entry->nr_migrated = nr_migrated;
 		__entry->nr_reclaimed = nr_reclaimed;
 		__entry->nr_mapped = nr_mapped;
-		__entry->alloc_flags = alloc_flags;
+		__entry->alloc_mode = alloc_mode;
 	),

-	TP_printk("start=0x%lx end=0x%lx alloc_flags=%d nr_migrated=%lu nr_reclaimed=%lu nr_mapped=%lu",
+	TP_printk("start=0x%lx end=0x%lx alloc_mode=%d nr_migrated=%lu nr_reclaimed=%lu nr_mapped=%lu",
 		  __entry->start,
 		  __entry->end,
-		  __entry->alloc_flags,
+		  __entry->alloc_mode,
 		  __entry->nr_migrated,
 		  __entry->nr_reclaimed,
 		  __entry->nr_mapped)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index dd761f5e6310..dc418510aba2 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6696,12 +6696,12 @@ static void alloc_contig_dump_pages(struct list_head *page_list)

 /*
  * [start, end) must belong to a single zone.
- * @alloc_flags: using acr_flags_t to filter the type of migration in
+ * @alloc_mode: using acr_mode to filter the type of migration in
  *		trace_mm_alloc_contig_migrate_range_info.
  */
 static int __alloc_contig_migrate_range(struct compact_control *cc,
 					unsigned long start, unsigned long end,
-					enum acr_flags_t alloc_flags)
+					enum acr_mode alloc_mode)
 {
 	/* This function is based on compact_zone() from compaction.c. */
 	unsigned int nr_reclaimed;
@@ -6773,7 +6773,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
 		putback_movable_pages(&cc->migratepages);
 	}

-	trace_mm_alloc_contig_migrate_range_info(start, end, alloc_flags,
+	trace_mm_alloc_contig_migrate_range_info(start, end, alloc_mode,
 						 total_migrated,
 						 total_reclaimed,
 						 total_mapped);
@@ -6844,7 +6844,7 @@ static int __alloc_contig_verify_gfp_mask(gfp_t gfp_mask, gfp_t *gfp_cc_mask)
  * alloc_contig_range() -- tries to allocate given range of pages
  * @start:	start PFN to allocate
  * @end:	one-past-the-last PFN to allocate
- * @alloc_flags:	allocation information
+ * @alloc_mode:	allocation information
  * @gfp_mask:	GFP mask. Node/zone/placement hints are ignored; only some
  *		action and reclaim modifiers are supported. Reclaim modifiers
  *		control allocation behavior during compaction/migration/reclaim.
@@ -6861,7 +6861,7 @@ static int __alloc_contig_verify_gfp_mask(gfp_t gfp_mask, gfp_t *gfp_cc_mask)
  * need to be freed with free_contig_range().
  */
 int alloc_contig_range_noprof(unsigned long start, unsigned long end,
-			      enum acr_flags_t alloc_flags, gfp_t gfp_mask)
+			      enum acr_mode alloc_mode, gfp_t gfp_mask)
 {
 	unsigned long outer_start, outer_end;
 	int ret = 0;
@@ -6876,7 +6876,7 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 		.alloc_contig = true,
 	};
 	INIT_LIST_HEAD(&cc.migratepages);
-	enum pb_isolate_mode mode = (alloc_flags == ACR_CMA) ?
+	enum pb_isolate_mode mode = (alloc_mode == ACR_CMA) ?
 					    PB_ISOLATE_MODE_CMA_ALLOC :
 					    PB_ISOLATE_MODE_OTHER;

@@ -6921,7 +6921,7 @@ int alloc_contig_range_noprof(unsigned long start, unsigned long end,
 	 * allocated.  So, if we fall through be sure to clear ret so that
 	 * -EBUSY is not accidentally used or returned to caller.
 	 */
-	ret = __alloc_contig_migrate_range(&cc, start, end, alloc_flags);
+	ret = __alloc_contig_migrate_range(&cc, start, end, alloc_mode);
 	if (ret && ret != -EBUSY)
 		goto done;

-- 
2.47.2



Best Regards,
Yan, Zi
Re: [PATCH v6 6/6] mm/page_isolation: remove migratetype parameter from more functions.
Posted by Zi Yan 6 months, 2 weeks ago
On 30 May 2025, at 13:15, Vlastimil Babka wrote:

> On 5/30/25 18:22, Zi Yan wrote:
>> migratetype is no longer overwritten during pageblock isolation,
>> start_isolate_page_range(), has_unmovable_pages(), and
>> set_migratetype_isolate() no longer need which migratetype to restore
>> during isolation failure.
>>
>> For has_unmoable_pages(), it needs to know if the isolation is for CMA
>> allocation, so adding CMA_ALLOCATION to provide the information. At the
>> same time change isolation flags to enum pb_isolate_mode
>> (PB_ISOLATE_MODE_MEM_OFFLINE, PB_ISOLATE_MODE_CMA_ALLOC,
>> PB_ISOLATE_MODE_OTHER). Remove REPORT_FAILURE and check
>> MEMORY_OFFLINE instead, since only PB_ISOLATE_MODE_MEM_OFFLINE reports
>> isolation failures.
>>
>> alloc_contig_range() no longer needs migratetype. Replace it with
>> enum acr_flags_t to tell if an allocation is for CMA. So does
>> __alloc_contig_migrate_range().
>>
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>
> Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
>
>> ---
>>  drivers/virtio/virtio_mem.c    |  2 +-
>>  include/linux/gfp.h            |  9 ++++-
>>  include/linux/page-isolation.h | 20 ++++++++--
>>  include/trace/events/kmem.h    | 14 ++++---
>>  mm/cma.c                       |  2 +-
>>  mm/memory_hotplug.c            |  6 +--
>>  mm/page_alloc.c                | 27 ++++++-------
>>  mm/page_isolation.c            | 70 +++++++++++++++-------------------
>>  8 files changed, 82 insertions(+), 68 deletions(-)
>>
>> diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
>> index 56d0dbe62163..6bce70b139b2 100644
>> --- a/drivers/virtio/virtio_mem.c
>> +++ b/drivers/virtio/virtio_mem.c
>> @@ -1243,7 +1243,7 @@ static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
>>  		if (atomic_read(&vm->config_changed))
>>  			return -EAGAIN;
>>
>> -		rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
>> +		rc = alloc_contig_range(pfn, pfn + nr_pages, ACR_OTHER,
>>  					GFP_KERNEL);
>>  		if (rc == -ENOMEM)
>>  			/* whoops, out of memory */
>> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
>> index be160e8d8bcb..51990d571e3e 100644
>> --- a/include/linux/gfp.h
>> +++ b/include/linux/gfp.h
>> @@ -423,9 +423,16 @@ static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
>>  extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma);
>>
>>  #ifdef CONFIG_CONTIG_ALLOC
>> +
>> +enum acr_flags_t {
>> +	ACR_CMA,	// CMA allocation
>> +	ACR_OTHER,	// other allocation
>> +};
>> +
>>  /* The below functions must be run on a range from a single zone. */
>>  extern int alloc_contig_range_noprof(unsigned long start, unsigned long end,
>> -			      unsigned migratetype, gfp_t gfp_mask);
>> +				     enum acr_flags_t alloc_flags,
>> +				     gfp_t gfp_mask);
>
> Nit: when used this way I think it's also rather a "mode" than "flags". It's
> probably sufficient though, I don't expect we'll be adding more and want to
> combine them in a flags way. So it's just about the enum's name.
>

So enum acr_flags_t to enum acr_mode_t? Sure. Let me send a fixup.

Best Regards,
Yan, Zi