diff -u lb5-2.5.44/mm/page_alloc.c lb5-2.5.44/mm/page_alloc.c --- lb5-2.5.44/mm/page_alloc.c 2002-10-28 19:08:03.000000000 -0800 +++ lb5-2.5.44/mm/page_alloc.c 2002-10-29 08:28:03.000000000 -0800 @@ -108,7 +108,6 @@ BUG(); index = page_idx >> (1 + order); - zone->free_pages -= mask; while (mask + (1 << (MAX_ORDER-1))) { struct page *buddy1, *buddy2; @@ -153,12 +152,15 @@ /* fall through */ case 1: buddy_free(page, base, zone, area, mask, order); + break; default: list_add(&page->list, &area->deferred_pages); area->locally_free++; break; } - area->active--; + if (area->active) + area->active--; + zone->free_pages += 1 << order; } static inline void free_pages_check(const char *function, struct page *page) @@ -1024,8 +1026,7 @@ nr_free_pages()); for_each_zone(zone) { - struct list_head *elem; - unsigned long nr, flags, order, total = 0; + unsigned long order, total = 0; printk("Node %d, Zone %s: ", zone->zone_pgdat->node_id, zone->name); if (!zone->present_pages) { @@ -1033,16 +1034,20 @@ continue; } - spin_lock_irqsave(&zone->lock, flags); + printk("buddy: "); + for (order = 0; order < MAX_ORDER; order++) { + printk("%lu*%lukB ", zone->free_area[order].globally_free, K(1UL) << order); + total += zone->free_area[order].globally_free << order; + } + printk("\ndefer: "); for (order = 0; order < MAX_ORDER; order++) { - nr = 0; - list_for_each(elem, &zone->free_area[order].free_list) - ++nr; - total += nr << order; - printk("%lu*%lukB ", nr, K(1UL) << order); + printk("%lu*%lukB ", zone->free_area[order].active, K(1UL) << order); + total += zone->free_area[order].locally_free << order; } - spin_unlock_irqrestore(&zone->lock, flags); - printk("= %lukB)\n", K(total)); + printk("\nactive: "); + for (order = 0; order < MAX_ORDER; order++) + printk("%lu*%lukB ", zone->free_area[order].active, K(1UL) << order); + printk("\n= %lukB)\n", K(total)); } for_each_zone(zone) { @@ -1483,7 +1488,6 @@ pg_data_t *pgdat = (pg_data_t *)arg; struct zone *zone; struct zone *node_zones = pgdat->node_zones; - unsigned long flags; int order; for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {