diff options
Diffstat (limited to 'mm')
-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 | ||