diff -u --recursive --new-file pre6/linux/mm/page_alloc.c linux/mm/page_alloc.c --- pre6/linux/mm/page_alloc.c Sat Nov 17 19:07:43 2001 +++ linux/mm/page_alloc.c Mon Nov 19 15:13:36 2001 @@ -299,29 +299,26 @@ return page; } -static inline unsigned long zone_free_pages(zone_t * zone, unsigned int order) -{ - long free = zone->free_pages - (1UL << order); - return free >= 0 ? free : 0; -} - /* * This is the 'heart' of the zoned buddy allocator: */ struct page * __alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist) { + unsigned long min; zone_t **zone, * classzone; struct page * page; int freed; zone = zonelist->zones; classzone = *zone; + min = 1UL << order; for (;;) { zone_t *z = *(zone++); if (!z) break; - if (zone_free_pages(z, order) > z->pages_low) { + min += z->pages_low; + if (z->free_pages > min) { page = rmqueue(z, order); if (page) return page; @@ -334,16 +331,18 @@ wake_up_interruptible(&kswapd_wait); zone = zonelist->zones; + min = 1UL << order; for (;;) { - unsigned long min; + unsigned long local_min; zone_t *z = *(zone++); if (!z) break; - min = z->pages_min; + local_min = z->pages_min; if (!(gfp_mask & __GFP_WAIT)) - min >>= 2; - if (zone_free_pages(z, order) > min) { + local_min >>= 2; + min += local_min; + if (z->free_pages > min) { page = rmqueue(z, order); if (page) return page; @@ -376,12 +375,14 @@ return page; zone = zonelist->zones; + min = 1UL << order; for (;;) { zone_t *z = *(zone++); if (!z) break; - if (zone_free_pages(z, order) > z->pages_min) { + min += z->pages_min; + if (z->free_pages > min) { page = rmqueue(z, order); if (page) return page;