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);
 }