|
@@ -1462,15 +1462,33 @@ zonelist_scan:
|
|
|
BUILD_BUG_ON(ALLOC_NO_WATERMARKS < NR_WMARK);
|
|
|
if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
|
|
|
unsigned long mark;
|
|
|
+ int ret;
|
|
|
+
|
|
|
mark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK];
|
|
|
- if (!zone_watermark_ok(zone, order, mark,
|
|
|
- classzone_idx, alloc_flags)) {
|
|
|
- if (!zone_reclaim_mode ||
|
|
|
- !zone_reclaim(zone, gfp_mask, order))
|
|
|
+ if (zone_watermark_ok(zone, order, mark,
|
|
|
+ classzone_idx, alloc_flags))
|
|
|
+ goto try_this_zone;
|
|
|
+
|
|
|
+ if (zone_reclaim_mode == 0)
|
|
|
+ goto this_zone_full;
|
|
|
+
|
|
|
+ ret = zone_reclaim(zone, gfp_mask, order);
|
|
|
+ switch (ret) {
|
|
|
+ case ZONE_RECLAIM_NOSCAN:
|
|
|
+ /* did not scan */
|
|
|
+ goto try_next_zone;
|
|
|
+ case ZONE_RECLAIM_FULL:
|
|
|
+ /* scanned but unreclaimable */
|
|
|
+ goto this_zone_full;
|
|
|
+ default:
|
|
|
+ /* did we reclaim enough */
|
|
|
+ if (!zone_watermark_ok(zone, order, mark,
|
|
|
+ classzone_idx, alloc_flags))
|
|
|
goto this_zone_full;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+try_this_zone:
|
|
|
page = buffered_rmqueue(preferred_zone, zone, order,
|
|
|
gfp_mask, migratetype);
|
|
|
if (page)
|