Andrew Morton wrote: > On Mon, 5 Jan 2015 13:46:22 +0200 "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> wrote: > > > The only caller is __free_one_page(). By the time we should have > > page->flags to be cleared already: > > > > - for 0-order pages though PCP list: > > free_hot_cold_page() > > free_pages_prepare() > > free_pages_check() > > page->flags &= ~PAGE_FLAGS_CHECK_AT_PREP; > > <put the page to PCP list> > > > > free_pcppages_bulk() > > page = <withdraw pages from PCP list> > > __free_one_page(page) > > > > - for non-0-order pages: > > __free_pages_ok() > > free_pages_prepare() > > free_pages_check() > > page->flags &= ~PAGE_FLAGS_CHECK_AT_PREP; > > free_one_page() > > __free_one_page() > > > > So there's no way PageCompound() will return true in __free_one_page(). > > Let's remove dead destroy_compound_page() and put assert for page->flags > > there instead. > > Well. An alternative would be to fix up the call site so those > useful-looking checks actually get to check things. Perhaps under > CONFIG_DEBUG_VM. Something like this? >From 5fd481c1c521112e9cea407f5a2644c9f93d0e14 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Date: Thu, 8 Jan 2015 15:59:23 +0200 Subject: [PATCH] mm: more checks on free_pages_prepare() for tail pages Apart form being dead, destroy_compound_page() did some potentially useful checks. Let's re-introduce them in free_pages_prepare(), where they can be acctually triggered. compound_order() assert is already in free_pages_prepare(). We have few checks for tail pages left. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> --- mm/page_alloc.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 23b85d97f61c..53f1a617866b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -767,21 +767,40 @@ static void free_one_page(struct zone *zone, spin_unlock(&zone->lock); } +static int free_tail_pages_check(struct page *head_page, struct page *page) +{ + if (!IS_ENABLED(CONFIG_DEBUG_VM)) + return 0; + if (unlikely(!PageTail(page))) { + bad_page(page, "PageTail not set", 0); + return 1; + } + if (unlikely(page->first_page != head_page)) { + bad_page(page, "first_page not consistent", 0); + return 1; + } + return 0; +} + static bool free_pages_prepare(struct page *page, unsigned int order) { - int i; - int bad = 0; + bool compound = PageCompound(page); + int i, bad = 0; VM_BUG_ON_PAGE(PageTail(page), page); - VM_BUG_ON_PAGE(PageHead(page) && compound_order(page) != order, page); + VM_BUG_ON_PAGE(compound && compound_order(page) != order, page); trace_mm_page_free(page, order); kmemcheck_free_shadow(page, order); if (PageAnon(page)) page->mapping = NULL; - for (i = 0; i < (1 << order); i++) + bad += free_pages_check(page); + for (i = 1; i < (1 << order); i++) { + if (compound) + free_tail_pages_check(page, page + i); bad += free_pages_check(page + i); + } if (bad) return false; if (order) -- 2.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>