Messages in this thread Patch in this message | | | Date | Fri, 12 Nov 1999 20:02:07 +0100 (CET) | From | Ingo Molnar <> | Subject | Re: 2.3.27 always keeping 15M free? |
| |
On Fri, 12 Nov 1999, Alan Cox wrote:
> 2.3.27 seperates DMA memory from the rest but forgets that you need to > pull from the DMA pool for a failing GFP_KERNEL allocation.
what it does forget is to balance memory in lower-order zones. Does the attached patch fix the bad behavior?
-- mingo --- linux/mm/page_alloc.c.orig Fri Nov 12 01:34:46 1999 +++ linux/mm/page_alloc.c Fri Nov 12 10:55:11 1999 @@ -51,11 +51,13 @@ #ifdef CONFIG_HIGHMEM # define ZONE_HIGHMEM 2 -# define NR_ZONES 3 +# define MAX_NR_ZONES 3 #else -# define NR_ZONES 2 +# define MAX_NR_ZONES 2 #endif +int nr_zones = MAX_NR_ZONES; + typedef struct zone_struct { spinlock_t lock; unsigned long offset; @@ -68,7 +70,7 @@ char * name; } zone_t; -static zone_t zones[NR_ZONES] = +static zone_t zones[MAX_NR_ZONES] = { { name: "DMA" }, { name: "Normal" }, @@ -120,12 +122,12 @@ /* * Which zone is this page belonging to. * - * (NR_ZONES is low, and we do not want (yet) to introduce + * (nr_zones is low, and we do not want (yet) to introduce * put page->zone, it increases the size of mem_map[] * unnecesserily. This small loop is basically equivalent * to the previous #ifdef jungle, speed-wise.) */ - i = NR_ZONES-1; + i = nr_zones-1; zone = zones + i; for ( ; i >= 0; i--, zone--) if (map_nr >= zone->offset) @@ -258,6 +260,7 @@ page = mem_map + map_nr; if (BAD_RANGE(zone,page)) BUG(); +printk("allocated page %p, %08lx.\n", page, PageHighMem(page) ? 0xffffffff : page_address(page)); return page; } curr_order++; @@ -265,6 +268,7 @@ } while (curr_order < MAX_ORDER); spin_unlock_irqrestore(&zone->lock, flags); +printk("returning NULL page to %p.\n", __builtin_return_address(0)); return NULL; } @@ -309,14 +313,6 @@ */ /* - * If this is a recursive call, we'd better - * do our best to just allocate things without - * further thought. - */ - if (!(current->flags & PF_MEMALLOC)) - if (!balance_memory(zone, gfp_mask)) - goto nopage; - /* * We are falling back to lower-level zones if allocation * in a higher zone fails. This assumes a hierarchical * dependency between zones, which is true currently. If @@ -324,6 +320,15 @@ * this function, into the zone-specific allocator. */ do { + /* + * If this is a recursive call, we'd better + * do our best to just allocate things without + * further thought. + */ + if (!(current->flags & PF_MEMALLOC)) + if (!balance_memory(zone, gfp_mask)) + goto nopage; + page = rmqueue(zone, order); if (page) return page; @@ -345,7 +350,7 @@ static inline zone_t * gfp_mask_to_zone (int gfp_mask) { - zone_t *zone; + zone_t *zone, *limit; #if CONFIG_HIGHMEM if (gfp_mask & __GFP_HIGHMEM) @@ -356,6 +361,9 @@ zone = zones + ZONE_DMA; else zone = zones + ZONE_NORMAL; + limit = zones + nr_zones-1; + if (zone > limit) + zone = limit; return zone; } @@ -383,7 +391,7 @@ zone_t *zone; sum = 0; - for (zone = zones; zone < zones+NR_ZONES; zone++) + for (zone = zones; zone < zones+nr_zones; zone++) sum += zone->free_pages; return sum; } @@ -429,7 +437,7 @@ freepages.low, freepages.high); - for (type = 0; type < NR_ZONES; type++) { + for (type = 0; type < nr_zones; type++) { zone_t *zone = zones + type; unsigned long total = 0; @@ -466,12 +474,12 @@ void __init free_area_init(unsigned int *zones_size) { mem_map_t * p; - unsigned long i, j; + int i, j; unsigned long map_size; unsigned int totalpages, offset; totalpages = 0; - for (i = 0; i < NR_ZONES; i++) + for (i = 0; i < nr_zones; i++) totalpages += zones_size[i]; printk("totalpages: %08x\n", totalpages); @@ -498,7 +506,6 @@ */ map_size = totalpages*sizeof(struct page); mem_map = (struct page *) alloc_bootmem(map_size); - memset(mem_map, 0, map_size); /* * Initially all pages are reserved - free ones are freed @@ -514,12 +521,18 @@ } offset = 0; - for (j = 0; j < NR_ZONES; j++) { + for (j = 0; j < MAX_NR_ZONES; j++) { zone_t *zone = zones + j; unsigned long mask = -1; unsigned long size; size = zones_size[j]; + printk("zone %d, size %08lx\n", j, size); + if (!size) { + nr_zones = j; + printk("setting nr_zones to %d\n", nr_zones); + break; + } zone->size = size; zone->offset = offset; zone->pages_low = freepages.low; @@ -538,7 +551,6 @@ bitmap_size = LONG_ALIGN(bitmap_size); map = (unsigned int *) alloc_bootmem(bitmap_size); zone->free_area[i].map = map; - memset((void *) map, 0, bitmap_size); } } }
| |