Messages in this thread Patch in this message | | | From | Andrea Arcangeli <> | Subject | [PATCH 1/1] mm: compaction: avoid fast_isolate_around() to set pageblock_skip on reserved pages | Date | Sat, 21 Nov 2020 14:45:06 -0500 |
| |
A corollary issue was fixed in e577c8b64d58fe307ea4d5149d31615df2d90861. A second issue remained in v5.7:
https://lkml.kernel.org/r/8C537EB7-85EE-4DCF-943E-3CC0ED0DF56D@lca.pw
== page:ffffea0000aa0000 refcount:1 mapcount:0 mapping:000000002243743b index:0x0 flags: 0x1fffe000001000(reserved) ==
73a6e474cb376921a311786652782155eac2fdf0 was applied to supposedly the second issue, but I still reproduced it twice with v5.9 on two different systems:
== page:0000000062b3e92f refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x39800 flags: 0x1000(reserved) == page:000000002a7114f8 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x7a200 flags: 0x1fff000000001000(reserved) ==
I actually never reproduced it until v5.9, but it's still the same bug as it was reported first for v5.7.
See the page is "reserved" in all 3 cases. In the last two crashes with the pfn:
pfn 0x39800 -> 0x39800000 min_pfn hit non-RAM:
39639000-39814fff : Unknown E820 type
pfn 0x7a200 -> 0x7a200000 min_pfn hit non-RAM:
7a17b000-7a216fff : Unknown E820 type
This actually seems a false positive bugcheck, the page structures are valid and the zones are correct, just it's non-RAM but setting pageblockskip should do no harm. However it's possible to solve the crash without lifting the bugcheck, by enforcing the invariant that the free_pfn cursor doesn't point to reserved pages (which would be otherwise implicitly achieved through the PageBuddy check, except in the new fast_isolate_around() path).
Fixes: 5a811889de10 ("mm, compaction: use free lists to quickly locate a migration target") Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> --- mm/compaction.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/mm/compaction.c b/mm/compaction.c index 13cb7a961b31..d17e69549d34 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1433,7 +1433,10 @@ fast_isolate_freepages(struct compact_control *cc) page = pageblock_pfn_to_page(min_pfn, pageblock_end_pfn(min_pfn), cc->zone); - cc->free_pfn = min_pfn; + if (likely(!PageReserved(page))) + cc->free_pfn = min_pfn; + else + page = NULL; } } }
| |