summaryrefslogtreecommitdiff
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorHeesub Shin <heesub.shin@samsung.com>2013-01-07 11:10:13 +0900
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-13 11:11:30 -0700
commitd491cf59f01c82ba8c91ff80d984a1bee9186b0d (patch)
tree68c98c95d566ea475247265b7c1c690e79b786fd /mm/page_alloc.c
parent59a8d2507c667b6973135d882278a119dca09454 (diff)
cma: redirect page allocation to CMA
CMA pages are designed to be used as fallback for movable allocations and cannot be used for non-movable allocations. If CMA pages are utilized poorly, non-movable allocations may end up getting starved if all regular movable pages are allocated and the only pages left are CMA. Always using CMA pages first creates unacceptable performance problems. As a midway alternative, use CMA pages for certain userspace allocations. The userspace pages can be migrated or dropped quickly which giving decent utilization. Change-Id: I6165dda01b705309eebabc6dfa67146b7a95c174 CRs-Fixed: 452508 Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Heesub Shin <heesub.shin@samsung.com [lauraa@codeaurora.org: Missing CONFIG_CMA guards, add commit text] Signed-off-by: Laura Abbott <lauraa@codeaurora.org> [lmark@codeaurora.org: resolve conflicts relating to MIGRATE_HIGHATOMIC and some other trivial merge conflicts] Signed-off-by: Liam Mark <lmark@codeaurora.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1eafd75f402e..2695ca00653e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1815,11 +1815,26 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order,
page = __rmqueue_smallest(zone, order, migratetype);
if (unlikely(!page)) {
- if (migratetype == MIGRATE_MOVABLE)
- page = __rmqueue_cma_fallback(zone, order);
+ page = __rmqueue_fallback(zone, order, migratetype);
+ }
- if (!page)
- page = __rmqueue_fallback(zone, order, migratetype);
+ trace_mm_page_alloc_zone_locked(page, order, migratetype);
+ return page;
+}
+
+static struct page *__rmqueue_cma(struct zone *zone, unsigned int order,
+ int migratetype, gfp_t gfp_flags)
+{
+ struct page *page = 0;
+#ifdef CONFIG_CMA
+ if (migratetype == MIGRATE_MOVABLE && !zone->cma_alloc)
+ page = __rmqueue_cma_fallback(zone, order);
+ else
+#endif
+ page = __rmqueue_smallest(zone, order, migratetype);
+
+ if (unlikely(!page)) {
+ page = __rmqueue_fallback(zone, order, migratetype);
}
trace_mm_page_alloc_zone_locked(page, order, migratetype);
@@ -1833,13 +1848,17 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order,
*/
static int rmqueue_bulk(struct zone *zone, unsigned int order,
unsigned long count, struct list_head *list,
- int migratetype, bool cold)
+ int migratetype, bool cold, int cma)
{
int i;
spin_lock(&zone->lock);
for (i = 0; i < count; ++i) {
- struct page *page = __rmqueue(zone, order, migratetype, 0);
+ struct page *page;
+ if (cma)
+ page = __rmqueue_cma(zone, order, migratetype, 0);
+ else
+ page = __rmqueue(zone, order, migratetype, 0);
if (unlikely(page == NULL))
break;
@@ -2229,7 +2248,8 @@ struct page *buffered_rmqueue(struct zone *preferred_zone,
if (list_empty(list)) {
pcp->count += rmqueue_bulk(zone, 0,
pcp->batch, list,
- migratetype, cold);
+ migratetype, cold,
+ gfp_flags & __GFP_CMA);
if (unlikely(list_empty(list)))
goto failed;
}
@@ -2263,8 +2283,13 @@ struct page *buffered_rmqueue(struct zone *preferred_zone,
if (page)
trace_mm_page_alloc_zone_locked(page, order, migratetype);
}
- if (!page)
+ if (!page) {
+ if (gfp_flags & __GFP_CMA)
+ page = __rmqueue_cma(zone, order, migratetype, gfp_flags);
+ else
page = __rmqueue(zone, order, migratetype, gfp_flags);
+
+ }
spin_unlock(&zone->lock);
if (!page)
goto failed;
@@ -6753,6 +6778,8 @@ int alloc_contig_range(unsigned long start, unsigned long end,
if (ret)
return ret;
+ cc.zone->cma_alloc = 1;
+
ret = __alloc_contig_migrate_range(&cc, start, end);
if (ret)
goto done;
@@ -6811,6 +6838,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
done:
undo_isolate_page_range(pfn_max_align_down(start),
pfn_max_align_up(end), migratetype);
+ cc.zone->cma_alloc = 0;
return ret;
}