aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorJoonsoo Kim <iamjoonsoo.kim@lge.com>2018-05-22 21:18:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-24 13:07:50 -0400
commitd883c6cf3b39f1f42506e82ad2779fb88004acf3 (patch)
tree13c8874a7b7fa67546001f638d84696df9b8d65b /mm/page_alloc.c
parent577e75e0c9da98b898d2dbe94c30b40eec5b9c99 (diff)
Revert "mm/cma: manage the memory of the CMA area by using the ZONE_MOVABLE"
This reverts the following commits that change CMA design in MM. 3d2054ad8c2d ("ARM: CMA: avoid double mapping to the CMA area if CONFIG_HIGHMEM=y") 1d47a3ec09b5 ("mm/cma: remove ALLOC_CMA") bad8c6c0b114 ("mm/cma: manage the memory of the CMA area by using the ZONE_MOVABLE") Ville reported a following error on i386. Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) microcode: microcode updated early to revision 0x4, date = 2013-06-28 Initializing CPU#0 Initializing HighMem for node 0 (000377fe:00118000) Initializing Movable for node 0 (00000001:00118000) BUG: Bad page state in process swapper pfn:377fe page:f53effc0 count:0 mapcount:-127 mapping:00000000 index:0x0 flags: 0x80000000() raw: 80000000 00000000 00000000 ffffff80 00000000 00000100 00000200 00000001 page dumped because: nonzero mapcount Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 4.17.0-rc5-elk+ #145 Hardware name: Dell Inc. Latitude E5410/03VXMC, BIOS A15 07/11/2013 Call Trace: dump_stack+0x60/0x96 bad_page+0x9a/0x100 free_pages_check_bad+0x3f/0x60 free_pcppages_bulk+0x29d/0x5b0 free_unref_page_commit+0x84/0xb0 free_unref_page+0x3e/0x70 __free_pages+0x1d/0x20 free_highmem_page+0x19/0x40 add_highpages_with_active_regions+0xab/0xeb set_highmem_pages_init+0x66/0x73 mem_init+0x1b/0x1d7 start_kernel+0x17a/0x363 i386_start_kernel+0x95/0x99 startup_32_smp+0x164/0x168 The reason for this error is that the span of MOVABLE_ZONE is extended to whole node span for future CMA initialization, and, normal memory is wrongly freed here. I submitted the fix and it seems to work, but, another problem happened. It's so late time to fix the later problem so I decide to reverting the series. Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Laura Abbott <labbott@redhat.com> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c83
1 files changed, 30 insertions, 53 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 905db9d7962f..511a7124d7f9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1743,38 +1743,16 @@ void __init page_alloc_init_late(void)
1743} 1743}
1744 1744
1745#ifdef CONFIG_CMA 1745#ifdef CONFIG_CMA
1746static void __init adjust_present_page_count(struct page *page, long count)
1747{
1748 struct zone *zone = page_zone(page);
1749
1750 /* We don't need to hold a lock since it is boot-up process */
1751 zone->present_pages += count;
1752}
1753
1754/* Free whole pageblock and set its migration type to MIGRATE_CMA. */ 1746/* Free whole pageblock and set its migration type to MIGRATE_CMA. */
1755void __init init_cma_reserved_pageblock(struct page *page) 1747void __init init_cma_reserved_pageblock(struct page *page)
1756{ 1748{
1757 unsigned i = pageblock_nr_pages; 1749 unsigned i = pageblock_nr_pages;
1758 unsigned long pfn = page_to_pfn(page);
1759 struct page *p = page; 1750 struct page *p = page;
1760 int nid = page_to_nid(page);
1761
1762 /*
1763 * ZONE_MOVABLE will steal present pages from other zones by
1764 * changing page links so page_zone() is changed. Before that,
1765 * we need to adjust previous zone's page count first.
1766 */
1767 adjust_present_page_count(page, -pageblock_nr_pages);
1768 1751
1769 do { 1752 do {
1770 __ClearPageReserved(p); 1753 __ClearPageReserved(p);
1771 set_page_count(p, 0); 1754 set_page_count(p, 0);
1772 1755 } while (++p, --i);
1773 /* Steal pages from other zones */
1774 set_page_links(p, ZONE_MOVABLE, nid, pfn);
1775 } while (++p, ++pfn, --i);
1776
1777 adjust_present_page_count(page, pageblock_nr_pages);
1778 1756
1779 set_pageblock_migratetype(page, MIGRATE_CMA); 1757 set_pageblock_migratetype(page, MIGRATE_CMA);
1780 1758
@@ -2889,7 +2867,7 @@ int __isolate_free_page(struct page *page, unsigned int order)
2889 * exists. 2867 * exists.
2890 */ 2868 */
2891 watermark = min_wmark_pages(zone) + (1UL << order); 2869 watermark = min_wmark_pages(zone) + (1UL << order);
2892 if (!zone_watermark_ok(zone, 0, watermark, 0, 0)) 2870 if (!zone_watermark_ok(zone, 0, watermark, 0, ALLOC_CMA))
2893 return 0; 2871 return 0;
2894 2872
2895 __mod_zone_freepage_state(zone, -(1UL << order), mt); 2873 __mod_zone_freepage_state(zone, -(1UL << order), mt);
@@ -3165,6 +3143,12 @@ bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
3165 } 3143 }
3166 3144
3167 3145
3146#ifdef CONFIG_CMA
3147 /* If allocation can't use CMA areas don't use free CMA pages */
3148 if (!(alloc_flags & ALLOC_CMA))
3149 free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES);
3150#endif
3151
3168 /* 3152 /*
3169 * Check watermarks for an order-0 allocation request. If these 3153 * Check watermarks for an order-0 allocation request. If these
3170 * are not met, then a high-order request also cannot go ahead 3154 * are not met, then a high-order request also cannot go ahead
@@ -3191,8 +3175,10 @@ bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
3191 } 3175 }
3192 3176
3193#ifdef CONFIG_CMA 3177#ifdef CONFIG_CMA
3194 if (!list_empty(&area->free_list[MIGRATE_CMA])) 3178 if ((alloc_flags & ALLOC_CMA) &&
3179 !list_empty(&area->free_list[MIGRATE_CMA])) {
3195 return true; 3180 return true;
3181 }
3196#endif 3182#endif
3197 if (alloc_harder && 3183 if (alloc_harder &&
3198 !list_empty(&area->free_list[MIGRATE_HIGHATOMIC])) 3184 !list_empty(&area->free_list[MIGRATE_HIGHATOMIC]))
@@ -3212,6 +3198,13 @@ static inline bool zone_watermark_fast(struct zone *z, unsigned int order,
3212 unsigned long mark, int classzone_idx, unsigned int alloc_flags) 3198 unsigned long mark, int classzone_idx, unsigned int alloc_flags)
3213{ 3199{
3214 long free_pages = zone_page_state(z, NR_FREE_PAGES); 3200 long free_pages = zone_page_state(z, NR_FREE_PAGES);
3201 long cma_pages = 0;
3202
3203#ifdef CONFIG_CMA
3204 /* If allocation can't use CMA areas don't use free CMA pages */
3205 if (!(alloc_flags & ALLOC_CMA))
3206 cma_pages = zone_page_state(z, NR_FREE_CMA_PAGES);
3207#endif
3215 3208
3216 /* 3209 /*
3217 * Fast check for order-0 only. If this fails then the reserves 3210 * Fast check for order-0 only. If this fails then the reserves
@@ -3220,7 +3213,7 @@ static inline bool zone_watermark_fast(struct zone *z, unsigned int order,
3220 * the caller is !atomic then it'll uselessly search the free 3213 * the caller is !atomic then it'll uselessly search the free
3221 * list. That corner case is then slower but it is harmless. 3214 * list. That corner case is then slower but it is harmless.
3222 */ 3215 */
3223 if (!order && free_pages > mark + z->lowmem_reserve[classzone_idx]) 3216 if (!order && (free_pages - cma_pages) > mark + z->lowmem_reserve[classzone_idx])
3224 return true; 3217 return true;
3225 3218
3226 return __zone_watermark_ok(z, order, mark, classzone_idx, alloc_flags, 3219 return __zone_watermark_ok(z, order, mark, classzone_idx, alloc_flags,
@@ -3856,6 +3849,10 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
3856 } else if (unlikely(rt_task(current)) && !in_interrupt()) 3849 } else if (unlikely(rt_task(current)) && !in_interrupt())
3857 alloc_flags |= ALLOC_HARDER; 3850 alloc_flags |= ALLOC_HARDER;
3858 3851
3852#ifdef CONFIG_CMA
3853 if (gfpflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
3854 alloc_flags |= ALLOC_CMA;
3855#endif
3859 return alloc_flags; 3856 return alloc_flags;
3860} 3857}
3861 3858
@@ -4322,6 +4319,9 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order,
4322 if (should_fail_alloc_page(gfp_mask, order)) 4319 if (should_fail_alloc_page(gfp_mask, order))
4323 return false; 4320 return false;
4324 4321
4322 if (IS_ENABLED(CONFIG_CMA) && ac->migratetype == MIGRATE_MOVABLE)
4323 *alloc_flags |= ALLOC_CMA;
4324
4325 return true; 4325 return true;
4326} 4326}
4327 4327
@@ -6204,7 +6204,6 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat)
6204{ 6204{
6205 enum zone_type j; 6205 enum zone_type j;
6206 int nid = pgdat->node_id; 6206 int nid = pgdat->node_id;
6207 unsigned long node_end_pfn = 0;
6208 6207
6209 pgdat_resize_init(pgdat); 6208 pgdat_resize_init(pgdat);
6210#ifdef CONFIG_NUMA_BALANCING 6209#ifdef CONFIG_NUMA_BALANCING
@@ -6232,13 +6231,9 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat)
6232 struct zone *zone = pgdat->node_zones + j; 6231 struct zone *zone = pgdat->node_zones + j;
6233 unsigned long size, realsize, freesize, memmap_pages; 6232 unsigned long size, realsize, freesize, memmap_pages;
6234 unsigned long zone_start_pfn = zone->zone_start_pfn; 6233 unsigned long zone_start_pfn = zone->zone_start_pfn;
6235 unsigned long movable_size = 0;
6236 6234
6237 size = zone->spanned_pages; 6235 size = zone->spanned_pages;
6238 realsize = freesize = zone->present_pages; 6236 realsize = freesize = zone->present_pages;
6239 if (zone_end_pfn(zone) > node_end_pfn)
6240 node_end_pfn = zone_end_pfn(zone);
6241
6242 6237
6243 /* 6238 /*
6244 * Adjust freesize so that it accounts for how much memory 6239 * Adjust freesize so that it accounts for how much memory
@@ -6287,30 +6282,12 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat)
6287 zone_seqlock_init(zone); 6282 zone_seqlock_init(zone);
6288 zone_pcp_init(zone); 6283 zone_pcp_init(zone);
6289 6284
6290 /* 6285 if (!size)
6291 * The size of the CMA area is unknown now so we need to
6292 * prepare the memory for the usemap at maximum.
6293 */
6294 if (IS_ENABLED(CONFIG_CMA) && j == ZONE_MOVABLE &&
6295 pgdat->node_spanned_pages) {
6296 movable_size = node_end_pfn - pgdat->node_start_pfn;
6297 }
6298
6299 if (!size && !movable_size)
6300 continue; 6286 continue;
6301 6287
6302 set_pageblock_order(); 6288 set_pageblock_order();
6303 if (movable_size) { 6289 setup_usemap(pgdat, zone, zone_start_pfn, size);
6304 zone->zone_start_pfn = pgdat->node_start_pfn; 6290 init_currently_empty_zone(zone, zone_start_pfn, size);
6305 zone->spanned_pages = movable_size;
6306 setup_usemap(pgdat, zone,
6307 pgdat->node_start_pfn, movable_size);
6308 init_currently_empty_zone(zone,
6309 pgdat->node_start_pfn, movable_size);
6310 } else {
6311 setup_usemap(pgdat, zone, zone_start_pfn, size);
6312 init_currently_empty_zone(zone, zone_start_pfn, size);
6313 }
6314 memmap_init(size, nid, j, zone_start_pfn); 6291 memmap_init(size, nid, j, zone_start_pfn);
6315 } 6292 }
6316} 6293}
@@ -7951,7 +7928,7 @@ void free_contig_range(unsigned long pfn, unsigned nr_pages)
7951} 7928}
7952#endif 7929#endif
7953 7930
7954#if defined CONFIG_MEMORY_HOTPLUG || defined CONFIG_CMA 7931#ifdef CONFIG_MEMORY_HOTPLUG
7955/* 7932/*
7956 * The zone indicated has a new number of managed_pages; batch sizes and percpu 7933 * The zone indicated has a new number of managed_pages; batch sizes and percpu
7957 * page high values need to be recalulated. 7934 * page high values need to be recalulated.