Re: [PATCH v2] mm/page_isolation: fix potential missing call to unset_migratetype_isolate()

From: David Hildenbrand
Date: Mon Sep 13 2021 - 08:20:34 EST


On 13.09.21 14:12, Michal Hocko wrote:
On Mon 13-09-21 19:51:25, Miaohe Lin wrote:
In start_isolate_page_range() undo path, pfn_to_online_page() just checks
the first pfn in a pageblock while __first_valid_page() will traverse the
pageblock until the first online pfn is found. So we may miss the call to
unset_migratetype_isolate() in undo path and pages will remain isolated
unexpectedly. Fix this by calling undo_isolate_page_range() and this will
also help to simplify the code further.

I like the clean up part but is this a real problem that requires CC
stable? Have you ever seen this to be a real problem? It looks like
something based on reading the code.

We discussed that it isn't an issue anymore (we never call it on memory holes), but might have been an issue on older kernels, back when we didn't have the "memory holes" check in the memory offlining path in place.

Agreed, these details belong into this description.


Fixes: 2ce13640b3f4 ("mm: __first_valid_page skip over offline pages")
Signed-off-by: Miaohe Lin <linmiaohe@xxxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
---
v1->v2:
Simplify the code further per David Hildenbrand.
---
mm/page_isolation.c | 20 +++-----------------
1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index a95c2c6562d0..f93cc63d8fa1 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -183,7 +183,6 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
unsigned migratetype, int flags)
{
unsigned long pfn;
- unsigned long undo_pfn;
struct page *page;
BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages));
@@ -193,25 +192,12 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
pfn < end_pfn;
pfn += pageblock_nr_pages) {
page = __first_valid_page(pfn, pageblock_nr_pages);
- if (page) {
- if (set_migratetype_isolate(page, migratetype, flags)) {
- undo_pfn = pfn;
- goto undo;
- }
+ if (page && set_migratetype_isolate(page, migratetype, flags)) {
+ undo_isolate_page_range(start_pfn, pfn, migratetype);
+ return -EBUSY;
}
}
return 0;
-undo:
- for (pfn = start_pfn;
- pfn < undo_pfn;
- pfn += pageblock_nr_pages) {
- struct page *page = pfn_to_online_page(pfn);
- if (!page)
- continue;
- unset_migratetype_isolate(page, migratetype);
- }
-
- return -EBUSY;
}
/*
--
2.23.0



--
Thanks,

David / dhildenb