lkml.org 
[lkml]   [1999]   [Nov]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: 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);
}
}
}
\
 
 \ /
  Last update: 2005-03-22 13:55    [W:0.065 / U:0.156 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site