[PATCH 5/5] mm: Check page poison before finding a head page

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

 



From: "Matthew Wilcox (Oracle)" <willy@xxxxxxxxxxxxx>

If a page is poisoned, the page->compound_head will be set to -1.
Since it has bit zero set, we will think it is a tail page, and the head
page is at 0xff..fe.  Checking said head page for being poisoned will
not have good results.  Therefore we need to check for poison in each
of compound_head(), PageTail() and PageCompound() (and can remove the
checks which are now redundant from the PF_ macros).

Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx>
---
 include/linux/page-flags.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 331aef35f3e0..340ceeeda8ed 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -190,6 +190,7 @@ static inline int PagePoisoned(const struct page *page)
 #define compound_head(page) ({						\
 	__typeof__(page) _page = page;					\
 	unsigned long head = READ_ONCE(_page->compound_head);		\
+	VM_BUG_ON_PAGE(head == PAGE_POISON_PATTERN, page);		\
 	if (unlikely(head & 1))						\
 		_page = (void *)(head - 1);				\
 	_page;								\
@@ -197,11 +198,13 @@ static inline int PagePoisoned(const struct page *page)
 
 static __always_inline int PageTail(const struct page *page)
 {
+	page_poison_check(page);
 	return READ_ONCE(page->compound_head) & 1;
 }
 
 static __always_inline int PageCompound(const struct page *page)
 {
+	page_poison_check(page);
 	return test_bit(PG_head, &page->flags) || PageTail(page);
 }
 
@@ -234,13 +237,13 @@ static inline void page_init_poison(struct page *page, size_t size)
  *     the page flag is not relevant for compound pages.
  */
 #define PF_ANY(page, enforce)	page_poison_check(page)
-#define PF_HEAD(page, enforce)	page_poison_check(compound_head(page))
+#define PF_HEAD(page, enforce)	compound_head(page)
 #define PF_ONLY_HEAD(page, enforce) ({					\
 		VM_BUG_ON_PGFLAGS(PageTail(page), page);		\
-		page_poison_check(page); })
+		page; })
 #define PF_NO_TAIL(page, enforce) ({					\
 		VM_BUG_ON_PGFLAGS(enforce && PageTail(page), page);	\
-		page_poison_check(compound_head(page)); })
+		compound_head(page); })
 #define PF_NO_COMPOUND(page, enforce) ({				\
 		VM_BUG_ON_PGFLAGS(enforce && PageCompound(page), page);	\
 		page_poison_check(page); })
-- 
2.25.1





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

  Powered by Linux