diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2015-02-11 18:25:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 20:06:02 -0500 |
commit | 81422f29c5f4fb968023f465218c3d978c133ceb (patch) | |
tree | 87ee41d4351d2ecd1a8affeb563e3e8aca2961d2 | |
parent | 6e9f0d582dde095d971a3c6ce4685a218a0eac8e (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>
-rw-r--r-- | mm/page_alloc.c | 27 |
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 | ||
767 | static 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 | |||
767 | static bool free_pages_prepare(struct page *page, unsigned int order) | 782 | static 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 | ||