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