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 14:46:22.000000000 -0800 +++ linux-2.6.16-rc1-mm3/mm/page_alloc.c 2006-01-27 14:51:09.000000000 -0800 @@ -85,6 +85,45 @@ unsigned int sysctl_scrub_limit __read_m ((z)->zeroed_pages < (z)->free_pages * sysctl_scrub_limit >> 10) static void zero_page(struct page *page, struct zone *zone, int order); + +/* + * Hardware zeroing drivers + */ +static LIST_HEAD(zero_drivers); + +/* Registering and unregistering zero drivers */ +void register_zero_driver(struct zero_driver *z) +{ + list_add(&z->list, &zero_drivers); +} + +void unregister_zero_driver(struct zero_driver *z) +{ + list_del(&z->list); +} + +/* + * Overwrite page with zeroes using hardware support + */ +static int __zero_page(struct page *page, int order) +{ + struct list_head *l; + + list_for_each(l, &zero_drivers) { + struct zero_driver *driver = container_of(l, struct zero_driver, list); + + if (driver->zero_func(page_address(page), PAGE_SIZE << order) == 0) + return 1; + } + + /* + * No zeroeing device + */ + return 0; +} + +#else +#define __zero_page(page, order) 0 #endif EXPORT_SYMBOL(totalram_pages); @@ -862,11 +901,13 @@ static inline void prep_zero_page(struct } /* - * Zero a page and prep for reintegration to free lists. + * Zero a page (if possible using hardware zeroing support) and prep for + * reintegration to free lists. */ static void zero_page(struct page *page, struct zone *zone, int order) { - prep_zero_page(page, order, 0); + if (!__zero_page(page, order)) + prep_zero_page(page, order, 0); __SetPageZeroed(page); zone->zeroed_pages += 1 << order; } Index: linux-2.6.16-rc1-mm3/include/linux/gfp.h =================================================================== --- linux-2.6.16-rc1-mm3.orig/include/linux/gfp.h 2006-01-16 23:44:47.000000000 -0800 +++ linux-2.6.16-rc1-mm3/include/linux/gfp.h 2006-01-27 14:49:22.000000000 -0800 @@ -162,4 +162,13 @@ void drain_remote_pages(void); static inline void drain_remote_pages(void) { }; #endif +/* Zeroing driver */ +struct zero_driver { + int (*zero_func)(void *, unsigned long); + struct list_head list; +}; + +void register_zero_driver(struct zero_driver *z); +void unregister_zero_driver(struct zero_driver *z); + #endif /* __LINUX_GFP_H */