compound pages: Store address in page[1] Storing the address in page[1].lru.prev allows an optimization of the address determination for compund pages. Storing the address in the page structs of the compound page itself is going to be important for virtual compound pages. Add a new function page_to_addr in order to determine the address of a page that can exploit the address stored in the compound page. Signed-off-by: Christoph Lameter --- include/linux/mm.h | 12 ++++++++++++ mm/page_alloc.c | 9 +++++++++ 2 files changed, 21 insertions(+) Index: linux-2.6/include/linux/mm.h =================================================================== --- linux-2.6.orig/include/linux/mm.h 2007-09-28 09:54:34.000000000 -0700 +++ linux-2.6/include/linux/mm.h 2007-09-28 09:54:58.000000000 -0700 @@ -363,6 +363,18 @@ static inline void set_compound_order(st atomic_set(&page[1]._mapcount, order); } +extern void *page_to_addr(struct page *page); + +static inline void *compound_address(struct page *page) +{ + return (void *)page[1].lru.prev; +} + +static inline void set_compound_address(struct page *page, void *addr) +{ + page[1].lru.prev = addr; +} + /* * Multiple processes may "see" the same page. E.g. for untouched * mappings of /dev/null, all processes see the same page full of Index: linux-2.6/mm/page_alloc.c =================================================================== --- linux-2.6.orig/mm/page_alloc.c 2007-09-28 09:54:34.000000000 -0700 +++ linux-2.6/mm/page_alloc.c 2007-09-28 09:54:48.000000000 -0700 @@ -242,6 +242,14 @@ static void free_compound_page(struct pa __free_pages_ok(page, compound_order(page)); } +void *page_to_addr(struct page *page) +{ + if (likely(!PageHead(page))) + return page_address(page); + return compound_address(page); +} +EXPORT_SYMBOL(page_to_addr); + static void prep_compound_page(struct page *page, unsigned long order) { int i; @@ -249,6 +257,7 @@ static void prep_compound_page(struct pa set_compound_page_dtor(page, free_compound_page); set_compound_order(page, order); + set_compound_address(page, page_address(page)); __SetPageHead(page); for (i = 1; i < nr_pages; i++) { struct page *p = page + i;