Re: [PATCH] mm/page_alloc.c: drop dead destroy_compound_page()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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>



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]