--- linux/mm/page_alloc.c.orig Fri May 12 08:45:17 2000 +++ linux/mm/page_alloc.c Fri May 12 09:14:58 2000 @@ -29,9 +29,9 @@ pg_data_t *pgdat_list = (pg_data_t *)0; 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_min[MAX_NR_ZONES] = { 10 , 10, 10, }; -static int zone_balance_max[MAX_NR_ZONES] = { 255 , 255, 255, }; +static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 1, }; +static int zone_balance_min[MAX_NR_ZONES] = { 10 , 10, 0, }; +static int zone_balance_max[MAX_NR_ZONES] = { 255 , 255, 0, }; /* * Free_page() adds the page to the free lists. This is optimized for @@ -271,7 +271,10 @@ if (!(current->flags & PF_MEMALLOC)) { int gfp_mask = zonelist->gfp_mask; if (!try_to_free_pages(gfp_mask)) { - if (!(gfp_mask & __GFP_HIGH)) + /* + * Non-highprio allocations fail here: + */ + if (!(gfp_mask & __GFP_PRIO)) goto fail; } } @@ -440,6 +443,9 @@ zone = pgdat->node_zones + ZONE_NORMAL; if (zone->size) zonelist->zones[j++] = zone; + if ((i && __GFP_WAIT) || !(i && __GFP_PRIO) || + (i && __GFP_IO)) + break; case ZONE_DMA: zone = pgdat->node_zones + ZONE_DMA; if (zone->size) --- linux/mm/highmem.c.orig Fri May 12 09:16:25 2000 +++ linux/mm/highmem.c Fri May 12 09:27:14 2000 @@ -66,6 +66,13 @@ return new_page; } +/* + * Special zonelist so we can just query the highmem pool and + * return immediately if there is no highmem page free. + */ +static zonelist_t high_zonelist = + { { NODE_DATA(0)->node_zones + ZONE_HIGHMEM, NULL, }, __GFP_HIGHMEM }; + struct page * replace_with_highmem(struct page * page) { struct page *highpage; @@ -74,13 +81,11 @@ if (PageHighMem(page) || !nr_free_highpages()) return page; - highpage = alloc_page(GFP_ATOMIC|__GFP_HIGHMEM); + highpage = __alloc_pages(&high_zonelist, 0); if (!highpage) return page; - if (!PageHighMem(highpage)) { - __free_page(highpage); - return page; - } + if (!PageHighMem(highpage)) + BUG(); vaddr = kmap(highpage); copy_page((void *)vaddr, (void *)page_address(page)); --- linux/include/linux/mm.h.orig Fri May 12 08:46:55 2000 +++ linux/include/linux/mm.h Fri May 12 09:27:56 2000 @@ -471,33 +471,49 @@ * GFP bitmasks.. */ #define __GFP_WAIT 0x01 -#define __GFP_HIGH 0x02 +#define __GFP_PRIO 0x02 #define __GFP_IO 0x04 +/* + * indicates that the buffer will be suitable for DMA. Ignored on some + * platforms, used as appropriate on others + */ #define __GFP_DMA 0x08 + +/* + * indicates that the buffer can be taken from high memory, + * which is not permanently mapped by the kernel + */ #ifdef CONFIG_HIGHMEM #define __GFP_HIGHMEM 0x10 #else #define __GFP_HIGHMEM 0x0 /* noop */ #endif - -#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) -#define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO) -#define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO) -#define GFP_KSWAPD (__GFP_IO) - -/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some - platforms, used as appropriate on others */ - -#define GFP_DMA __GFP_DMA - -/* Flag - indicates that the buffer can be taken from high memory which is not - permanently mapped by the kernel */ - -#define GFP_HIGHMEM __GFP_HIGHMEM +/* + * The 5 GFP bits: + * ( __GFP_WAIT | __GFP_PRIO | __GFP_IO | __GFP_DMA | __GFP_HIGHMEM ) + * + * The most typical combinations: + */ + +#define GFP_BUFFER \ + ( __GFP_WAIT | __GFP_PRIO | 0 | 0 | 0 ) +#define GFP_ATOMIC \ + ( 0 | __GFP_PRIO | 0 | 0 | 0 ) +#define GFP_USER \ + ( __GFP_WAIT | 0 | __GFP_IO | 0 | 0 ) +#define GFP_HIGHUSER \ + ( __GFP_WAIT | 0 | __GFP_IO | 0 | __GFP_HIGHMEM ) +#define GFP_KERNEL \ + ( __GFP_WAIT | __GFP_PRIO | __GFP_IO | 0 | 0 ) +#define GFP_NFS \ + ( __GFP_WAIT | __GFP_PRIO | __GFP_IO | 0 | 0 ) +#define GFP_KSWAPD \ + ( 0 | 0 | __GFP_IO | 0 | 0 ) +#define GFP_DMA \ + ( 0 | 0 | 0 | __GFP_DMA | 0 ) +#define GFP_HIGHMEM \ + ( 0 | 0 | 0 | 0 | __GFP_HIGHMEM ) /* vma is the first one with address < vma->vm_end, * and even address < vma->vm_start. Have to extend vma. */ --- linux/include/linux/slab.h.orig Fri May 12 09:05:15 2000 +++ linux/include/linux/slab.h Fri May 12 09:27:56 2000 @@ -22,7 +22,7 @@ #define SLAB_NFS GFP_NFS #define SLAB_DMA GFP_DMA -#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHMEM) +#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_PRIO|__GFP_IO|__GFP_HIGHMEM) #define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */ /* flags to pass to kmem_cache_create().