[PATCH 7/9] mm: page_isolation: do not take slab pages for free

From: Vlastimil Babka (SUSE)

Date: Tue Oct 27 2026 - 12:00:23 EST


From: Josef Bacik <josef@xxxxxxxxxxxxxx>

page_is_unmovable() regards a page with a reference count of zero as free
or about to be freed. Since slab allocates frozen pages, they will
be wrongly considered to be freed if order 0 (higher-order compound
pages are caught earlier).

If such slabs are the only unmovable pages of a memory block, memory
offlining now isolates the block, this can lead to offline_pages()
looping without progress.

Thus detect the slab pages as removable to return -EBUSY, as would
happen before commit 9aec2fb0fd5e ("slab: allocate frozen pages").

Fixes: 9aec2fb0fd5e ("slab: allocate frozen pages")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
Signed-off-by: Vlastimil Babka (SUSE) <vbabka@xxxxxxxxxx>
---
mm/memory_hotplug.c | 7 +++++++
mm/page_isolation.c | 7 +++++++
2 files changed, 14 insertions(+)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 796af1028ee2..e773a7d54165 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1847,6 +1847,13 @@ static int scan_movable_pages(unsigned long start, unsigned long end,
if (PageOffline(page) && page_count(page))
return -EBUSY;

+ /*
+ * A page that was allocated, but was not a slab page yet, when
+ * its pageblock was isolated.
+ */
+ if (PageSlab(page))
+ return -EBUSY;
+
folio = page_folio(page);
if (!folio_test_hugetlb(folio))
continue;
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index 5aaad037384e..f4f0571607ab 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -74,6 +74,13 @@ bool page_is_unmovable(struct zone *zone, struct page *page,
return false;
}

+ /*
+ * Slab pages are frozen: do not take their reference count of zero
+ * for that of a free page.
+ */
+ if (PageSlab(page))
+ return true;
+
/*
* We can't use page_count without pin a page
* because another CPU can free compound page.

--
2.56.0