diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 97170131f2ab..8cbc38f923aa 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -2085,13 +2085,25 @@ static void unreserve_highatomic_pageblock(const struct alloc_context *ac) | |||
2085 | continue; | 2085 | continue; |
2086 | 2086 | ||
2087 | /* | 2087 | /* |
2088 | * It should never happen but changes to locking could | 2088 | * In page freeing path, migratetype change is racy so |
2089 | * inadvertently allow a per-cpu drain to add pages | 2089 | * we can counter several free pages in a pageblock |
2090 | * to MIGRATE_HIGHATOMIC while unreserving so be safe | 2090 | * in this loop althoug we changed the pageblock type |
2091 | * and watch for underflows. | 2091 | * from highatomic to ac->migratetype. So we should |
2092 | * adjust the count once. | ||
2092 | */ | 2093 | */ |
2093 | zone->nr_reserved_highatomic -= min(pageblock_nr_pages, | 2094 | if (get_pageblock_migratetype(page) == |
2094 | zone->nr_reserved_highatomic); | 2095 | MIGRATE_HIGHATOMIC) { |
2096 | /* | ||
2097 | * It should never happen but changes to | ||
2098 | * locking could inadvertently allow a per-cpu | ||
2099 | * drain to add pages to MIGRATE_HIGHATOMIC | ||
2100 | * while unreserving so be safe and watch for | ||
2101 | * underflows. | ||
2102 | */ | ||
2103 | zone->nr_reserved_highatomic -= min( | ||
2104 | pageblock_nr_pages, | ||
2105 | zone->nr_reserved_highatomic); | ||
2106 | } | ||
2095 | 2107 | ||
2096 | /* | 2108 | /* |
2097 | * Convert to ac->migratetype and avoid the normal | 2109 | * Convert to ac->migratetype and avoid the normal |