Skip to content

Commit 47aef60

Browse files
Doug Bergertorvalds
authored andcommitted
mm/page_alloc: don't corrupt pcppage_migratetype
When placing pages on a pcp list, migratetype values over MIGRATE_PCPTYPES get added to the MIGRATE_MOVABLE pcp list. However, the actual migratetype is preserved in the page and should not be changed to MIGRATE_MOVABLE or the page may end up on the wrong free_list. The impact is that HIGHATOMIC or CMA pages getting bulk freed from the PCP lists could potentially end up on the wrong buddy list. There are various consequences but minimally NR_FREE_CMA_PAGES accounting could get screwed up. [[email protected]: changelog update] Link: https://lkml.kernel.org/r/[email protected] Fixes: df1acc8 ("mm/page_alloc: avoid conflating IRQs disabled with zone->lock") Signed-off-by: Doug Berger <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Acked-by: Mel Gorman <[email protected]> Cc: "Peter Zijlstra (Intel)" <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent c04b3d0 commit 47aef60

File tree

1 file changed

+12
-13
lines changed

1 file changed

+12
-13
lines changed

mm/page_alloc.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3453,19 +3453,10 @@ void free_unref_page_list(struct list_head *list)
34533453
* comment in free_unref_page.
34543454
*/
34553455
migratetype = get_pcppage_migratetype(page);
3456-
if (unlikely(migratetype >= MIGRATE_PCPTYPES)) {
3457-
if (unlikely(is_migrate_isolate(migratetype))) {
3458-
list_del(&page->lru);
3459-
free_one_page(page_zone(page), page, pfn, 0,
3460-
migratetype, FPI_NONE);
3461-
continue;
3462-
}
3463-
3464-
/*
3465-
* Non-isolated types over MIGRATE_PCPTYPES get added
3466-
* to the MIGRATE_MOVABLE pcp list.
3467-
*/
3468-
set_pcppage_migratetype(page, MIGRATE_MOVABLE);
3456+
if (unlikely(is_migrate_isolate(migratetype))) {
3457+
list_del(&page->lru);
3458+
free_one_page(page_zone(page), page, pfn, 0, migratetype, FPI_NONE);
3459+
continue;
34693460
}
34703461

34713462
set_page_private(page, pfn);
@@ -3475,7 +3466,15 @@ void free_unref_page_list(struct list_head *list)
34753466
list_for_each_entry_safe(page, next, list, lru) {
34763467
pfn = page_private(page);
34773468
set_page_private(page, 0);
3469+
3470+
/*
3471+
* Non-isolated types over MIGRATE_PCPTYPES get added
3472+
* to the MIGRATE_MOVABLE pcp list.
3473+
*/
34783474
migratetype = get_pcppage_migratetype(page);
3475+
if (unlikely(migratetype >= MIGRATE_PCPTYPES))
3476+
migratetype = MIGRATE_MOVABLE;
3477+
34793478
trace_mm_page_free_batched(page);
34803479
free_unref_page_commit(page, pfn, migratetype, 0);
34813480

0 commit comments

Comments
 (0)