* pages
         */
        COMPACT_PARTIAL,
-       /* The full zone was compacted */
+       /*
+        * direct compaction has scanned part of the zone but wasn't successfull
+        * to compact suitable pages.
+        */
+       COMPACT_PARTIAL_SKIPPED,
+       /*
+        * The full zone was compacted scanned but wasn't successfull to compact
+        * suitable pages.
+        */
        COMPACT_COMPLETE,
        /* For more detailed tracepoint output */
        COMPACT_NO_SUITABLE_PAGE,
 
        EM( COMPACT_DEFERRED,           "deferred")             \
        EM( COMPACT_CONTINUE,           "continue")             \
        EM( COMPACT_PARTIAL,            "partial")              \
+       EM( COMPACT_PARTIAL_SKIPPED,    "partial_skipped")      \
        EM( COMPACT_COMPLETE,           "complete")             \
        EM( COMPACT_NO_SUITABLE_PAGE,   "no_suitable_page")     \
        EM( COMPACT_NOT_SUITABLE_ZONE,  "not_suitable_zone")    \
 
                if (cc->direct_compaction)
                        zone->compact_blockskip_flush = true;
 
-               return COMPACT_COMPLETE;
+               if (cc->whole_zone)
+                       return COMPACT_COMPLETE;
+               else
+                       return COMPACT_PARTIAL_SKIPPED;
        }
 
        if (is_via_compact_memory(cc->order))
                zone->compact_cached_migrate_pfn[0] = cc->migrate_pfn;
                zone->compact_cached_migrate_pfn[1] = cc->migrate_pfn;
        }
+
+       if (cc->migrate_pfn == start_pfn)
+               cc->whole_zone = true;
+
        cc->last_migrated_pfn = 0;
 
        trace_mm_compaction_begin(start_pfn, cc->migrate_pfn,
                        goto break_loop;
                }
 
-               if (mode != MIGRATE_ASYNC && status == COMPACT_COMPLETE) {
+               if (mode != MIGRATE_ASYNC && (status == COMPACT_COMPLETE ||
+                                       status == COMPACT_PARTIAL_SKIPPED)) {
                        /*
                         * We think that allocation won't succeed in this zone
                         * so we defer compaction there. If it ends up
                                                cc.classzone_idx, 0)) {
                        success = true;
                        compaction_defer_reset(zone, cc.order, false);
-               } else if (status == COMPACT_COMPLETE) {
+               } else if (status == COMPACT_PARTIAL_SKIPPED || status == COMPACT_COMPLETE) {
                        /*
                         * We use sync migration mode here, so we defer like
                         * sync direct compaction does.
 
        enum migrate_mode mode;         /* Async or sync migration mode */
        bool ignore_skip_hint;          /* Scan blocks even if marked skip */
        bool direct_compaction;         /* False from kcompactd or /proc/... */
+       bool whole_zone;                /* Whole zone has been scanned */
        int order;                      /* order a direct compactor needs */
        const gfp_t gfp_mask;           /* gfp mask of a direct compactor */
        const unsigned int alloc_flags; /* alloc flags of a direct compactor */