Index: linux-2.6.16-rc1-mm3/mm/page_alloc.c =================================================================== --- linux-2.6.16-rc1-mm3.orig/mm/page_alloc.c 2006-01-27 10:18:14.000000000 -0800 +++ linux-2.6.16-rc1-mm3/mm/page_alloc.c 2006-01-27 14:10:43.000000000 -0800 @@ -357,6 +357,7 @@ static void __free_one_page(struct page * pages are zeroed beginning with the largest * order. */ + zone->zeroed_pages -= 1 << order; __ClearPageZeroed(page); __ClearPageZeroed(buddy); } @@ -604,6 +605,8 @@ static struct page *__rmqueue(struct zon rmv_page_order(page); area->nr_free--; zone->free_pages -= 1UL << order; + if (PageZeroed(page)) + zone->zeroed_pages -= 1UL << order; expand(zone, page, order, current_order, area); return page; } @@ -1434,7 +1437,8 @@ void mod_page_state_offset(unsigned long EXPORT_SYMBOL(mod_page_state_offset); void __get_zone_counts(unsigned long *active, unsigned long *inactive, - unsigned long *free, struct pglist_data *pgdat) + unsigned long *free, unsigned long *zero, + struct pglist_data *pgdat) { struct zone *zones = pgdat->node_zones; int i; @@ -1442,27 +1446,31 @@ void __get_zone_counts(unsigned long *ac *active = 0; *inactive = 0; *free = 0; + *zero = 0; for (i = 0; i < MAX_NR_ZONES; i++) { *active += zones[i].nr_active; *inactive += zones[i].nr_inactive; *free += zones[i].free_pages; + *zero += zones[i].zeroed_pages; } } -void get_zone_counts(unsigned long *active, - unsigned long *inactive, unsigned long *free) +void get_zone_counts(unsigned long *active, unsigned long *inactive, + unsigned long *free, unsigned long *zero) { struct pglist_data *pgdat; *active = 0; *inactive = 0; *free = 0; + *zero = 0; for_each_pgdat(pgdat) { - unsigned long l, m, n; - __get_zone_counts(&l, &m, &n, pgdat); + unsigned long l, m, n, o; + __get_zone_counts(&l, &m, &n, &o, pgdat); *active += l; *inactive += m; *free += n; + *zero += o; } } @@ -1513,6 +1521,7 @@ void show_free_areas(void) unsigned long active; unsigned long inactive; unsigned long free; + unsigned long zero; struct zone *zone; for_each_zone(zone) { @@ -1542,20 +1551,21 @@ void show_free_areas(void) } get_page_state(&ps); - get_zone_counts(&active, &inactive, &free); + get_zone_counts(&active, &inactive, &free, &zero); printk("Free pages: %11ukB (%ukB HighMem)\n", K(nr_free_pages()), K(nr_free_highpages())); printk("Active:%lu inactive:%lu dirty:%lu writeback:%lu " - "unstable:%lu free:%u slab:%lu mapped:%lu pagetables:%lu\n", + "unstable:%lu free:%u zero:%lu slab:%lu mapped:%lu pagetables:%lu\n", active, inactive, ps.nr_dirty, ps.nr_writeback, ps.nr_unstable, nr_free_pages(), + zero, ps.nr_slab, ps.nr_mapped, ps.nr_page_table_pages); @@ -2214,6 +2224,7 @@ static void __init free_area_init_core(s zone_seqlock_init(zone); zone->zone_pgdat = pgdat; zone->free_pages = 0; + zone->zeroed_pages = 0; zone->temp_priority = zone->prev_priority = DEF_PRIORITY; Index: linux-2.6.16-rc1-mm3/include/linux/mmzone.h =================================================================== --- linux-2.6.16-rc1-mm3.orig/include/linux/mmzone.h 2006-01-27 09:54:43.000000000 -0800 +++ linux-2.6.16-rc1-mm3/include/linux/mmzone.h 2006-01-27 14:10:03.000000000 -0800 @@ -132,6 +132,7 @@ struct per_cpu_pageset { struct zone { /* Fields commonly accessed by the page allocator */ unsigned long free_pages; + unsigned long zeroed_pages; unsigned long pages_min, pages_low, pages_high; /* * We don't know if the memory that we're going to allocate will be freeable @@ -339,9 +340,10 @@ typedef struct pglist_data { extern struct pglist_data *pgdat_list; void __get_zone_counts(unsigned long *active, unsigned long *inactive, - unsigned long *free, struct pglist_data *pgdat); + unsigned long *free, unsigned long *zero, + struct pglist_data *pgdat); void get_zone_counts(unsigned long *active, unsigned long *inactive, - unsigned long *free); + unsigned long *free, unsigned long *zero); void build_all_zonelists(void); void wakeup_kswapd(struct zone *zone, int order); int zone_watermark_ok(struct zone *z, int order, unsigned long mark, Index: linux-2.6.16-rc1-mm3/drivers/base/node.c =================================================================== --- linux-2.6.16-rc1-mm3.orig/drivers/base/node.c 2006-01-16 23:44:47.000000000 -0800 +++ linux-2.6.16-rc1-mm3/drivers/base/node.c 2006-01-27 14:10:03.000000000 -0800 @@ -43,10 +43,11 @@ static ssize_t node_read_meminfo(struct unsigned long inactive; unsigned long active; unsigned long free; + unsigned long zero; si_meminfo_node(&i, nid); get_page_state_node(&ps, nid); - __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid)); + __get_zone_counts(&active, &inactive, &free, &zero, NODE_DATA(nid)); /* Check for negative values in these approximate counters */ if ((long)ps.nr_dirty < 0) @@ -61,6 +62,7 @@ static ssize_t node_read_meminfo(struct n = sprintf(buf, "\n" "Node %d MemTotal: %8lu kB\n" "Node %d MemFree: %8lu kB\n" + "Node %d MemZero: %8lu kB\n" "Node %d MemUsed: %8lu kB\n" "Node %d Active: %8lu kB\n" "Node %d Inactive: %8lu kB\n" @@ -74,6 +76,7 @@ static ssize_t node_read_meminfo(struct "Node %d Slab: %8lu kB\n", nid, K(i.totalram), nid, K(i.freeram), + nid, K(zero), nid, K(i.totalram - i.freeram), nid, K(active), nid, K(inactive), Index: linux-2.6.16-rc1-mm3/fs/proc/proc_misc.c =================================================================== --- linux-2.6.16-rc1-mm3.orig/fs/proc/proc_misc.c 2006-01-26 22:14:11.000000000 -0800 +++ linux-2.6.16-rc1-mm3/fs/proc/proc_misc.c 2006-01-27 14:10:03.000000000 -0800 @@ -124,13 +124,14 @@ static int meminfo_read_proc(char *page, unsigned long inactive; unsigned long active; unsigned long free; + unsigned long zero; unsigned long committed; unsigned long allowed; struct vmalloc_info vmi; long cached; get_page_state(&ps); - get_zone_counts(&active, &inactive, &free); + get_zone_counts(&active, &inactive, &free, &zero); /* * display in kilobytes. @@ -154,6 +155,7 @@ static int meminfo_read_proc(char *page, len = sprintf(page, "MemTotal: %8lu kB\n" "MemFree: %8lu kB\n" + "MemZero: %8lu kB\n" "Buffers: %8lu kB\n" "Cached: %8lu kB\n" "SwapCached: %8lu kB\n" @@ -177,6 +179,7 @@ static int meminfo_read_proc(char *page, "VmallocChunk: %8lu kB\n", K(i.totalram), K(i.freeram), + K(zero), K(i.bufferram), K(cached), K(total_swapcache_pages), Index: linux-2.6.16-rc1-mm3/mm/readahead.c =================================================================== --- linux-2.6.16-rc1-mm3.orig/mm/readahead.c 2006-01-26 22:14:12.000000000 -0800 +++ linux-2.6.16-rc1-mm3/mm/readahead.c 2006-01-27 14:10:03.000000000 -0800 @@ -571,7 +571,8 @@ unsigned long max_sane_readahead(unsigne unsigned long active; unsigned long inactive; unsigned long free; + unsigned long zero; - __get_zone_counts(&active, &inactive, &free, NODE_DATA(numa_node_id())); + __get_zone_counts(&active, &inactive, &free, &zero, NODE_DATA(numa_node_id())); return min(nr, (inactive + free) / 2); }