Index: linux-2.6.16-rc1-mm3/mm/page_alloc.c =================================================================== --- linux-2.6.16-rc1-mm3.orig/mm/page_alloc.c 2006-01-26 18:34:09.000000000 -0800 +++ linux-2.6.16-rc1-mm3/mm/page_alloc.c 2006-01-26 18:35:09.000000000 -0800 @@ -12,6 +12,7 @@ * Zone balancing, Kanoj Sarcar, SGI, Jan 2000 * Per cpu hot/cold page lists, bulk allocation, Martin J. Bligh, Sept 2002 * (lots of bits borrowed from Ingo Molnar & Andrew Morton) + * Page zeroing Christoph Lameter, Silicon Graphics, Inc, January 2006. */ #include @@ -512,26 +513,26 @@ static inline void expand(struct zone *z int low, int high, struct free_area *area) { unsigned long size = 1 << high; - struct page *new_page; + struct page *newpage; while (high > low) { area--; high--; size >>= 1; - new_page = &page[size]; - BUG_ON(bad_range(zone, new_page)); + newpage = &page[size]; + BUG_ON(bad_range(zone, newpage)); if (PageZeroed(page)) { /* * Splitting a zeroed page. The new page is also * already zeroed and will go to the back of the - * list. + * end of the list. */ - __SetZeroed(page); - list_add_tail(newpage->lru, &area->free_list); + __SetPageZeroed(page); + list_add_tail(&newpage->lru, &area->free_list); } else - list_add(newpage->lru, &area->free_list); + list_add(&newpage->lru, &area->free_list); area->nr_free++; set_page_order(&page[size], high); @@ -822,7 +823,6 @@ static struct page *buffered_rmqueue(str { unsigned long flags; struct page *page; - int cold = !!(gfp_flags & __GFP_COLD); int zero = !!(gfp_flags & __GFP_ZERO); int cpu; @@ -830,8 +830,15 @@ again: cpu = get_cpu(); if (likely(order == 0)) { struct per_cpu_pages *pcp; + int list; + + list = PER_CPU_HOT; + if (gfp_flags & __GFP_COLD) + list = PER_CPU_COLD; + if (zero) + list = PER_CPU_ZEROED; - pcp = &zone_pcp(zone, cpu)->pcp[cold]; + pcp = &zone_pcp(zone, cpu)->pcp[list]; local_irq_save(flags); if (!pcp->count) { pcp->count += rmqueue_bulk(zone, 0, @@ -1487,7 +1494,7 @@ void si_meminfo_node(struct sysinfo *val #define K(x) ((x) << (PAGE_SHIFT-10)) -static const char *temperature_descr[] = { "cold", "hot" }; +static const char *temperature_descr[] = { "cold", "hot", "zeroed" }; /* * Show free area list (used inside shift_scroll-lock stuff) @@ -1978,6 +1985,12 @@ inline void setup_pageset(struct per_cpu pcp->high = 2 * batch; pcp->batch = max(1UL, batch/2); INIT_LIST_HEAD(&pcp->list); + + pcp = &p->pcp[PER_CPU_ZEROED]; + pcp->count = 0; + pcp->high = 2 * batch; + pcp->batch = max(1UL, batch/2); + INIT_LIST_HEAD(&pcp->list); } /* Index: linux-2.6.16-rc1-mm3/include/linux/mmzone.h =================================================================== --- linux-2.6.16-rc1-mm3.orig/include/linux/mmzone.h 2006-01-26 18:33:51.000000000 -0800 +++ linux-2.6.16-rc1-mm3/include/linux/mmzone.h 2006-01-26 18:35:09.000000000 -0800 @@ -22,13 +22,19 @@ #define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER #endif -#define NR_PER_CPU_PAGES 2 +#define NR_PER_CPU_PAGES 3 /* Types of per cpu pages */ #define PER_CPU_HOT 0 #define PER_CPU_COLD 1 +#define PER_CPU_ZEROED 2 struct free_area { + /* + * The free list contains free pages of a specific order. + * Zeroed pages are at the back of the list and unzeroed ones + * at the front. + */ struct list_head free_list; unsigned long nr_free; };