******************************************* Patch prepared by: roger.larsson@norran.net Name of file: /home/roger/patches/patch-2.4.10-pre9-recycle-R1 --- linux/mm/page_alloc.c.orig Sat Sep 15 17:30:32 2001 +++ linux/mm/page_alloc.c Sun Sep 16 00:01:24 2001 @@ -104,7 +104,12 @@ spin_lock_irqsave(&zone->lock, flags); - zone->free_pages -= mask; + area->recycled++; + if (area->recycled <= 0) + area->recycled=1; + + if (!order || area->recycled < 0) + zone->free_pages -= mask; while (mask + (1 << (MAX_ORDER-1))) { struct page *buddy1, *buddy2; @@ -193,9 +198,14 @@ index = page - zone->zone_mem_map; if (curr_order != MAX_ORDER-1) MARK_USED(index, curr_order, area); - zone->free_pages -= 1 << order; page = expand(zone, page, index, order, curr_order, area); + /* use initial area, requested order */ + area=zone->free_area + order; + area->recycled--; /* might go neg, fixed in free */ + if (!order || area->recycled < 0) + zone->free_pages -= 1 << order; + spin_unlock_irqrestore(&zone->lock, flags); set_page_count(page, 1); @@ -653,7 +663,8 @@ if (zone->size) { spin_lock_irqsave(&zone->lock, flags); for (order = 0; order < MAX_ORDER; order++) { - head = &(zone->free_area + order)->free_list; + free_area_t *area = zone->free_area + order; + head = &area->free_list; curr = head; nr = 0; for (;;) { @@ -663,8 +674,9 @@ nr++; } total += nr * (1 << order); - printk("%lu*%lukB ", nr, - (PAGE_SIZE>>10) << order); + printk("%lu/%ld*%lukB ", nr, + area->recycled, + (PAGE_SIZE>>10) << order); } spin_unlock_irqrestore(&zone->lock, flags); } @@ -891,6 +903,7 @@ bitmap_size = LONG_ALIGN(bitmap_size+1); zone->free_area[i].map = (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size); + zone->free_area[i].recycled = 0; } } build_zonelists(pgdat); --- linux/include/linux/mmzone.h.orig Sat Sep 15 21:58:47 2001 +++ linux/include/linux/mmzone.h Sat Sep 15 22:01:29 2001 @@ -21,6 +21,7 @@ typedef struct free_area_struct { struct list_head free_list; unsigned long *map; + long recycled; } free_area_t; struct pglist_data;