diff -urN ref/include/linux/mm.h 2.3.42aa3-alpha/include/linux/mm.h --- ref/include/linux/mm.h Sun Feb 6 19:28:44 2000 +++ 2.3.42aa3-alpha/include/linux/mm.h Sun Feb 6 19:25:00 2000 @@ -461,7 +461,7 @@ #define __GFP_DMA 0x20 -#define GFP_BUFFER (__GFP_WAIT) +#define GFP_BUFFER (__GFP_HIGH | __GFP_WAIT) #define GFP_ATOMIC (__GFP_HIGH) #define GFP_USER (__GFP_WAIT | __GFP_IO) #define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM) diff -urN ref/include/linux/mmzone.h 2.3.42aa3-alpha/include/linux/mmzone.h --- ref/include/linux/mmzone.h Sun Feb 6 19:28:44 2000 +++ 2.3.42aa3-alpha/include/linux/mmzone.h Sun Feb 6 19:24:37 2000 @@ -29,7 +29,7 @@ unsigned long offset; unsigned long free_pages; int low_on_memory; - unsigned long pages_low, pages_high; + unsigned long pages_min, pages_low, pages_high; struct pglist_data *zone_pgdat; /* diff -urN ref/mm/page_alloc.c 2.3.42aa3-alpha/mm/page_alloc.c --- ref/mm/page_alloc.c Sun Feb 6 19:28:44 2000 +++ 2.3.42aa3-alpha/mm/page_alloc.c Sat Feb 5 22:37:15 2000 @@ -29,7 +29,9 @@ LIST_HEAD(lru_cache); static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; -static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 128 }; +static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 128, }; +static int zone_balance_min[MAX_NR_ZONES] = { 10 , 10, 10, }; +static int zone_balance_max[MAX_NR_ZONES] = { 255 , 255, 255, }; /* * Free_page() adds the page to the free lists. This is optimized for @@ -196,9 +198,6 @@ return NULL; } -#define ZONE_BALANCED(zone) \ - (((zone)->free_pages > (zone)->pages_low) && (!(zone)->low_on_memory)) - static inline unsigned long classfree(zone_t *zone) { unsigned long free = 0; @@ -215,21 +214,6 @@ static inline int zone_balance_memory (zone_t *zone, int gfp_mask) { int freed; - unsigned long free = classfree(zone); - - if (free >= zone->pages_low) { - if (!zone->low_on_memory) - return 1; - /* - * Simple hysteresis: exit 'low memory mode' if - * the upper limit has been reached: - */ - if (free >= zone->pages_high) { - zone->low_on_memory = 0; - return 1; - } - } else - zone->low_on_memory = 1; /* * In the atomic allocation case we only 'kick' the @@ -243,43 +227,6 @@ return 1; } -#if 0 -/* - * We are still balancing memory in a global way: - */ -static inline int balance_memory (zone_t *zone, int gfp_mask) -{ - unsigned long free = nr_free_pages(); - static int low_on_memory = 0; - int freed; - - if (free >= freepages.low) { - if (!low_on_memory) - return 1; - /* - * Simple hysteresis: exit 'low memory mode' if - * the upper limit has been reached: - */ - if (free >= freepages.high) { - low_on_memory = 0; - return 1; - } - } else - low_on_memory = 1; - - /* - * In the atomic allocation case we only 'kick' the - * state machine, but do not try to free pages - * ourselves. - */ - freed = try_to_free_pages(gfp_mask, zone); - - if (!freed && !(gfp_mask & __GFP_HIGH)) - return 0; - return 1; -} -#endif - /* * This is the 'heart' of the zoned buddy allocator: */ @@ -310,11 +257,31 @@ * further thought. */ if (!(current->flags & PF_MEMALLOC)) - /* - * fastpath - */ - if (!ZONE_BALANCED(z)) - goto balance; + { + if (classfree(z) > z->pages_high) + { + if (z->low_on_memory) + z->low_on_memory = 0; + } + else + { + extern wait_queue_head_t kswapd_wait; + + if (z->low_on_memory) + goto balance; + + if (classfree(z) <= z->pages_low) + { + wake_up_interruptible(&kswapd_wait); + + if (classfree(z) <= z->pages_min) + { + z->low_on_memory = 1; + goto balance; + } + } + } + } /* * This is an optimization for the 'higher order zone * is empty' case - it can happen even in well-behaved @@ -590,7 +557,11 @@ zone->offset = offset; cumulative += size; mask = (cumulative / zone_balance_ratio[j]); - if (mask < 1) mask = 1; + if (mask < zone_balance_min[j]) + mask = zone_balance_min[j]; + else if (mask > zone_balance_max[j]) + mask = zone_balance_max[j]; + zone->pages_min = mask; zone->pages_low = mask*2; zone->pages_high = mask*3; zone->low_on_memory = 0; diff -urN ref/mm/vmscan.c 2.3.42aa3-alpha/mm/vmscan.c --- ref/mm/vmscan.c Sun Feb 6 19:28:44 2000 +++ 2.3.42aa3-alpha/mm/vmscan.c Fri Feb 4 20:10:33 2000 @@ -451,7 +451,7 @@ return priority >= 0; } -static struct task_struct *kswapd_process; +DECLARE_WAIT_QUEUE_HEAD(kswapd_wait); /* * The background pageout daemon, started as a kernel thread @@ -471,7 +471,6 @@ { struct task_struct *tsk = current; - kswapd_process = tsk; tsk->session = 1; tsk->pgrp = 1; strcpy(tsk->comm, "kswapd"); @@ -510,7 +509,7 @@ run_task_queue(&tq_disk); } while (!tsk->need_resched); tsk->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ); + interruptible_sleep_on(&kswapd_wait); } } @@ -533,7 +532,6 @@ { int retval = 1; - wake_up_process(kswapd_process); if (gfp_mask & __GFP_WAIT) { current->flags |= PF_MEMALLOC; retval = do_try_to_free_pages(gfp_mask, zone);