Index: linux-2.6.8.1-ck/mm/page_alloc.c =================================================================== --- linux-2.6.8.1-ck.orig/mm/page_alloc.c 2004-08-23 13:19:02.000000000 +1000 +++ linux-2.6.8.1-ck/mm/page_alloc.c 2004-08-25 23:30:54.000000000 +1000 @@ -725,8 +725,9 @@ __alloc_pages(unsigned int gfp_mask, uns */ if (rt_task(p)) min -= z->pages_low >> 1; - else - if (wait && z->free_pages < z->pages_unmapped) + else if (vm_mapped && wait && + z->free_pages < z->pages_unmapped && + z->free_pages > z->pages_low) wakeup_kswapd(z); if (z->free_pages >= min || Index: linux-2.6.8.1-ck/mm/vmscan.c =================================================================== --- linux-2.6.8.1-ck.orig/mm/vmscan.c 2004-08-25 21:27:13.000000000 +1000 +++ linux-2.6.8.1-ck/mm/vmscan.c 2004-08-25 23:32:38.000000000 +1000 @@ -966,6 +966,20 @@ static int balance_pgdat(pg_data_t *pgda sc.may_writepage = 0; sc.nr_mapped = read_page_state(nr_mapped); + /* + * Sanity check to ensure we don't have a stale maplimit set + * and are calling balance_pgdat for a different reason. + */ + if (nr_pages) + maplimit = 0; + /* + * kswapd does a light balance_pgdat() when there is less than 1/3 + * ram free provided there is less than vm_mapped % of that ram + * mapped. + */ + if (maplimit && sc.nr_mapped * 100 / total_memory > vm_mapped) + return 0; + inc_page_state(pageoutrun); for (i = 0; i < pgdat->nr_zones; i++) { @@ -978,15 +992,13 @@ static int balance_pgdat(pg_data_t *pgda int all_zones_ok = 1; int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */ unsigned long lru_pages = 0; - int mapped_ratio = sc.nr_mapped * 100 / total_memory; - if (maplimit && (mapped_ratio > vm_mapped || - priority < DEF_PRIORITY)) - /* - * Evict pages only if mapped_ratio < vm_mapped and - * only do low priority scanning. - */ - goto out; + /* + * Only do low priority scanning if we're here due to + * mapped watermark. + */ + if (maplimit && priority < DEF_PRIORITY) + goto out; if (nr_pages == 0) { /* * Scan in the highmem->dma direction for the highest @@ -1142,12 +1154,13 @@ int kswapd(void *p) void wakeup_kswapd(struct zone *zone) { if (zone->free_pages > zone->pages_unmapped) - return; + goto out; if (zone->free_pages > zone->pages_low) zone->zone_pgdat->maplimit = 1; if (!waitqueue_active(&zone->zone_pgdat->kswapd_wait)) - return; + goto out; wake_up_interruptible(&zone->zone_pgdat->kswapd_wait); +out: zone->zone_pgdat->maplimit = 0; }