diff options
-rw-r--r-- | mm/page_alloc.c | 39 |
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 | ||