mm/page_alloc: Call kernel_map_pages in unset_migrateype_isolate
Subsystems (2)
PATCH 1/1 mm/page_alloc: Call kernel_map_pages in unset_migrateype_isolate
Commit 3c605096d315 ("mm/page_alloc: restrict max order of merging on isolated pageblock") changed the logic of unset_migratetype_isolate to check the buddy allocator and explicitly call __free_pages to merge. The page that is being freed in this path never had prep_new_page called so set_page_refcounted is called explicitly but there is no call to kernel_map_pages. With the default kernel_map_pages this is mostly harmless but if kernel_map_pages does any manipulation of the page tables (unmapping or setting pages to read only) this may trigger a fault:
alloc_contig_range test_pages_isolated(ceb00, ced00) failed
Unable to handle kernel paging request at virtual address ffffffc0cec00000
pgd = ffffffc045fc4000
[ffffffc0cec00000] *pgd=0000000000000000
Internal error: Oops: 9600004f [#1] PREEMPT SMP
Modules linked in: exfatfs
CPU: 1 PID: 23237 Comm: TimedEventQueue Not tainted 3.10.49-gc72ad36-dirty #1
task: ffffffc03de52100 ti: ffffffc015388000 task.ti: ffffffc015388000
PC is at memset+0xc8/0x1c0
LR is at kernel_map_pages+0x1ec/0x244Fix this by calling kernel_map_pages to ensure the page is set in the page table properly
---
Note this was found on a backport to 3.10 and the code to make kernel_map_pages change the page table state is currently out of tree. The original had stable, so this may need to go into stable as well.
--- mm/page_isolation.c | 1 + 1 file changed, 1 insertion(+)
mm/page_isolation.c +1 -0
@@ -103,6 +103,7 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype)if (!is_migrate_isolate_page (buddy)) {__isolate_free_page (page, order); +kernel_map_pages (page, (1 << order),1 );set_page_refcounted (page); isolated_page = page; }
Signature · 10 lines
Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project This e-mail address will be inactive after March 20, 2015 Please contact privately for follow up after that date. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 37 lines · Laura Abbott
Commit
3c605096d315("mm/page_alloc: restrict max order of merging on isolated pageblock") changed the logic ofunset_migratetype_isolateto check the buddy allocator and explicitly call__free_pagesto merge. The page that is being freed in this path never hadprep_new_pagecalled soset_page_refcountedis called explicitly but there is no call tokernel_map_pages. With the defaultkernel_map_pagesthis is mostly harmless but ifkernel_map_pagesdoes any manipulation of the page tables (unmapping or setting pages to read only) this may trigger a fault:alloc_contig_range test_pages_isolated(ceb00, ced00) failed Unable to handle kernel paging request at virtual address ffffffc0cec00000 pgd = ffffffc045fc4000 [ffffffc0cec00000] *pgd=0000000000000000 Internal error: Oops: 9600004f [#1] PREEMPT SMP Modules linked in: exfatfs CPU: 1 PID: 23237 Comm: TimedEventQueue Not tainted 3.10.49-gc72ad36-dirty #1 task: ffffffc03de52100 ti: ffffffc015388000 task.ti: ffffffc015388000 PC is at memset+0xc8/0x1c0 LR is at kernel_map_pages+0x1ec/0x244Fix this by calling
kernel_map_pagesto ensure the page is set in the page table properlyFixes 3c605096d315 ("mm/page_alloc: restrict max order of merging on isolated pageblock")Cc Naoya Horiguchi <[email protected]>Cc Mel Gorman <[email protected]>Cc Rik van Riel <[email protected]>Cc Yasuaki Ishimatsu <[email protected]>Cc Zhang Yanfei <[email protected]>Cc Xishi Qiu <[email protected]>Cc Vladimir Davydov <[email protected]>Cc Joonsoo Kim <[email protected]>Cc Gioh Kim <[email protected]>Cc Michal Nazarewicz <[email protected]>Cc Marek Szyprowski <[email protected]>Cc Vlastimil Babka <[email protected]>Signed-off-by Laura Abbott <[email protected]>
Quoted 4 lines
---
Note this was found on a backport to 3.10 and the code to makekernel_map_pageschange the page table state is currently out of tree. The original had stable, so this may need to go into stable as well.
I found that some implementation of kernel_map_pages() in mainline also require this change. Some implementation doesn't check previous state of page table, but some others check previous state of page table when calling kernel_map_pages().
Thanks.
Quoted 27 lines
--- mm/page_isolation.c | 1 + 1 file changed, 1 insertion(+)mm/page_isolation.c +1
-0@@ -103,6 +103,7 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype)if (!is_migrate_isolate_page (buddy)) {__isolate_free_page (page, order); +kernel_map_pages (page, (1 << order),1 );set_page_refcounted (page); isolated_page = page; }Signature · 10 lines
Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project This e-mail address will be inactive after March 20, 2015 Please contact privately for follow up after that date. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 20 lines · Laura Abbott
Commit
3c605096d315("mm/page_alloc: restrict max order of merging on isolated pageblock") changed the logic ofunset_migratetype_isolateto check the buddy allocator and explicitly call__free_pagesto merge. The page that is being freed in this path never hadprep_new_pagecalled soset_page_refcountedis called explicitly but there is no call tokernel_map_pages. With the defaultkernel_map_pagesthis is mostly harmless but ifkernel_map_pagesdoes any manipulation of the page tables (unmapping or setting pages to read only) this may trigger a fault:alloc_contig_range test_pages_isolated(ceb00, ced00) failed Unable to handle kernel paging request at virtual address ffffffc0cec00000 pgd = ffffffc045fc4000 [ffffffc0cec00000] *pgd=0000000000000000 Internal error: Oops: 9600004f [#1] PREEMPT SMP Modules linked in: exfatfs CPU: 1 PID: 23237 Comm: TimedEventQueue Not tainted 3.10.49-gc72ad36-dirty #1 task: ffffffc03de52100 ti: ffffffc015388000 task.ti: ffffffc015388000 PC is at memset+0xc8/0x1c0 LR is at kernel_map_pages+0x1ec/0x244
Quoted 2 lines
Fix this by calling
kernel_map_pagesto ensure the page is set in the page table properly
Signature · 7 lines
All rights reversed -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>