Commit 81422f29 authored by Kirill A. Shutemov's avatar Kirill A. Shutemov Committed by Linus Torvalds
Browse files

mm: more checks on free_pages_prepare() for tail pages



Although it was not called, destroy_compound_page() did some potentially
useful checks.  Let's re-introduce them in free_pages_prepare(), where
they can be actually triggered when CONFIG_DEBUG_VM=y.

compound_order() assert is already in free_pages_prepare().  We have few
checks for tail pages left.
Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6e9f0d58
...@@ -764,21 +764,40 @@ static void free_one_page(struct zone *zone, ...@@ -764,21 +764,40 @@ static void free_one_page(struct zone *zone,
spin_unlock(&zone->lock); 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) static bool free_pages_prepare(struct page *page, unsigned int order)
{ {
int i; bool compound = PageCompound(page);
int bad = 0; int i, bad = 0;
VM_BUG_ON_PAGE(PageTail(page), page); 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); trace_mm_page_free(page, order);
kmemcheck_free_shadow(page, order); kmemcheck_free_shadow(page, order);
if (PageAnon(page)) if (PageAnon(page))
page->mapping = NULL; page->mapping = NULL;
for (i = 0; i < (1 << order); i++) bad += free_pages_check(page);
for (i = 1; i < (1 << order); i++) {
if (compound)
bad += free_tail_pages_check(page, page + i);
bad += free_pages_check(page + i); bad += free_pages_check(page + i);
}
if (bad) if (bad)
return false; return false;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment