From 7fbb986c38ecce8c9a96c172469611f1660c6ad1 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 25 Jul 2007 20:05:38 -0700 Subject: [PATCH] compound_free_via_pagevec compound pages: Allow freeing of compound pages via pagevec 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(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6c61a61..0e9bc46 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1424,8 +1424,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) diff --git a/mm/swap.c b/mm/swap.c index d3cb966..64f224f 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -263,7 +263,13 @@ void release_pages(struct page **pages, int nr, int cold) 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; -- 1.4.4.4