return min(batch << 2, pcp->high);
        }
 
-       if (pcp->count >= high && high_min != high_max) {
+       if (high_min == high_max)
+               return high;
+
+       if (test_bit(ZONE_BELOW_HIGH, &zone->flags)) {
+               pcp->high = max(high - (batch << pcp->free_factor), high_min);
+               high = max(pcp->count, high_min);
+       } else if (pcp->count >= high) {
                int need_high = (batch << pcp->free_factor) + batch;
 
                /* pcp->high should be large enough to hold batch freed pages */
        if (pcp->count >= high) {
                free_pcppages_bulk(zone, nr_pcp_free(pcp, batch, high, free_high),
                                   pcp, pindex);
+               if (test_bit(ZONE_BELOW_HIGH, &zone->flags) &&
+                   zone_watermark_ok(zone, 0, high_wmark_pages(zone),
+                                     ZONE_MOVABLE, 0))
+                       clear_bit(ZONE_BELOW_HIGH, &zone->flags);
        }
 }
 
         * If we had larger pcp->high, we could avoid to allocate from
         * zone.
         */
-       if (high_min != high_max && !test_bit(ZONE_RECLAIM_ACTIVE, &zone->flags))
+       if (high_min != high_max && !test_bit(ZONE_BELOW_HIGH, &zone->flags))
                high = pcp->high = min(high + batch, high_max);
 
        if (!order) {
                        }
                }
 
+               /*
+                * Detect whether the number of free pages is below high
+                * watermark.  If so, we will decrease pcp->high and free
+                * PCP pages in free path to reduce the possibility of
+                * premature page reclaiming.  Detection is done here to
+                * avoid to do that in hotter free path.
+                */
+               if (test_bit(ZONE_BELOW_HIGH, &zone->flags))
+                       goto check_alloc_wmark;
+
+               mark = high_wmark_pages(zone);
+               if (zone_watermark_fast(zone, order, mark,
+                                       ac->highest_zoneidx, alloc_flags,
+                                       gfp_mask))
+                       goto try_this_zone;
+               else
+                       set_bit(ZONE_BELOW_HIGH, &zone->flags);
+
+check_alloc_wmark:
                mark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK);
                if (!zone_watermark_fast(zone, order, mark,
                                       ac->highest_zoneidx, alloc_flags,