aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 08c195cdf161..e29a6ba050c8 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1080,12 +1080,10 @@ static void free_pcppages_bulk(struct zone *zone, int count,
1080 int migratetype = 0; 1080 int migratetype = 0;
1081 int batch_free = 0; 1081 int batch_free = 0;
1082 bool isolated_pageblocks; 1082 bool isolated_pageblocks;
1083 1083 struct page *page, *tmp;
1084 spin_lock(&zone->lock); 1084 LIST_HEAD(head);
1085 isolated_pageblocks = has_isolate_pageblock(zone);
1086 1085
1087 while (count) { 1086 while (count) {
1088 struct page *page;
1089 struct list_head *list; 1087 struct list_head *list;
1090 1088
1091 /* 1089 /*
@@ -1107,27 +1105,36 @@ static void free_pcppages_bulk(struct zone *zone, int count,
1107 batch_free = count; 1105 batch_free = count;
1108 1106
1109 do { 1107 do {
1110 int mt; /* migratetype of the to-be-freed page */
1111
1112 page = list_last_entry(list, struct page, lru); 1108 page = list_last_entry(list, struct page, lru);
1113 /* must delete as __free_one_page list manipulates */ 1109 /* must delete to avoid corrupting pcp list */
1114 list_del(&page->lru); 1110 list_del(&page->lru);
1115 pcp->count--; 1111 pcp->count--;
1116 1112
1117 mt = get_pcppage_migratetype(page);
1118 /* MIGRATE_ISOLATE page should not go to pcplists */
1119 VM_BUG_ON_PAGE(is_migrate_isolate(mt), page);
1120 /* Pageblock could have been isolated meanwhile */
1121 if (unlikely(isolated_pageblocks))
1122 mt = get_pageblock_migratetype(page);
1123
1124 if (bulkfree_pcp_prepare(page)) 1113 if (bulkfree_pcp_prepare(page))
1125 continue; 1114 continue;
1126 1115
1127 __free_one_page(page, page_to_pfn(page), zone, 0, mt); 1116 list_add_tail(&page->lru, &head);
1128 trace_mm_page_pcpu_drain(page, 0, mt);
1129 } while (--count && --batch_free && !list_empty(list)); 1117 } while (--count && --batch_free && !list_empty(list));
1130 } 1118 }
1119
1120 spin_lock(&zone->lock);
1121 isolated_pageblocks = has_isolate_pageblock(zone);
1122
1123 /*
1124 * Use safe version since after __free_one_page(),
1125 * page->lru.next will not point to original list.
1126 */
1127 list_for_each_entry_safe(page, tmp, &head, lru) {
1128 int mt = get_pcppage_migratetype(page);
1129 /* MIGRATE_ISOLATE page should not go to pcplists */
1130 VM_BUG_ON_PAGE(is_migrate_isolate(mt), page);
1131 /* Pageblock could have been isolated meanwhile */
1132 if (unlikely(isolated_pageblocks))
1133 mt = get_pageblock_migratetype(page);
1134
1135 __free_one_page(page, page_to_pfn(page), zone, 0, mt);
1136 trace_mm_page_pcpu_drain(page, 0, mt);
1137 }
1131 spin_unlock(&zone->lock); 1138 spin_unlock(&zone->lock);
1132} 1139}
1133 1140