aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2015-02-11 18:25:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 20:06:02 -0500
commit81422f29c5f4fb968023f465218c3d978c133ceb (patch)
tree87ee41d4351d2ecd1a8affeb563e3e8aca2961d2 /mm
parent6e9f0d582dde095d971a3c6ce4685a218a0eac8e (diff)
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: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Andrea Arcangeli <aarcange@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/page_alloc.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 12d55b859d3f..0081228d1caa 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -764,21 +764,40 @@ static void free_one_page(struct zone *zone,
764 spin_unlock(&zone->lock); 764 spin_unlock(&zone->lock);
765} 765}
766 766
767static int free_tail_pages_check(struct page *head_page, struct page *page)
768{
769 if (!IS_ENABLED(CONFIG_DEBUG_VM))
770 return 0;
771 if (unlikely(!PageTail(page))) {
772 bad_page(page, "PageTail not set", 0);
773 return 1;
774 }
775 if (unlikely(page->first_page != head_page)) {
776 bad_page(page, "first_page not consistent", 0);
777 return 1;
778 }
779 return 0;
780}
781
767static bool free_pages_prepare(struct page *page, unsigned int order) 782static bool free_pages_prepare(struct page *page, unsigned int order)
768{ 783{
769 int i; 784 bool compound = PageCompound(page);
770 int bad = 0; 785 int i, bad = 0;
771 786
772 VM_BUG_ON_PAGE(PageTail(page), page); 787 VM_BUG_ON_PAGE(PageTail(page), page);
773 VM_BUG_ON_PAGE(PageHead(page) && compound_order(page) != order, page); 788 VM_BUG_ON_PAGE(compound && compound_order(page) != order, page);
774 789
775 trace_mm_page_free(page, order); 790 trace_mm_page_free(page, order);
776 kmemcheck_free_shadow(page, order); 791 kmemcheck_free_shadow(page, order);
777 792
778 if (PageAnon(page)) 793 if (PageAnon(page))
779 page->mapping = NULL; 794 page->mapping = NULL;
780 for (i = 0; i < (1 << order); i++) 795 bad += free_pages_check(page);
796 for (i = 1; i < (1 << order); i++) {
797 if (compound)
798 bad += free_tail_pages_check(page, page + i);
781 bad += free_pages_check(page + i); 799 bad += free_pages_check(page + i);
800 }
782 if (bad) 801 if (bad)
783 return false; 802 return false;
784 803