Allow the freeing of compound pages via pagevec. In release_pages() we currently special case for compound pages in order to be sure to always decrement the page count of the head page and not the tail page. However that redirection to the head page is only necessary for tail pages. So use PageTail instead of PageCompound. No change therefore for the handling of tail pages. The head page of a compound pages now represents single page large page. We do the usual processing including checking if its on the LRU and removing it (not useful right now but later when compound pages are on the LRU this will work). Then we add the compound page to the pagevec. Only head pages will end up on the pagevec not tail pages. In __pagevec_free() we then check if we are freeing a head page and if so call the destructor for the compound page. Signed-off-by: Christoph Lameter --- mm/page_alloc.c | 13 +++++++++++-- mm/swap.c | 8 +++++++- 2 files changed, 18 insertions(+), 3 deletions(-) Index: linux-2.6.22-rc4-mm2/mm/page_alloc.c =================================================================== --- linux-2.6.22-rc4-mm2.orig/mm/page_alloc.c 2007-06-18 19:13:03.000000000 -0700 +++ linux-2.6.22-rc4-mm2/mm/page_alloc.c 2007-06-18 19:14:03.000000000 -0700 @@ -1746,8 +1746,17 @@ void __pagevec_free(struct pagevec *pvec { int i = pagevec_count(pvec); - while (--i >= 0) - free_hot_cold_page(pvec->pages[i], pvec->cold); + while (--i >= 0) { + struct page *page = pvec->pages[i]; + + if (PageHead(page)) { + compound_page_dtor *dtor; + + dtor = get_compound_page_dtor(page); + (*dtor)(page); + } else + free_hot_cold_page(page, pvec->cold); + } } fastcall void __free_pages(struct page *page, unsigned int order) Index: linux-2.6.22-rc4-mm2/mm/swap.c =================================================================== --- linux-2.6.22-rc4-mm2.orig/mm/swap.c 2007-06-15 17:35:33.000000000 -0700 +++ linux-2.6.22-rc4-mm2/mm/swap.c 2007-06-18 19:14:03.000000000 -0700 @@ -293,7 +293,13 @@ void release_pages(struct page **pages, for (i = 0; i < nr; i++) { struct page *page = pages[i]; - if (unlikely(PageCompound(page))) { + /* + * If we have a tail page on the LRU then we need to + * decrement the page count of the head page. There + * is no further need to do anything since tail pages + * cannot be on the LRU. + */ + if (unlikely(PageTail(page))) { if (zone) { spin_unlock_irq(&zone->lru_lock); zone = NULL; -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/