|
@@ -2085,13 +2085,25 @@ static void unreserve_highatomic_pageblock(const struct alloc_context *ac)
|
|
|
continue;
|
|
|
|
|
|
/*
|
|
|
- * It should never happen but changes to locking could
|
|
|
- * inadvertently allow a per-cpu drain to add pages
|
|
|
- * to MIGRATE_HIGHATOMIC while unreserving so be safe
|
|
|
- * and watch for underflows.
|
|
|
+ * In page freeing path, migratetype change is racy so
|
|
|
+ * we can counter several free pages in a pageblock
|
|
|
+ * in this loop althoug we changed the pageblock type
|
|
|
+ * from highatomic to ac->migratetype. So we should
|
|
|
+ * adjust the count once.
|
|
|
*/
|
|
|
- zone->nr_reserved_highatomic -= min(pageblock_nr_pages,
|
|
|
- zone->nr_reserved_highatomic);
|
|
|
+ if (get_pageblock_migratetype(page) ==
|
|
|
+ MIGRATE_HIGHATOMIC) {
|
|
|
+ /*
|
|
|
+ * It should never happen but changes to
|
|
|
+ * locking could inadvertently allow a per-cpu
|
|
|
+ * drain to add pages to MIGRATE_HIGHATOMIC
|
|
|
+ * while unreserving so be safe and watch for
|
|
|
+ * underflows.
|
|
|
+ */
|
|
|
+ zone->nr_reserved_highatomic -= min(
|
|
|
+ pageblock_nr_pages,
|
|
|
+ zone->nr_reserved_highatomic);
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* Convert to ac->migratetype and avoid the normal
|