diff -urN oldtree/include/linux/mmzone.h newtree/include/linux/mmzone.h --- oldtree/include/linux/mmzone.h 2006-09-24 17:03:56.000000000 -0400 +++ newtree/include/linux/mmzone.h 2006-09-26 15:14:15.000000000 -0400 @@ -174,7 +174,7 @@ struct zone { /* Fields commonly accessed by the page allocator */ unsigned long free_pages; - unsigned long pages_min, pages_low, pages_high; + unsigned long pages_min, pages_low, pages_high, pages_lots; /* * We don't know if the memory that we're going to allocate will be freeable * or/and it will be released eventually, so to avoid totally wasting several diff -urN oldtree/mm/page_alloc.c newtree/mm/page_alloc.c --- oldtree/mm/page_alloc.c 2006-09-24 17:03:56.000000000 -0400 +++ newtree/mm/page_alloc.c 2006-09-26 15:14:15.000000000 -0400 @@ -1445,6 +1445,7 @@ " min:%lukB" " low:%lukB" " high:%lukB" + " lots:%lukB" " active:%lukB" " inactive:%lukB" " present:%lukB" @@ -1456,6 +1457,7 @@ K(zone->pages_min), K(zone->pages_low), K(zone->pages_high), + K(zone->pages_lots), K(zone->nr_active), K(zone->nr_inactive), K(zone->present_pages), @@ -2971,6 +2973,7 @@ zone->pages_low = zone->pages_min + (tmp >> 2); zone->pages_high = zone->pages_min + (tmp >> 1); + zone->pages_lots = zone->pages_min + tmp; spin_unlock_irqrestore(&zone->lru_lock, flags); } diff -urN oldtree/mm/vmscan.c newtree/mm/vmscan.c --- oldtree/mm/vmscan.c 2006-09-26 15:14:04.000000000 -0400 +++ newtree/mm/vmscan.c 2006-09-26 15:14:15.000000000 -0400 @@ -1145,6 +1145,7 @@ */ for (i = pgdat->nr_zones - 1; i >= 0; i--) { struct zone *zone = pgdat->node_zones + i; + unsigned long watermark; if (!populated_zone(zone)) continue; @@ -1152,11 +1153,18 @@ if (zone->all_unreclaimable && priority != DEF_PRIORITY) continue; - if (!zone_watermark_ok(zone, order, zone->pages_high, - 0, 0)) { + /* + * The watermark is relaxed depending on the + * level of "priority" till it drops to + * pages_high. + */ + watermark = zone->pages_high + (zone->pages_high * + priority / DEF_PRIORITY); + if (!zone_watermark_ok(zone, order, watermark, 0, 0)) { end_zone = i; goto scan; } + } goto out; scan: @@ -1178,6 +1186,7 @@ for (i = 0; i <= end_zone; i++) { struct zone *zone = pgdat->node_zones + i; int nr_slab; + unsigned long watermark; if (!populated_zone(zone)) continue; @@ -1185,7 +1194,10 @@ if (zone->all_unreclaimable && priority != DEF_PRIORITY) continue; - if (!zone_watermark_ok(zone, order, zone->pages_high, + watermark = zone->pages_high + (zone->pages_high * + priority / DEF_PRIORITY); + + if (!zone_watermark_ok(zone, order, watermark, end_zone, 0)) all_zones_ok = 0; zone->temp_priority = priority; Files oldtree/scripts/kconfig/mconf and newtree/scripts/kconfig/mconf differ