If page alloc function __rmqueue try to get pages from MIGRATE_MOVABLE and
conditions (cma_alloc_counter, cma_aggressive_free_min, cma_alloc_counter)
allow, MIGRATE_CMA will be allocated as MIGRATE_MOVABLE first.

Signed-off-by: Hui Zhu <zhu...@xiaomi.com>
---
 mm/page_alloc.c | 42 +++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 736d8e1..87bc326 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -65,6 +65,10 @@
 #include <asm/div64.h>
 #include "internal.h"
 
+#ifdef CONFIG_CMA_AGGRESSIVE
+#include <linux/cma.h>
+#endif
+
 /* prevent >1 _updater_ of zone percpu pageset ->high and ->batch fields */
 static DEFINE_MUTEX(pcp_batch_high_lock);
 #define MIN_PERCPU_PAGELIST_FRACTION   (8)
@@ -1189,20 +1193,36 @@ static struct page *__rmqueue(struct zone *zone, 
unsigned int order,
 {
        struct page *page;
 
-retry_reserve:
+#ifdef CONFIG_CMA_AGGRESSIVE
+       if (cma_aggressive_switch
+           && migratetype == MIGRATE_MOVABLE
+           && atomic_read(&cma_alloc_counter) == 0
+           && global_page_state(NR_FREE_CMA_PAGES) > cma_aggressive_free_min
+                                                       + (1 << order))
+               migratetype = MIGRATE_CMA;
+#endif
+retry:
        page = __rmqueue_smallest(zone, order, migratetype);
 
-       if (unlikely(!page) && migratetype != MIGRATE_RESERVE) {
-               page = __rmqueue_fallback(zone, order, migratetype);
+       if (unlikely(!page)) {
+#ifdef CONFIG_CMA_AGGRESSIVE
+               if (migratetype == MIGRATE_CMA) {
+                       migratetype = MIGRATE_MOVABLE;
+                       goto retry;
+               }
+#endif
+               if (migratetype != MIGRATE_RESERVE) {
+                       page = __rmqueue_fallback(zone, order, migratetype);
 
-               /*
-                * Use MIGRATE_RESERVE rather than fail an allocation. goto
-                * is used because __rmqueue_smallest is an inline function
-                * and we want just one call site
-                */
-               if (!page) {
-                       migratetype = MIGRATE_RESERVE;
-                       goto retry_reserve;
+                       /*
+                       * Use MIGRATE_RESERVE rather than fail an allocation.
+                       * goto is used because __rmqueue_smallest is an inline
+                       * function and we want just one call site
+                       */
+                       if (!page) {
+                               migratetype = MIGRATE_RESERVE;
+                               goto retry;
+                       }
                }
        }
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to