|
@@ -1743,38 +1743,16 @@ void __init page_alloc_init_late(void)
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_CMA
|
|
|
-static void __init adjust_present_page_count(struct page *page, long count)
|
|
|
-{
|
|
|
- struct zone *zone = page_zone(page);
|
|
|
-
|
|
|
- /* We don't need to hold a lock since it is boot-up process */
|
|
|
- zone->present_pages += count;
|
|
|
-}
|
|
|
-
|
|
|
/* Free whole pageblock and set its migration type to MIGRATE_CMA. */
|
|
|
void __init init_cma_reserved_pageblock(struct page *page)
|
|
|
{
|
|
|
unsigned i = pageblock_nr_pages;
|
|
|
- unsigned long pfn = page_to_pfn(page);
|
|
|
struct page *p = page;
|
|
|
- int nid = page_to_nid(page);
|
|
|
-
|
|
|
- /*
|
|
|
- * ZONE_MOVABLE will steal present pages from other zones by
|
|
|
- * changing page links so page_zone() is changed. Before that,
|
|
|
- * we need to adjust previous zone's page count first.
|
|
|
- */
|
|
|
- adjust_present_page_count(page, -pageblock_nr_pages);
|
|
|
|
|
|
do {
|
|
|
__ClearPageReserved(p);
|
|
|
set_page_count(p, 0);
|
|
|
-
|
|
|
- /* Steal pages from other zones */
|
|
|
- set_page_links(p, ZONE_MOVABLE, nid, pfn);
|
|
|
- } while (++p, ++pfn, --i);
|
|
|
-
|
|
|
- adjust_present_page_count(page, pageblock_nr_pages);
|
|
|
+ } while (++p, --i);
|
|
|
|
|
|
set_pageblock_migratetype(page, MIGRATE_CMA);
|
|
|
|
|
@@ -2889,7 +2867,7 @@ int __isolate_free_page(struct page *page, unsigned int order)
|
|
|
* exists.
|
|
|
*/
|
|
|
watermark = min_wmark_pages(zone) + (1UL << order);
|
|
|
- if (!zone_watermark_ok(zone, 0, watermark, 0, 0))
|
|
|
+ if (!zone_watermark_ok(zone, 0, watermark, 0, ALLOC_CMA))
|
|
|
return 0;
|
|
|
|
|
|
__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,
|
|
|
}
|
|
|
|
|
|
|
|
|
+#ifdef CONFIG_CMA
|
|
|
+ /* If allocation can't use CMA areas don't use free CMA pages */
|
|
|
+ if (!(alloc_flags & ALLOC_CMA))
|
|
|
+ free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES);
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Check watermarks for an order-0 allocation request. If these
|
|
|
* 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,
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_CMA
|
|
|
- if (!list_empty(&area->free_list[MIGRATE_CMA]))
|
|
|
+ if ((alloc_flags & ALLOC_CMA) &&
|
|
|
+ !list_empty(&area->free_list[MIGRATE_CMA])) {
|
|
|
return true;
|
|
|
+ }
|
|
|
#endif
|
|
|
if (alloc_harder &&
|
|
|
!list_empty(&area->free_list[MIGRATE_HIGHATOMIC]))
|
|
@@ -3212,6 +3198,13 @@ static inline bool zone_watermark_fast(struct zone *z, unsigned int order,
|
|
|
unsigned long mark, int classzone_idx, unsigned int alloc_flags)
|
|
|
{
|
|
|
long free_pages = zone_page_state(z, NR_FREE_PAGES);
|
|
|
+ long cma_pages = 0;
|
|
|
+
|
|
|
+#ifdef CONFIG_CMA
|
|
|
+ /* If allocation can't use CMA areas don't use free CMA pages */
|
|
|
+ if (!(alloc_flags & ALLOC_CMA))
|
|
|
+ cma_pages = zone_page_state(z, NR_FREE_CMA_PAGES);
|
|
|
+#endif
|
|
|
|
|
|
/*
|
|
|
* 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,
|
|
|
* the caller is !atomic then it'll uselessly search the free
|
|
|
* list. That corner case is then slower but it is harmless.
|
|
|
*/
|
|
|
- if (!order && free_pages > mark + z->lowmem_reserve[classzone_idx])
|
|
|
+ if (!order && (free_pages - cma_pages) > mark + z->lowmem_reserve[classzone_idx])
|
|
|
return true;
|
|
|
|
|
|
return __zone_watermark_ok(z, order, mark, classzone_idx, alloc_flags,
|
|
@@ -3856,6 +3849,10 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
|
|
|
} else if (unlikely(rt_task(current)) && !in_interrupt())
|
|
|
alloc_flags |= ALLOC_HARDER;
|
|
|
|
|
|
+#ifdef CONFIG_CMA
|
|
|
+ if (gfpflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
|
|
|
+ alloc_flags |= ALLOC_CMA;
|
|
|
+#endif
|
|
|
return alloc_flags;
|
|
|
}
|
|
|
|
|
@@ -4322,6 +4319,9 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order,
|
|
|
if (should_fail_alloc_page(gfp_mask, order))
|
|
|
return false;
|
|
|
|
|
|
+ if (IS_ENABLED(CONFIG_CMA) && ac->migratetype == MIGRATE_MOVABLE)
|
|
|
+ *alloc_flags |= ALLOC_CMA;
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -6204,7 +6204,6 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat)
|
|
|
{
|
|
|
enum zone_type j;
|
|
|
int nid = pgdat->node_id;
|
|
|
- unsigned long node_end_pfn = 0;
|
|
|
|
|
|
pgdat_resize_init(pgdat);
|
|
|
#ifdef CONFIG_NUMA_BALANCING
|
|
@@ -6232,13 +6231,9 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat)
|
|
|
struct zone *zone = pgdat->node_zones + j;
|
|
|
unsigned long size, realsize, freesize, memmap_pages;
|
|
|
unsigned long zone_start_pfn = zone->zone_start_pfn;
|
|
|
- unsigned long movable_size = 0;
|
|
|
|
|
|
size = zone->spanned_pages;
|
|
|
realsize = freesize = zone->present_pages;
|
|
|
- if (zone_end_pfn(zone) > node_end_pfn)
|
|
|
- node_end_pfn = zone_end_pfn(zone);
|
|
|
-
|
|
|
|
|
|
/*
|
|
|
* 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)
|
|
|
zone_seqlock_init(zone);
|
|
|
zone_pcp_init(zone);
|
|
|
|
|
|
- /*
|
|
|
- * The size of the CMA area is unknown now so we need to
|
|
|
- * prepare the memory for the usemap at maximum.
|
|
|
- */
|
|
|
- if (IS_ENABLED(CONFIG_CMA) && j == ZONE_MOVABLE &&
|
|
|
- pgdat->node_spanned_pages) {
|
|
|
- movable_size = node_end_pfn - pgdat->node_start_pfn;
|
|
|
- }
|
|
|
-
|
|
|
- if (!size && !movable_size)
|
|
|
+ if (!size)
|
|
|
continue;
|
|
|
|
|
|
set_pageblock_order();
|
|
|
- if (movable_size) {
|
|
|
- zone->zone_start_pfn = pgdat->node_start_pfn;
|
|
|
- zone->spanned_pages = movable_size;
|
|
|
- setup_usemap(pgdat, zone,
|
|
|
- pgdat->node_start_pfn, movable_size);
|
|
|
- init_currently_empty_zone(zone,
|
|
|
- pgdat->node_start_pfn, movable_size);
|
|
|
- } else {
|
|
|
- setup_usemap(pgdat, zone, zone_start_pfn, size);
|
|
|
- init_currently_empty_zone(zone, zone_start_pfn, size);
|
|
|
- }
|
|
|
+ setup_usemap(pgdat, zone, zone_start_pfn, size);
|
|
|
+ init_currently_empty_zone(zone, zone_start_pfn, size);
|
|
|
memmap_init(size, nid, j, zone_start_pfn);
|
|
|
}
|
|
|
}
|
|
@@ -7951,7 +7928,7 @@ void free_contig_range(unsigned long pfn, unsigned nr_pages)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-#if defined CONFIG_MEMORY_HOTPLUG || defined CONFIG_CMA
|
|
|
+#ifdef CONFIG_MEMORY_HOTPLUG
|
|
|
/*
|
|
|
* The zone indicated has a new number of managed_pages; batch sizes and percpu
|
|
|
* page high values need to be recalulated.
|