extern unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *mask,
                        enum migrate_mode mode, int *contended,
+                       int alloc_flags, int classzone_idx,
                        struct zone **candidate_zone);
 extern void compact_pgdat(pg_data_t *pgdat, int order);
 extern void reset_isolation_suitable(pg_data_t *pgdat);
-extern unsigned long compaction_suitable(struct zone *zone, int order);
+extern unsigned long compaction_suitable(struct zone *zone, int order,
+                                       int alloc_flags, int classzone_idx);
 
 /* Do not skip compaction more than 64 times */
 #define COMPACT_MAX_DEFER_SHIFT 6
 static inline unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *nodemask,
                        enum migrate_mode mode, int *contended,
+                       int alloc_flags, int classzone_idx,
                        struct zone **candidate_zone)
 {
        return COMPACT_CONTINUE;
 {
 }
 
-static inline unsigned long compaction_suitable(struct zone *zone, int order)
+static inline unsigned long compaction_suitable(struct zone *zone, int order,
+                                       int alloc_flags, int classzone_idx)
 {
        return COMPACT_SKIPPED;
 }
 
 
        /* Compaction run is not finished if the watermark is not met */
        watermark = low_wmark_pages(zone);
-       watermark += (1 << cc->order);
 
-       if (!zone_watermark_ok(zone, cc->order, watermark, 0, 0))
+       if (!zone_watermark_ok(zone, cc->order, watermark, cc->classzone_idx,
+                                                       cc->alloc_flags))
                return COMPACT_CONTINUE;
 
        /* Direct compactor: Is a suitable page free? */
  *   COMPACT_PARTIAL  - If the allocation would succeed without compaction
  *   COMPACT_CONTINUE - If compaction should run now
  */
-unsigned long compaction_suitable(struct zone *zone, int order)
+unsigned long compaction_suitable(struct zone *zone, int order,
+                                       int alloc_flags, int classzone_idx)
 {
        int fragindex;
        unsigned long watermark;
        if (order == -1)
                return COMPACT_CONTINUE;
 
+       watermark = low_wmark_pages(zone);
+       /*
+        * If watermarks for high-order allocation are already met, there
+        * should be no need for compaction at all.
+        */
+       if (zone_watermark_ok(zone, order, watermark, classzone_idx,
+                                                               alloc_flags))
+               return COMPACT_PARTIAL;
+
        /*
         * Watermarks for order-0 must be met for compaction. Note the 2UL.
         * This is because during migration, copies of pages need to be
         * allocated and for a short time, the footprint is higher
         */
-       watermark = low_wmark_pages(zone) + (2UL << order);
-       if (!zone_watermark_ok(zone, 0, watermark, 0, 0))
+       watermark += (2UL << order);
+       if (!zone_watermark_ok(zone, 0, watermark, classzone_idx, alloc_flags))
                return COMPACT_SKIPPED;
 
        /*
         * fragmentation index determines if allocation failures are due to
         * low memory or external fragmentation
         *
-        * index of -1000 implies allocations might succeed depending on
-        * watermarks
+        * index of -1000 would imply allocations might succeed depending on
+        * watermarks, but we already failed the high-order watermark check
         * index towards 0 implies failure is due to lack of memory
         * index towards 1000 implies failure is due to fragmentation
         *
        if (fragindex >= 0 && fragindex <= sysctl_extfrag_threshold)
                return COMPACT_SKIPPED;
 
-       if (fragindex == -1000 && zone_watermark_ok(zone, order, watermark,
-           0, 0))
-               return COMPACT_PARTIAL;
-
        return COMPACT_CONTINUE;
 }
 
        const int migratetype = gfpflags_to_migratetype(cc->gfp_mask);
        const bool sync = cc->mode != MIGRATE_ASYNC;
 
-       ret = compaction_suitable(zone, cc->order);
+       ret = compaction_suitable(zone, cc->order, cc->alloc_flags,
+                                                       cc->classzone_idx);
        switch (ret) {
        case COMPACT_PARTIAL:
        case COMPACT_SKIPPED:
 }
 
 static unsigned long compact_zone_order(struct zone *zone, int order,
-               gfp_t gfp_mask, enum migrate_mode mode, int *contended)
+               gfp_t gfp_mask, enum migrate_mode mode, int *contended,
+               int alloc_flags, int classzone_idx)
 {
        unsigned long ret;
        struct compact_control cc = {
                .gfp_mask = gfp_mask,
                .zone = zone,
                .mode = mode,
+               .alloc_flags = alloc_flags,
+               .classzone_idx = classzone_idx,
        };
        INIT_LIST_HEAD(&cc.freepages);
        INIT_LIST_HEAD(&cc.migratepages);
 unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *nodemask,
                        enum migrate_mode mode, int *contended,
+                       int alloc_flags, int classzone_idx,
                        struct zone **candidate_zone)
 {
        enum zone_type high_zoneidx = gfp_zone(gfp_mask);
        struct zoneref *z;
        struct zone *zone;
        int rc = COMPACT_DEFERRED;
-       int alloc_flags = 0;
        int all_zones_contended = COMPACT_CONTENDED_LOCK; /* init for &= op */
 
        *contended = COMPACT_CONTENDED_NONE;
        if (!order || !may_enter_fs || !may_perform_io)
                return COMPACT_SKIPPED;
 
-#ifdef CONFIG_CMA
-       if (gfpflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
-               alloc_flags |= ALLOC_CMA;
-#endif
        /* Compact each zone in the list */
        for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx,
                                                                nodemask) {
                        continue;
 
                status = compact_zone_order(zone, order, gfp_mask, mode,
-                                                       &zone_contended);
+                               &zone_contended, alloc_flags, classzone_idx);
                rc = max(status, rc);
                /*
                 * It takes at least one zone that wasn't lock contended
                all_zones_contended &= zone_contended;
 
                /* If a normal allocation would succeed, stop compacting */
-               if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0,
-                                     alloc_flags)) {
+               if (zone_watermark_ok(zone, order, low_wmark_pages(zone),
+                                       classzone_idx, alloc_flags)) {
                        *candidate_zone = zone;
                        /*
                         * We think the allocation will succeed in this zone,
 
                return true;
 
        /* If compaction would go ahead or the allocation would succeed, stop */
-       switch (compaction_suitable(zone, sc->order)) {
+       switch (compaction_suitable(zone, sc->order, 0, 0)) {
        case COMPACT_PARTIAL:
        case COMPACT_CONTINUE:
                return false;
         * If compaction is not ready to start and allocation is not likely
         * to succeed without it, then keep reclaiming.
         */
-       if (compaction_suitable(zone, order) == COMPACT_SKIPPED)
+       if (compaction_suitable(zone, order, 0, 0) == COMPACT_SKIPPED)
                return false;
 
        return watermark_ok;
                                    balance_gap, classzone_idx, 0))
                return false;
 
-       if (IS_ENABLED(CONFIG_COMPACTION) && order &&
-           compaction_suitable(zone, order) == COMPACT_SKIPPED)
+       if (IS_ENABLED(CONFIG_COMPACTION) && order && compaction_suitable(zone,
+                               order, 0, classzone_idx) == COMPACT_SKIPPED)
                return false;
 
        return true;
         * from memory. Do not reclaim more than needed for compaction.
         */
        if (IS_ENABLED(CONFIG_COMPACTION) && sc->order &&
-                       compaction_suitable(zone, sc->order) !=
-                               COMPACT_SKIPPED)
+                       compaction_suitable(zone, sc->order, 0, classzone_idx)
+                                                       != COMPACT_SKIPPED)
                testorder = 0;
 
        /*