diff for duplicates of <20150820123107.GA31768@node.dhcp.inet.fi> diff --git a/a/2.txt b/N1/2.txt index 8b13789..b61cd82 100644 --- a/a/2.txt +++ b/N1/2.txt @@ -1 +1,203 @@ +>From 1b88b5b6025e81a9f6b99275d66e129de52bd795 Mon Sep 17 00:00:00 2001 +From: Andrew Morton <akpm@linux-foundation.org> +Date: Tue, 18 Aug 2015 09:49:52 +1000 +Subject: [PATCH] include/linux/page-flags.h: rename macros to avoid collisions +Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +--- + include/linux/page-flags.h | 106 ++++++++++++++++++++++----------------------- + 1 file changed, 53 insertions(+), 53 deletions(-) + +diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h +index 3d9270a9e885..cfff9fd5d858 100644 +--- a/include/linux/page-flags.h ++++ b/include/linux/page-flags.h +@@ -130,15 +130,15 @@ enum pageflags { + #ifndef __GENERATING_BOUNDS_H + + /* Page flags policies wrt compound pages */ +-#define ANY(page, enforce) page +-#define HEAD(page, enforce) compound_head(page) +-#define NO_TAIL(page, enforce) ({ \ ++#define PF_ANY(page, enforce) page ++#define PF_HEAD(page, enforce) compound_head(page) ++#define PF_NO_TAIL(page, enforce) ({ \ + if (enforce) \ + VM_BUG_ON_PAGE(PageTail(page), page); \ + else \ + page = compound_head(page); \ + page;}) +-#define NO_COMPOUND(page, enforce) ({ \ ++#define PF_NO_COMPOUND(page, enforce) ({ \ + if (enforce) \ + VM_BUG_ON_PAGE(PageCompound(page), page); \ + page;}) +@@ -225,55 +225,55 @@ static inline int PageCompound(struct page *page); + static inline int PageTail(struct page *page); + static struct page *compound_head(struct page *page); + +-__PAGEFLAG(Locked, locked, NO_TAIL) +-PAGEFLAG(Error, error, NO_COMPOUND) TESTCLEARFLAG(Error, error, NO_COMPOUND) +-PAGEFLAG(Referenced, referenced, HEAD) +- TESTCLEARFLAG(Referenced, referenced, HEAD) +- __SETPAGEFLAG(Referenced, referenced, HEAD) +-PAGEFLAG(Dirty, dirty, HEAD) TESTSCFLAG(Dirty, dirty, HEAD) +- __CLEARPAGEFLAG(Dirty, dirty, HEAD) +-PAGEFLAG(LRU, lru, HEAD) __CLEARPAGEFLAG(LRU, lru, HEAD) +-PAGEFLAG(Active, active, HEAD) __CLEARPAGEFLAG(Active, active, HEAD) +- TESTCLEARFLAG(Active, active, HEAD) +-__PAGEFLAG(Slab, slab, NO_TAIL) +-__PAGEFLAG(SlobFree, slob_free, NO_TAIL) +-PAGEFLAG(Checked, checked, NO_COMPOUND) /* Used by some filesystems */ ++__PAGEFLAG(Locked, locked, PF_NO_TAIL) ++PAGEFLAG(Error, error, PF_NO_COMPOUND) TESTCLEARFLAG(Error, error, PF_NO_COMPOUND) ++PAGEFLAG(Referenced, referenced, PF_HEAD) ++ TESTCLEARFLAG(Referenced, referenced, PF_HEAD) ++ __SETPAGEFLAG(Referenced, referenced, PF_HEAD) ++PAGEFLAG(Dirty, dirty, PF_HEAD) TESTSCFLAG(Dirty, dirty, PF_HEAD) ++ __CLEARPAGEFLAG(Dirty, dirty, PF_HEAD) ++PAGEFLAG(LRU, lru, PF_HEAD) __CLEARPAGEFLAG(LRU, lru, PF_HEAD) ++PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD) ++ TESTCLEARFLAG(Active, active, PF_HEAD) ++__PAGEFLAG(Slab, slab, PF_NO_TAIL) ++__PAGEFLAG(SlobFree, slob_free, PF_NO_TAIL) ++PAGEFLAG(Checked, checked, PF_NO_COMPOUND) /* Used by some filesystems */ + + /* Xen */ +-PAGEFLAG(Pinned, pinned, NO_COMPOUND) TESTSCFLAG(Pinned, pinned, NO_COMPOUND) +-PAGEFLAG(SavePinned, savepinned, NO_COMPOUND) +-PAGEFLAG(Foreign, foreign, NO_COMPOUND) ++PAGEFLAG(Pinned, pinned, PF_NO_COMPOUND) TESTSCFLAG(Pinned, pinned, PF_NO_COMPOUND) ++PAGEFLAG(SavePinned, savepinned, PF_NO_COMPOUND) ++PAGEFLAG(Foreign, foreign, PF_NO_COMPOUND) + +-PAGEFLAG(Reserved, reserved, NO_COMPOUND) +- __CLEARPAGEFLAG(Reserved, reserved, NO_COMPOUND) +-PAGEFLAG(SwapBacked, swapbacked, NO_TAIL) +- __CLEARPAGEFLAG(SwapBacked, swapbacked, NO_TAIL) +- __SETPAGEFLAG(SwapBacked, swapbacked, NO_TAIL) ++PAGEFLAG(Reserved, reserved, PF_NO_COMPOUND) ++ __CLEARPAGEFLAG(Reserved, reserved, PF_NO_COMPOUND) ++PAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL) ++ __CLEARPAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL) ++ __SETPAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL) + + /* + * Private page markings that may be used by the filesystem that owns the page + * for its own purposes. + * - PG_private and PG_private_2 cause releasepage() and co to be invoked + */ +-PAGEFLAG(Private, private, ANY) __SETPAGEFLAG(Private, private, ANY) +- __CLEARPAGEFLAG(Private, private, ANY) +-PAGEFLAG(Private2, private_2, ANY) TESTSCFLAG(Private2, private_2, ANY) +-PAGEFLAG(OwnerPriv1, owner_priv_1, ANY) +- TESTCLEARFLAG(OwnerPriv1, owner_priv_1, ANY) ++PAGEFLAG(Private, private, PF_ANY) __SETPAGEFLAG(Private, private, PF_ANY) ++ __CLEARPAGEFLAG(Private, private, PF_ANY) ++PAGEFLAG(Private2, private_2, PF_ANY) TESTSCFLAG(Private2, private_2, PF_ANY) ++PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY) ++ TESTCLEARFLAG(OwnerPriv1, owner_priv_1, PF_ANY) + + /* + * Only test-and-set exist for PG_writeback. The unconditional operators are + * risky: they bypass page accounting. + */ +-TESTPAGEFLAG(Writeback, writeback, NO_COMPOUND) +- TESTSCFLAG(Writeback, writeback, NO_COMPOUND) +-PAGEFLAG(MappedToDisk, mappedtodisk, NO_COMPOUND) ++TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND) ++ TESTSCFLAG(Writeback, writeback, PF_NO_COMPOUND) ++PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_COMPOUND) + + /* PG_readahead is only used for reads; PG_reclaim is only for writes */ +-PAGEFLAG(Reclaim, reclaim, NO_COMPOUND) +- TESTCLEARFLAG(Reclaim, reclaim, NO_COMPOUND) +-PAGEFLAG(Readahead, reclaim, NO_COMPOUND) +- TESTCLEARFLAG(Readahead, reclaim, NO_COMPOUND) ++PAGEFLAG(Reclaim, reclaim, PF_NO_COMPOUND) ++ TESTCLEARFLAG(Reclaim, reclaim, PF_NO_COMPOUND) ++PAGEFLAG(Readahead, reclaim, PF_NO_COMPOUND) ++ TESTCLEARFLAG(Readahead, reclaim, PF_NO_COMPOUND) + + #ifdef CONFIG_HIGHMEM + /* +@@ -286,33 +286,33 @@ PAGEFLAG_FALSE(HighMem) + #endif + + #ifdef CONFIG_SWAP +-PAGEFLAG(SwapCache, swapcache, NO_COMPOUND) ++PAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND) + #else + PAGEFLAG_FALSE(SwapCache) + #endif + +-PAGEFLAG(Unevictable, unevictable, HEAD) +- __CLEARPAGEFLAG(Unevictable, unevictable, HEAD) +- TESTCLEARFLAG(Unevictable, unevictable, HEAD) ++PAGEFLAG(Unevictable, unevictable, PF_HEAD) ++ __CLEARPAGEFLAG(Unevictable, unevictable, PF_HEAD) ++ TESTCLEARFLAG(Unevictable, unevictable, PF_HEAD) + + #ifdef CONFIG_MMU +-PAGEFLAG(Mlocked, mlocked, NO_TAIL) __CLEARPAGEFLAG(Mlocked, mlocked, NO_TAIL) +- TESTSCFLAG(Mlocked, mlocked, NO_TAIL) +- __TESTCLEARFLAG(Mlocked, mlocked, NO_TAIL) ++PAGEFLAG(Mlocked, mlocked, PF_NO_TAIL) __CLEARPAGEFLAG(Mlocked, mlocked, PF_NO_TAIL) ++ TESTSCFLAG(Mlocked, mlocked, PF_NO_TAIL) ++ __TESTCLEARFLAG(Mlocked, mlocked, PF_NO_TAIL) + #else + PAGEFLAG_FALSE(Mlocked) __CLEARPAGEFLAG_NOOP(Mlocked) + TESTSCFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked) + #endif + + #ifdef CONFIG_ARCH_USES_PG_UNCACHED +-PAGEFLAG(Uncached, uncached, NO_COMPOUND) ++PAGEFLAG(Uncached, uncached, PF_NO_COMPOUND) + #else + PAGEFLAG_FALSE(Uncached) + #endif + + #ifdef CONFIG_MEMORY_FAILURE +-PAGEFLAG(HWPoison, hwpoison, ANY) +-TESTSCFLAG(HWPoison, hwpoison, ANY) ++PAGEFLAG(HWPoison, hwpoison, PF_ANY) ++TESTSCFLAG(HWPoison, hwpoison, PF_ANY) + #define __PG_HWPOISON (1UL << PG_hwpoison) + #else + PAGEFLAG_FALSE(HWPoison) +@@ -402,7 +402,7 @@ static inline void SetPageUptodate(struct page *page) + set_bit(PG_uptodate, &page->flags); + } + +-CLEARPAGEFLAG(Uptodate, uptodate, NO_TAIL) ++CLEARPAGEFLAG(Uptodate, uptodate, PF_NO_TAIL) + + int test_clear_page_writeback(struct page *page); + int __test_set_page_writeback(struct page *page, bool keep_write); +@@ -422,7 +422,7 @@ static inline void set_page_writeback_keepwrite(struct page *page) + test_set_page_writeback_keepwrite(page); + } + +-__PAGEFLAG(Head, head, ANY) CLEARPAGEFLAG(Head, head, ANY) ++__PAGEFLAG(Head, head, PF_ANY) CLEARPAGEFLAG(Head, head, PF_ANY) + + static inline int PageTail(struct page *page) + { +@@ -643,10 +643,10 @@ static inline int page_has_private(struct page *page) + return !!(page->flags & PAGE_FLAGS_PRIVATE); + } + +-#undef ANY +-#undef HEAD +-#undef NO_TAIL +-#undef NO_COMPOUND ++#undef PF_ANY ++#undef PF_HEAD ++#undef PF_NO_TAIL ++#undef PF_NO_COMPOUND + #endif /* !__GENERATING_BOUNDS_H */ + + #endif /* PAGE_FLAGS_H */ +-- +2.5.0 diff --git a/N1/3.hdr b/N1/3.hdr new file mode 100644 index 0000000..3753f58 --- /dev/null +++ b/N1/3.hdr @@ -0,0 +1,2 @@ +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="page-flags-introduce-page-flags-policies-wrt-compound-pages.patch" diff --git a/N1/3.txt b/N1/3.txt new file mode 100644 index 0000000..baac180 --- /dev/null +++ b/N1/3.txt @@ -0,0 +1,300 @@ +>From 54d99b201f355af4e4bd401a1b39a8570dcda948 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Date: Tue, 18 Aug 2015 09:49:48 +1000 +Subject: [PATCH] page-flags: introduce page flags policies wrt compound pages + +This patch adds a third argument to macros which create function +definitions for page flags. This argument defines how page-flags helpers +behave on compound functions. + +For now we define four policies: + +- PF_ANY: the helper function operates on the page it gets, regardless + if it's non-compound, head or tail. + +- PF_HEAD: the helper function operates on the head page of the compound + page if it gets tail page. + +- PF_NO_TAIL: only head and non-compond pages are acceptable for this + helper function. + +- PF_NO_COMPOUND: only non-compound pages are acceptable for this helper + function. + +For now we use policy PF_ANY for all helpers, which matches current +behaviour. + +We do not enforce the policy for TESTPAGEFLAG, because we have flags +checked for random pages all over the kernel. Noticeable exception to +this is PageTransHuge() which triggers VM_BUG_ON() for tail page. + +Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +Cc: Andrea Arcangeli <aarcange@redhat.com> +Cc: Hugh Dickins <hughd@google.com> +Cc: Dave Hansen <dave.hansen@intel.com> +Cc: Mel Gorman <mgorman@suse.de> +Cc: Rik van Riel <riel@redhat.com> +Cc: Vlastimil Babka <vbabka@suse.cz> +Cc: Christoph Lameter <cl@linux.com> +Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> +Cc: Steve Capper <steve.capper@linaro.org> +Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> +Cc: Johannes Weiner <hannes@cmpxchg.org> +Cc: Michal Hocko <mhocko@suse.cz> +Cc: Jerome Marchand <jmarchan@redhat.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +--- + include/linux/page-flags.h | 153 +++++++++++++++++++++++++++------------------ + 1 file changed, 92 insertions(+), 61 deletions(-) + +diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h +index 490fbd3f8552..85b60119523a 100644 +--- a/include/linux/page-flags.h ++++ b/include/linux/page-flags.h +@@ -129,49 +129,68 @@ enum pageflags { + + #ifndef __GENERATING_BOUNDS_H + ++/* Page flags policies wrt compound pages */ ++#define ANY(page, enforce) page ++#define HEAD(page, enforce) compound_head(page) ++#define NO_TAIL(page, enforce) ({ \ ++ if (enforce) \ ++ VM_BUG_ON_PAGE(PageTail(page), page); \ ++ else \ ++ page = compound_head(page); \ ++ page;}) ++#define NO_COMPOUND(page, enforce) ({ \ ++ if (enforce) \ ++ VM_BUG_ON_PAGE(PageCompound(page), page); \ ++ page;}) ++ + /* + * Macros to create function definitions for page flags + */ +-#define TESTPAGEFLAG(uname, lname) \ +-static inline int Page##uname(const struct page *page) \ +- { return test_bit(PG_##lname, &page->flags); } ++#define TESTPAGEFLAG(uname, lname, policy) \ ++static inline int Page##uname(struct page *page) \ ++ { return test_bit(PG_##lname, &policy(page, 0)->flags); } + +-#define SETPAGEFLAG(uname, lname) \ ++#define SETPAGEFLAG(uname, lname, policy) \ + static inline void SetPage##uname(struct page *page) \ +- { set_bit(PG_##lname, &page->flags); } ++ { set_bit(PG_##lname, &policy(page, 1)->flags); } + +-#define CLEARPAGEFLAG(uname, lname) \ ++#define CLEARPAGEFLAG(uname, lname, policy) \ + static inline void ClearPage##uname(struct page *page) \ +- { clear_bit(PG_##lname, &page->flags); } ++ { clear_bit(PG_##lname, &policy(page, 1)->flags); } + +-#define __SETPAGEFLAG(uname, lname) \ ++#define __SETPAGEFLAG(uname, lname, policy) \ + static inline void __SetPage##uname(struct page *page) \ +- { __set_bit(PG_##lname, &page->flags); } ++ { __set_bit(PG_##lname, &policy(page, 1)->flags); } + +-#define __CLEARPAGEFLAG(uname, lname) \ ++#define __CLEARPAGEFLAG(uname, lname, policy) \ + static inline void __ClearPage##uname(struct page *page) \ +- { __clear_bit(PG_##lname, &page->flags); } ++ { __clear_bit(PG_##lname, &policy(page, 1)->flags); } + +-#define TESTSETFLAG(uname, lname) \ ++#define TESTSETFLAG(uname, lname, policy) \ + static inline int TestSetPage##uname(struct page *page) \ +- { return test_and_set_bit(PG_##lname, &page->flags); } ++ { return test_and_set_bit(PG_##lname, &policy(page, 1)->flags); } + +-#define TESTCLEARFLAG(uname, lname) \ ++#define TESTCLEARFLAG(uname, lname, policy) \ + static inline int TestClearPage##uname(struct page *page) \ +- { return test_and_clear_bit(PG_##lname, &page->flags); } ++ { return test_and_clear_bit(PG_##lname, &policy(page, 1)->flags); } + +-#define __TESTCLEARFLAG(uname, lname) \ ++#define __TESTCLEARFLAG(uname, lname, policy) \ + static inline int __TestClearPage##uname(struct page *page) \ +- { return __test_and_clear_bit(PG_##lname, &page->flags); } ++ { return __test_and_clear_bit(PG_##lname, &policy(page, 1)->flags); } + +-#define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \ +- SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname) ++#define PAGEFLAG(uname, lname, policy) \ ++ TESTPAGEFLAG(uname, lname, policy) \ ++ SETPAGEFLAG(uname, lname, policy) \ ++ CLEARPAGEFLAG(uname, lname, policy) + +-#define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \ +- __SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname) ++#define __PAGEFLAG(uname, lname, policy) \ ++ TESTPAGEFLAG(uname, lname, policy) \ ++ __SETPAGEFLAG(uname, lname, policy) \ ++ __CLEARPAGEFLAG(uname, lname, policy) + +-#define TESTSCFLAG(uname, lname) \ +- TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname) ++#define TESTSCFLAG(uname, lname, policy) \ ++ TESTSETFLAG(uname, lname, policy) \ ++ TESTCLEARFLAG(uname, lname, policy) + + #define TESTPAGEFLAG_FALSE(uname) \ + static inline int Page##uname(const struct page *page) { return 0; } +@@ -200,47 +219,54 @@ static inline int __TestClearPage##uname(struct page *page) { return 0; } + #define TESTSCFLAG_FALSE(uname) \ + TESTSETFLAG_FALSE(uname) TESTCLEARFLAG_FALSE(uname) + +-struct page; /* forward declaration */ +- +-TESTPAGEFLAG(Locked, locked) +-PAGEFLAG(Error, error) TESTCLEARFLAG(Error, error) +-PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced) +- __SETPAGEFLAG(Referenced, referenced) +-PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty) +-PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru) +-PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active) +- TESTCLEARFLAG(Active, active) +-__PAGEFLAG(Slab, slab) +-PAGEFLAG(Checked, checked) /* Used by some filesystems */ +-PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned) /* Xen */ +-PAGEFLAG(SavePinned, savepinned); /* Xen */ +-PAGEFLAG(Foreign, foreign); /* Xen */ +-PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved) +-PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked) +- __SETPAGEFLAG(SwapBacked, swapbacked) +- +-__PAGEFLAG(SlobFree, slob_free) ++/* Forward declarations */ ++struct page; ++static inline int PageCompound(struct page *page); ++static inline int PageTail(struct page *page); ++static struct page *compound_head(struct page *page); ++ ++TESTPAGEFLAG(Locked, locked, ANY) ++PAGEFLAG(Error, error, ANY) TESTCLEARFLAG(Error, error, ANY) ++PAGEFLAG(Referenced, referenced, ANY) TESTCLEARFLAG(Referenced, referenced, ANY) ++ __SETPAGEFLAG(Referenced, referenced, ANY) ++PAGEFLAG(Dirty, dirty, ANY) TESTSCFLAG(Dirty, dirty, ANY) ++ __CLEARPAGEFLAG(Dirty, dirty, ANY) ++PAGEFLAG(LRU, lru, ANY) __CLEARPAGEFLAG(LRU, lru, ANY) ++PAGEFLAG(Active, active, ANY) __CLEARPAGEFLAG(Active, active, ANY) ++ TESTCLEARFLAG(Active, active, ANY) ++__PAGEFLAG(Slab, slab, ANY) ++PAGEFLAG(Checked, checked, ANY) /* Used by some filesystems */ ++PAGEFLAG(Pinned, pinned, ANY) TESTSCFLAG(Pinned, pinned, ANY) /* Xen */ ++PAGEFLAG(SavePinned, savepinned, ANY); /* Xen */ ++PAGEFLAG(Foreign, foreign, ANY); /* Xen */ ++PAGEFLAG(Reserved, reserved, ANY) __CLEARPAGEFLAG(Reserved, reserved, ANY) ++PAGEFLAG(SwapBacked, swapbacked, ANY) ++ __CLEARPAGEFLAG(SwapBacked, swapbacked, ANY) ++ __SETPAGEFLAG(SwapBacked, swapbacked, ANY) ++ ++__PAGEFLAG(SlobFree, slob_free, ANY) + + /* + * Private page markings that may be used by the filesystem that owns the page + * for its own purposes. + * - PG_private and PG_private_2 cause releasepage() and co to be invoked + */ +-PAGEFLAG(Private, private) __SETPAGEFLAG(Private, private) +- __CLEARPAGEFLAG(Private, private) +-PAGEFLAG(Private2, private_2) TESTSCFLAG(Private2, private_2) +-PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1) ++PAGEFLAG(Private, private, ANY) __SETPAGEFLAG(Private, private, ANY) ++ __CLEARPAGEFLAG(Private, private, ANY) ++PAGEFLAG(Private2, private_2, ANY) TESTSCFLAG(Private2, private_2, ANY) ++PAGEFLAG(OwnerPriv1, owner_priv_1, ANY) ++ TESTCLEARFLAG(OwnerPriv1, owner_priv_1, ANY) + + /* + * Only test-and-set exist for PG_writeback. The unconditional operators are + * risky: they bypass page accounting. + */ +-TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback) +-PAGEFLAG(MappedToDisk, mappedtodisk) ++TESTPAGEFLAG(Writeback, writeback, ANY) TESTSCFLAG(Writeback, writeback, ANY) ++PAGEFLAG(MappedToDisk, mappedtodisk, ANY) + + /* PG_readahead is only used for reads; PG_reclaim is only for writes */ +-PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim) +-PAGEFLAG(Readahead, reclaim) TESTCLEARFLAG(Readahead, reclaim) ++PAGEFLAG(Reclaim, reclaim, ANY) TESTCLEARFLAG(Reclaim, reclaim, ANY) ++PAGEFLAG(Readahead, reclaim, ANY) TESTCLEARFLAG(Readahead, reclaim, ANY) + + #ifdef CONFIG_HIGHMEM + /* +@@ -253,31 +279,32 @@ PAGEFLAG_FALSE(HighMem) + #endif + + #ifdef CONFIG_SWAP +-PAGEFLAG(SwapCache, swapcache) ++PAGEFLAG(SwapCache, swapcache, ANY) + #else + PAGEFLAG_FALSE(SwapCache) + #endif + +-PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable) +- TESTCLEARFLAG(Unevictable, unevictable) ++PAGEFLAG(Unevictable, unevictable, ANY) ++ __CLEARPAGEFLAG(Unevictable, unevictable, ANY) ++ TESTCLEARFLAG(Unevictable, unevictable, ANY) + + #ifdef CONFIG_MMU +-PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked) +- TESTSCFLAG(Mlocked, mlocked) __TESTCLEARFLAG(Mlocked, mlocked) ++PAGEFLAG(Mlocked, mlocked, ANY) __CLEARPAGEFLAG(Mlocked, mlocked, ANY) ++ TESTSCFLAG(Mlocked, mlocked, ANY) __TESTCLEARFLAG(Mlocked, mlocked, ANY) + #else + PAGEFLAG_FALSE(Mlocked) __CLEARPAGEFLAG_NOOP(Mlocked) + TESTSCFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked) + #endif + + #ifdef CONFIG_ARCH_USES_PG_UNCACHED +-PAGEFLAG(Uncached, uncached) ++PAGEFLAG(Uncached, uncached, ANY) + #else + PAGEFLAG_FALSE(Uncached) + #endif + + #ifdef CONFIG_MEMORY_FAILURE +-PAGEFLAG(HWPoison, hwpoison) +-TESTSCFLAG(HWPoison, hwpoison) ++PAGEFLAG(HWPoison, hwpoison, ANY) ++TESTSCFLAG(HWPoison, hwpoison, ANY) + #define __PG_HWPOISON (1UL << PG_hwpoison) + #else + PAGEFLAG_FALSE(HWPoison) +@@ -362,7 +389,7 @@ static inline void SetPageUptodate(struct page *page) + set_bit(PG_uptodate, &(page)->flags); + } + +-CLEARPAGEFLAG(Uptodate, uptodate) ++CLEARPAGEFLAG(Uptodate, uptodate, ANY) + + int test_clear_page_writeback(struct page *page); + int __test_set_page_writeback(struct page *page, bool keep_write); +@@ -382,7 +409,7 @@ static inline void set_page_writeback_keepwrite(struct page *page) + test_set_page_writeback_keepwrite(page); + } + +-__PAGEFLAG(Head, head) CLEARPAGEFLAG(Head, head) ++__PAGEFLAG(Head, head, ANY) CLEARPAGEFLAG(Head, head, ANY) + + static inline int PageTail(struct page *page) + { +@@ -603,6 +630,10 @@ static inline int page_has_private(struct page *page) + return !!(page->flags & PAGE_FLAGS_PRIVATE); + } + ++#undef ANY ++#undef HEAD ++#undef NO_TAIL ++#undef NO_COMPOUND + #endif /* !__GENERATING_BOUNDS_H */ + + #endif /* PAGE_FLAGS_H */ +-- +2.5.0 diff --git a/N1/4.hdr b/N1/4.hdr new file mode 100644 index 0000000..a050984 --- /dev/null +++ b/N1/4.hdr @@ -0,0 +1,2 @@ +Content-Type: text/plain; charset=us-ascii +Content-Disposition: attachment; filename="mm-sanitize-page-mapping-for-tail-pages.patch" diff --git a/N1/4.txt b/N1/4.txt new file mode 100644 index 0000000..ba856af --- /dev/null +++ b/N1/4.txt @@ -0,0 +1,144 @@ +>From cdb3d7e7f717f3e96ee97c4b0a29a745701bd813 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Date: Tue, 18 Aug 2015 09:49:51 +1000 +Subject: [PATCH] mm: sanitize page->mapping for tail pages + +We don't define meaning of page->mapping for tail pages. Currently it's +always NULL, which can be inconsistent with head page and potentially lead +to problems. + +Let's poison the pointer to catch all illigal uses. + +page_rmapping(), page_mapping() and page_anon_vma() are changed to look on +head page. + +The only illegal use I've caught so far is __GPF_COMP pages from sound +subsystem, mapped with PTEs. do_shared_fault() is changed to use +page_rmapping() instead of direct access to fault_page->mapping. + +Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +Cc: Andrea Arcangeli <aarcange@redhat.com> +Cc: Hugh Dickins <hughd@google.com> +Cc: Dave Hansen <dave.hansen@intel.com> +Cc: Mel Gorman <mgorman@suse.de> +Cc: Rik van Riel <riel@redhat.com> +Cc: Vlastimil Babka <vbabka@suse.cz> +Cc: Christoph Lameter <cl@linux.com> +Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> +Cc: Steve Capper <steve.capper@linaro.org> +Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> +Cc: Johannes Weiner <hannes@cmpxchg.org> +Cc: Michal Hocko <mhocko@suse.cz> +Cc: Jerome Marchand <jmarchan@redhat.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +--- + include/linux/poison.h | 4 ++++ + mm/huge_memory.c | 2 +- + mm/memory.c | 2 +- + mm/page_alloc.c | 6 ++++++ + mm/util.c | 10 ++++++---- + 5 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/include/linux/poison.h b/include/linux/poison.h +index 2110a81c5e2a..7b2a7fcde6a3 100644 +--- a/include/linux/poison.h ++++ b/include/linux/poison.h +@@ -32,6 +32,10 @@ + /********** mm/debug-pagealloc.c **********/ + #define PAGE_POISON 0xaa + ++/********** mm/page_alloc.c ************/ ++ ++#define TAIL_MAPPING ((void *) 0x01014A11 + POISON_POINTER_DELTA) ++ + /********** mm/slab.c **********/ + /* + * Magic nums for obj red zoning. +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 7ef15f8f8bf3..1a3accef0756 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1772,7 +1772,7 @@ static void __split_huge_page_refcount(struct page *page, + */ + page_tail->_mapcount = page->_mapcount; + +- BUG_ON(page_tail->mapping); ++ BUG_ON(page_tail->mapping != TAIL_MAPPING); + page_tail->mapping = page->mapping; + + page_tail->index = page->index + i; +diff --git a/mm/memory.c b/mm/memory.c +index 6cd0b2160401..558ee16167d9 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -3087,7 +3087,7 @@ static int do_shared_fault(struct mm_struct *mm, struct vm_area_struct *vma, + * pinned by vma->vm_file's reference. We rely on unlock_page()'s + * release semantics to prevent the compiler from undoing this copying. + */ +- mapping = fault_page->mapping; ++ mapping = page_rmapping(fault_page); + unlock_page(fault_page); + if ((dirtied || vma->vm_ops->page_mkwrite) && mapping) { + /* +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index d752298a9e48..adefa3ad8e3e 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -470,6 +470,7 @@ void prep_compound_page(struct page *page, unsigned int order) + for (i = 1; i < nr_pages; i++) { + struct page *p = page + i; + set_page_count(p, 0); ++ p->mapping = TAIL_MAPPING; + set_compound_head(p, page); + } + } +@@ -855,6 +856,10 @@ static int free_tail_pages_check(struct page *head_page, struct page *page) + ret = 0; + goto out; + } ++ if (page->mapping != TAIL_MAPPING) { ++ bad_page(page, "corrupted mapping in tail page", 0); ++ goto out; ++ } + if (unlikely(!PageTail(page))) { + bad_page(page, "PageTail not set", 0); + goto out; +@@ -865,6 +870,7 @@ static int free_tail_pages_check(struct page *head_page, struct page *page) + } + ret = 0; + out: ++ page->mapping = NULL; + clear_compound_head(page); + return ret; + } +diff --git a/mm/util.c b/mm/util.c +index 68ff8a5361e7..0c7f65e7ef5e 100644 +--- a/mm/util.c ++++ b/mm/util.c +@@ -355,7 +355,9 @@ struct anon_vma *page_anon_vma(struct page *page) + + struct address_space *page_mapping(struct page *page) + { +- unsigned long mapping; ++ struct address_space *mapping; ++ ++ page = compound_head(page); + + /* This happens if someone calls flush_dcache_page on slab page */ + if (unlikely(PageSlab(page))) +@@ -368,10 +370,10 @@ struct address_space *page_mapping(struct page *page) + return swap_address_space(entry); + } + +- mapping = (unsigned long)page->mapping; +- if (mapping & PAGE_MAPPING_FLAGS) ++ mapping = page->mapping; ++ if ((unsigned long)mapping & PAGE_MAPPING_FLAGS) + return NULL; +- return page->mapping; ++ return mapping; + } + + int overcommit_ratio_handler(struct ctl_table *table, int write, +-- +2.5.0 diff --git a/a/content_digest b/N1/content_digest index fb8bcbe..dec5a93 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -77,5 +77,658 @@ "\01:2\0" "fn\0include-linux-page-flagsh-rename-macros-to-avoid-collisions.patch\0" "b\0" + ">From 1b88b5b6025e81a9f6b99275d66e129de52bd795 Mon Sep 17 00:00:00 2001\n" + "From: Andrew Morton <akpm@linux-foundation.org>\n" + "Date: Tue, 18 Aug 2015 09:49:52 +1000\n" + "Subject: [PATCH] include/linux/page-flags.h: rename macros to avoid collisions\n" + "\n" + "Cc: \"Kirill A. Shutemov\" <kirill.shutemov@linux.intel.com>\n" + "Signed-off-by: Andrew Morton <akpm@linux-foundation.org>\n" + "---\n" + " include/linux/page-flags.h | 106 ++++++++++++++++++++++-----------------------\n" + " 1 file changed, 53 insertions(+), 53 deletions(-)\n" + "\n" + "diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h\n" + "index 3d9270a9e885..cfff9fd5d858 100644\n" + "--- a/include/linux/page-flags.h\n" + "+++ b/include/linux/page-flags.h\n" + "@@ -130,15 +130,15 @@ enum pageflags {\n" + " #ifndef __GENERATING_BOUNDS_H\n" + " \n" + " /* Page flags policies wrt compound pages */\n" + "-#define ANY(page, enforce)\tpage\n" + "-#define HEAD(page, enforce)\tcompound_head(page)\n" + "-#define NO_TAIL(page, enforce) ({\t\t\t\t\t\\\n" + "+#define PF_ANY(page, enforce)\tpage\n" + "+#define PF_HEAD(page, enforce)\tcompound_head(page)\n" + "+#define PF_NO_TAIL(page, enforce) ({\t\t\t\t\t\\\n" + " \t\tif (enforce)\t\t\t\t\t\t\\\n" + " \t\t\tVM_BUG_ON_PAGE(PageTail(page), page);\t\t\\\n" + " \t\telse\t\t\t\t\t\t\t\\\n" + " \t\t\tpage = compound_head(page);\t\t\t\\\n" + " \t\tpage;})\n" + "-#define NO_COMPOUND(page, enforce) ({\t\t\t\t\t\\\n" + "+#define PF_NO_COMPOUND(page, enforce) ({\t\t\t\t\t\\\n" + " \t\tif (enforce)\t\t\t\t\t\t\\\n" + " \t\t\tVM_BUG_ON_PAGE(PageCompound(page), page);\t\\\n" + " \t\tpage;})\n" + "@@ -225,55 +225,55 @@ static inline int PageCompound(struct page *page);\n" + " static inline int PageTail(struct page *page);\n" + " static struct page *compound_head(struct page *page);\n" + " \n" + "-__PAGEFLAG(Locked, locked, NO_TAIL)\n" + "-PAGEFLAG(Error, error, NO_COMPOUND) TESTCLEARFLAG(Error, error, NO_COMPOUND)\n" + "-PAGEFLAG(Referenced, referenced, HEAD)\n" + "-\tTESTCLEARFLAG(Referenced, referenced, HEAD)\n" + "-\t__SETPAGEFLAG(Referenced, referenced, HEAD)\n" + "-PAGEFLAG(Dirty, dirty, HEAD) TESTSCFLAG(Dirty, dirty, HEAD)\n" + "-\t__CLEARPAGEFLAG(Dirty, dirty, HEAD)\n" + "-PAGEFLAG(LRU, lru, HEAD) __CLEARPAGEFLAG(LRU, lru, HEAD)\n" + "-PAGEFLAG(Active, active, HEAD) __CLEARPAGEFLAG(Active, active, HEAD)\n" + "-\tTESTCLEARFLAG(Active, active, HEAD)\n" + "-__PAGEFLAG(Slab, slab, NO_TAIL)\n" + "-__PAGEFLAG(SlobFree, slob_free, NO_TAIL)\n" + "-PAGEFLAG(Checked, checked, NO_COMPOUND) /* Used by some filesystems */\n" + "+__PAGEFLAG(Locked, locked, PF_NO_TAIL)\n" + "+PAGEFLAG(Error, error, PF_NO_COMPOUND) TESTCLEARFLAG(Error, error, PF_NO_COMPOUND)\n" + "+PAGEFLAG(Referenced, referenced, PF_HEAD)\n" + "+\tTESTCLEARFLAG(Referenced, referenced, PF_HEAD)\n" + "+\t__SETPAGEFLAG(Referenced, referenced, PF_HEAD)\n" + "+PAGEFLAG(Dirty, dirty, PF_HEAD) TESTSCFLAG(Dirty, dirty, PF_HEAD)\n" + "+\t__CLEARPAGEFLAG(Dirty, dirty, PF_HEAD)\n" + "+PAGEFLAG(LRU, lru, PF_HEAD) __CLEARPAGEFLAG(LRU, lru, PF_HEAD)\n" + "+PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD)\n" + "+\tTESTCLEARFLAG(Active, active, PF_HEAD)\n" + "+__PAGEFLAG(Slab, slab, PF_NO_TAIL)\n" + "+__PAGEFLAG(SlobFree, slob_free, PF_NO_TAIL)\n" + "+PAGEFLAG(Checked, checked, PF_NO_COMPOUND) /* Used by some filesystems */\n" + " \n" + " /* Xen */\n" + "-PAGEFLAG(Pinned, pinned, NO_COMPOUND) TESTSCFLAG(Pinned, pinned, NO_COMPOUND)\n" + "-PAGEFLAG(SavePinned, savepinned, NO_COMPOUND)\n" + "-PAGEFLAG(Foreign, foreign, NO_COMPOUND)\n" + "+PAGEFLAG(Pinned, pinned, PF_NO_COMPOUND) TESTSCFLAG(Pinned, pinned, PF_NO_COMPOUND)\n" + "+PAGEFLAG(SavePinned, savepinned, PF_NO_COMPOUND)\n" + "+PAGEFLAG(Foreign, foreign, PF_NO_COMPOUND)\n" + " \n" + "-PAGEFLAG(Reserved, reserved, NO_COMPOUND)\n" + "-\t__CLEARPAGEFLAG(Reserved, reserved, NO_COMPOUND)\n" + "-PAGEFLAG(SwapBacked, swapbacked, NO_TAIL)\n" + "-\t__CLEARPAGEFLAG(SwapBacked, swapbacked, NO_TAIL)\n" + "-\t__SETPAGEFLAG(SwapBacked, swapbacked, NO_TAIL)\n" + "+PAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)\n" + "+\t__CLEARPAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)\n" + "+PAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)\n" + "+\t__CLEARPAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)\n" + "+\t__SETPAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)\n" + " \n" + " /*\n" + " * Private page markings that may be used by the filesystem that owns the page\n" + " * for its own purposes.\n" + " * - PG_private and PG_private_2 cause releasepage() and co to be invoked\n" + " */\n" + "-PAGEFLAG(Private, private, ANY) __SETPAGEFLAG(Private, private, ANY)\n" + "-\t__CLEARPAGEFLAG(Private, private, ANY)\n" + "-PAGEFLAG(Private2, private_2, ANY) TESTSCFLAG(Private2, private_2, ANY)\n" + "-PAGEFLAG(OwnerPriv1, owner_priv_1, ANY)\n" + "-\tTESTCLEARFLAG(OwnerPriv1, owner_priv_1, ANY)\n" + "+PAGEFLAG(Private, private, PF_ANY) __SETPAGEFLAG(Private, private, PF_ANY)\n" + "+\t__CLEARPAGEFLAG(Private, private, PF_ANY)\n" + "+PAGEFLAG(Private2, private_2, PF_ANY) TESTSCFLAG(Private2, private_2, PF_ANY)\n" + "+PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY)\n" + "+\tTESTCLEARFLAG(OwnerPriv1, owner_priv_1, PF_ANY)\n" + " \n" + " /*\n" + " * Only test-and-set exist for PG_writeback. The unconditional operators are\n" + " * risky: they bypass page accounting.\n" + " */\n" + "-TESTPAGEFLAG(Writeback, writeback, NO_COMPOUND)\n" + "-\tTESTSCFLAG(Writeback, writeback, NO_COMPOUND)\n" + "-PAGEFLAG(MappedToDisk, mappedtodisk, NO_COMPOUND)\n" + "+TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)\n" + "+\tTESTSCFLAG(Writeback, writeback, PF_NO_COMPOUND)\n" + "+PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_COMPOUND)\n" + " \n" + " /* PG_readahead is only used for reads; PG_reclaim is only for writes */\n" + "-PAGEFLAG(Reclaim, reclaim, NO_COMPOUND)\n" + "-\tTESTCLEARFLAG(Reclaim, reclaim, NO_COMPOUND)\n" + "-PAGEFLAG(Readahead, reclaim, NO_COMPOUND)\n" + "-\tTESTCLEARFLAG(Readahead, reclaim, NO_COMPOUND)\n" + "+PAGEFLAG(Reclaim, reclaim, PF_NO_COMPOUND)\n" + "+\tTESTCLEARFLAG(Reclaim, reclaim, PF_NO_COMPOUND)\n" + "+PAGEFLAG(Readahead, reclaim, PF_NO_COMPOUND)\n" + "+\tTESTCLEARFLAG(Readahead, reclaim, PF_NO_COMPOUND)\n" + " \n" + " #ifdef CONFIG_HIGHMEM\n" + " /*\n" + "@@ -286,33 +286,33 @@ PAGEFLAG_FALSE(HighMem)\n" + " #endif\n" + " \n" + " #ifdef CONFIG_SWAP\n" + "-PAGEFLAG(SwapCache, swapcache, NO_COMPOUND)\n" + "+PAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND)\n" + " #else\n" + " PAGEFLAG_FALSE(SwapCache)\n" + " #endif\n" + " \n" + "-PAGEFLAG(Unevictable, unevictable, HEAD)\n" + "-\t__CLEARPAGEFLAG(Unevictable, unevictable, HEAD)\n" + "-\tTESTCLEARFLAG(Unevictable, unevictable, HEAD)\n" + "+PAGEFLAG(Unevictable, unevictable, PF_HEAD)\n" + "+\t__CLEARPAGEFLAG(Unevictable, unevictable, PF_HEAD)\n" + "+\tTESTCLEARFLAG(Unevictable, unevictable, PF_HEAD)\n" + " \n" + " #ifdef CONFIG_MMU\n" + "-PAGEFLAG(Mlocked, mlocked, NO_TAIL) __CLEARPAGEFLAG(Mlocked, mlocked, NO_TAIL)\n" + "-\tTESTSCFLAG(Mlocked, mlocked, NO_TAIL)\n" + "-\t__TESTCLEARFLAG(Mlocked, mlocked, NO_TAIL)\n" + "+PAGEFLAG(Mlocked, mlocked, PF_NO_TAIL) __CLEARPAGEFLAG(Mlocked, mlocked, PF_NO_TAIL)\n" + "+\tTESTSCFLAG(Mlocked, mlocked, PF_NO_TAIL)\n" + "+\t__TESTCLEARFLAG(Mlocked, mlocked, PF_NO_TAIL)\n" + " #else\n" + " PAGEFLAG_FALSE(Mlocked) __CLEARPAGEFLAG_NOOP(Mlocked)\n" + " \tTESTSCFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked)\n" + " #endif\n" + " \n" + " #ifdef CONFIG_ARCH_USES_PG_UNCACHED\n" + "-PAGEFLAG(Uncached, uncached, NO_COMPOUND)\n" + "+PAGEFLAG(Uncached, uncached, PF_NO_COMPOUND)\n" + " #else\n" + " PAGEFLAG_FALSE(Uncached)\n" + " #endif\n" + " \n" + " #ifdef CONFIG_MEMORY_FAILURE\n" + "-PAGEFLAG(HWPoison, hwpoison, ANY)\n" + "-TESTSCFLAG(HWPoison, hwpoison, ANY)\n" + "+PAGEFLAG(HWPoison, hwpoison, PF_ANY)\n" + "+TESTSCFLAG(HWPoison, hwpoison, PF_ANY)\n" + " #define __PG_HWPOISON (1UL << PG_hwpoison)\n" + " #else\n" + " PAGEFLAG_FALSE(HWPoison)\n" + "@@ -402,7 +402,7 @@ static inline void SetPageUptodate(struct page *page)\n" + " \tset_bit(PG_uptodate, &page->flags);\n" + " }\n" + " \n" + "-CLEARPAGEFLAG(Uptodate, uptodate, NO_TAIL)\n" + "+CLEARPAGEFLAG(Uptodate, uptodate, PF_NO_TAIL)\n" + " \n" + " int test_clear_page_writeback(struct page *page);\n" + " int __test_set_page_writeback(struct page *page, bool keep_write);\n" + "@@ -422,7 +422,7 @@ static inline void set_page_writeback_keepwrite(struct page *page)\n" + " \ttest_set_page_writeback_keepwrite(page);\n" + " }\n" + " \n" + "-__PAGEFLAG(Head, head, ANY) CLEARPAGEFLAG(Head, head, ANY)\n" + "+__PAGEFLAG(Head, head, PF_ANY) CLEARPAGEFLAG(Head, head, PF_ANY)\n" + " \n" + " static inline int PageTail(struct page *page)\n" + " {\n" + "@@ -643,10 +643,10 @@ static inline int page_has_private(struct page *page)\n" + " \treturn !!(page->flags & PAGE_FLAGS_PRIVATE);\n" + " }\n" + " \n" + "-#undef ANY\n" + "-#undef HEAD\n" + "-#undef NO_TAIL\n" + "-#undef NO_COMPOUND\n" + "+#undef PF_ANY\n" + "+#undef PF_HEAD\n" + "+#undef PF_NO_TAIL\n" + "+#undef PF_NO_COMPOUND\n" + " #endif /* !__GENERATING_BOUNDS_H */\n" + " \n" + " #endif\t/* PAGE_FLAGS_H */\n" + "-- \n" + 2.5.0 + "\01:3\0" + "fn\0page-flags-introduce-page-flags-policies-wrt-compound-pages.patch\0" + "b\0" + ">From 54d99b201f355af4e4bd401a1b39a8570dcda948 Mon Sep 17 00:00:00 2001\n" + "From: \"Kirill A. Shutemov\" <kirill.shutemov@linux.intel.com>\n" + "Date: Tue, 18 Aug 2015 09:49:48 +1000\n" + "Subject: [PATCH] page-flags: introduce page flags policies wrt compound pages\n" + "\n" + "This patch adds a third argument to macros which create function\n" + "definitions for page flags. This argument defines how page-flags helpers\n" + "behave on compound functions.\n" + "\n" + "For now we define four policies:\n" + "\n" + "- PF_ANY: the helper function operates on the page it gets, regardless\n" + " if it's non-compound, head or tail.\n" + "\n" + "- PF_HEAD: the helper function operates on the head page of the compound\n" + " page if it gets tail page.\n" + "\n" + "- PF_NO_TAIL: only head and non-compond pages are acceptable for this\n" + " helper function.\n" + "\n" + "- PF_NO_COMPOUND: only non-compound pages are acceptable for this helper\n" + " function.\n" + "\n" + "For now we use policy PF_ANY for all helpers, which matches current\n" + "behaviour.\n" + "\n" + "We do not enforce the policy for TESTPAGEFLAG, because we have flags\n" + "checked for random pages all over the kernel. Noticeable exception to\n" + "this is PageTransHuge() which triggers VM_BUG_ON() for tail page.\n" + "\n" + "Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>\n" + "Cc: Andrea Arcangeli <aarcange@redhat.com>\n" + "Cc: Hugh Dickins <hughd@google.com>\n" + "Cc: Dave Hansen <dave.hansen@intel.com>\n" + "Cc: Mel Gorman <mgorman@suse.de>\n" + "Cc: Rik van Riel <riel@redhat.com>\n" + "Cc: Vlastimil Babka <vbabka@suse.cz>\n" + "Cc: Christoph Lameter <cl@linux.com>\n" + "Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>\n" + "Cc: Steve Capper <steve.capper@linaro.org>\n" + "Cc: \"Aneesh Kumar K.V\" <aneesh.kumar@linux.vnet.ibm.com>\n" + "Cc: Johannes Weiner <hannes@cmpxchg.org>\n" + "Cc: Michal Hocko <mhocko@suse.cz>\n" + "Cc: Jerome Marchand <jmarchan@redhat.com>\n" + "Signed-off-by: Andrew Morton <akpm@linux-foundation.org>\n" + "---\n" + " include/linux/page-flags.h | 153 +++++++++++++++++++++++++++------------------\n" + " 1 file changed, 92 insertions(+), 61 deletions(-)\n" + "\n" + "diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h\n" + "index 490fbd3f8552..85b60119523a 100644\n" + "--- a/include/linux/page-flags.h\n" + "+++ b/include/linux/page-flags.h\n" + "@@ -129,49 +129,68 @@ enum pageflags {\n" + " \n" + " #ifndef __GENERATING_BOUNDS_H\n" + " \n" + "+/* Page flags policies wrt compound pages */\n" + "+#define ANY(page, enforce)\tpage\n" + "+#define HEAD(page, enforce)\tcompound_head(page)\n" + "+#define NO_TAIL(page, enforce) ({\t\t\t\t\t\\\n" + "+\t\tif (enforce)\t\t\t\t\t\t\\\n" + "+\t\t\tVM_BUG_ON_PAGE(PageTail(page), page);\t\t\\\n" + "+\t\telse\t\t\t\t\t\t\t\\\n" + "+\t\t\tpage = compound_head(page);\t\t\t\\\n" + "+\t\tpage;})\n" + "+#define NO_COMPOUND(page, enforce) ({\t\t\t\t\t\\\n" + "+\t\tif (enforce)\t\t\t\t\t\t\\\n" + "+\t\t\tVM_BUG_ON_PAGE(PageCompound(page), page);\t\\\n" + "+\t\tpage;})\n" + "+\n" + " /*\n" + " * Macros to create function definitions for page flags\n" + " */\n" + "-#define TESTPAGEFLAG(uname, lname)\t\t\t\t\t\\\n" + "-static inline int Page##uname(const struct page *page)\t\t\t\\\n" + "-\t\t\t{ return test_bit(PG_##lname, &page->flags); }\n" + "+#define TESTPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + "+static inline int Page##uname(struct page *page)\t\t\t\\\n" + "+\t{ return test_bit(PG_##lname, &policy(page, 0)->flags); }\n" + " \n" + "-#define SETPAGEFLAG(uname, lname)\t\t\t\t\t\\\n" + "+#define SETPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + " static inline void SetPage##uname(struct page *page)\t\t\t\\\n" + "-\t\t\t{ set_bit(PG_##lname, &page->flags); }\n" + "+\t{ set_bit(PG_##lname, &policy(page, 1)->flags); }\n" + " \n" + "-#define CLEARPAGEFLAG(uname, lname)\t\t\t\t\t\\\n" + "+#define CLEARPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + " static inline void ClearPage##uname(struct page *page)\t\t\t\\\n" + "-\t\t\t{ clear_bit(PG_##lname, &page->flags); }\n" + "+\t{ clear_bit(PG_##lname, &policy(page, 1)->flags); }\n" + " \n" + "-#define __SETPAGEFLAG(uname, lname)\t\t\t\t\t\\\n" + "+#define __SETPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + " static inline void __SetPage##uname(struct page *page)\t\t\t\\\n" + "-\t\t\t{ __set_bit(PG_##lname, &page->flags); }\n" + "+\t{ __set_bit(PG_##lname, &policy(page, 1)->flags); }\n" + " \n" + "-#define __CLEARPAGEFLAG(uname, lname)\t\t\t\t\t\\\n" + "+#define __CLEARPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + " static inline void __ClearPage##uname(struct page *page)\t\t\\\n" + "-\t\t\t{ __clear_bit(PG_##lname, &page->flags); }\n" + "+\t{ __clear_bit(PG_##lname, &policy(page, 1)->flags); }\n" + " \n" + "-#define TESTSETFLAG(uname, lname)\t\t\t\t\t\\\n" + "+#define TESTSETFLAG(uname, lname, policy)\t\t\t\t\\\n" + " static inline int TestSetPage##uname(struct page *page)\t\t\t\\\n" + "-\t\t{ return test_and_set_bit(PG_##lname, &page->flags); }\n" + "+\t{ return test_and_set_bit(PG_##lname, &policy(page, 1)->flags); }\n" + " \n" + "-#define TESTCLEARFLAG(uname, lname)\t\t\t\t\t\\\n" + "+#define TESTCLEARFLAG(uname, lname, policy)\t\t\t\t\\\n" + " static inline int TestClearPage##uname(struct page *page)\t\t\\\n" + "-\t\t{ return test_and_clear_bit(PG_##lname, &page->flags); }\n" + "+\t{ return test_and_clear_bit(PG_##lname, &policy(page, 1)->flags); }\n" + " \n" + "-#define __TESTCLEARFLAG(uname, lname)\t\t\t\t\t\\\n" + "+#define __TESTCLEARFLAG(uname, lname, policy)\t\t\t\t\\\n" + " static inline int __TestClearPage##uname(struct page *page)\t\t\\\n" + "-\t\t{ return __test_and_clear_bit(PG_##lname, &page->flags); }\n" + "+\t{ return __test_and_clear_bit(PG_##lname, &policy(page, 1)->flags); }\n" + " \n" + "-#define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname)\t\t\\\n" + "-\tSETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)\n" + "+#define PAGEFLAG(uname, lname, policy)\t\t\t\t\t\\\n" + "+\tTESTPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + "+\tSETPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + "+\tCLEARPAGEFLAG(uname, lname, policy)\n" + " \n" + "-#define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname)\t\t\\\n" + "-\t__SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname)\n" + "+#define __PAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + "+\tTESTPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + "+\t__SETPAGEFLAG(uname, lname, policy)\t\t\t\t\\\n" + "+\t__CLEARPAGEFLAG(uname, lname, policy)\n" + " \n" + "-#define TESTSCFLAG(uname, lname)\t\t\t\t\t\\\n" + "-\tTESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname)\n" + "+#define TESTSCFLAG(uname, lname, policy)\t\t\t\t\\\n" + "+\tTESTSETFLAG(uname, lname, policy)\t\t\t\t\\\n" + "+\tTESTCLEARFLAG(uname, lname, policy)\n" + " \n" + " #define TESTPAGEFLAG_FALSE(uname)\t\t\t\t\t\\\n" + " static inline int Page##uname(const struct page *page) { return 0; }\n" + "@@ -200,47 +219,54 @@ static inline int __TestClearPage##uname(struct page *page) { return 0; }\n" + " #define TESTSCFLAG_FALSE(uname)\t\t\t\t\t\t\\\n" + " \tTESTSETFLAG_FALSE(uname) TESTCLEARFLAG_FALSE(uname)\n" + " \n" + "-struct page;\t/* forward declaration */\n" + "-\n" + "-TESTPAGEFLAG(Locked, locked)\n" + "-PAGEFLAG(Error, error) TESTCLEARFLAG(Error, error)\n" + "-PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced)\n" + "-\t__SETPAGEFLAG(Referenced, referenced)\n" + "-PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty)\n" + "-PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru)\n" + "-PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active)\n" + "-\tTESTCLEARFLAG(Active, active)\n" + "-__PAGEFLAG(Slab, slab)\n" + "-PAGEFLAG(Checked, checked)\t\t/* Used by some filesystems */\n" + "-PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned)\t/* Xen */\n" + "-PAGEFLAG(SavePinned, savepinned);\t\t\t/* Xen */\n" + "-PAGEFLAG(Foreign, foreign);\t\t\t\t/* Xen */\n" + "-PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)\n" + "-PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)\n" + "-\t__SETPAGEFLAG(SwapBacked, swapbacked)\n" + "-\n" + "-__PAGEFLAG(SlobFree, slob_free)\n" + "+/* Forward declarations */\n" + "+struct page;\n" + "+static inline int PageCompound(struct page *page);\n" + "+static inline int PageTail(struct page *page);\n" + "+static struct page *compound_head(struct page *page);\n" + "+\n" + "+TESTPAGEFLAG(Locked, locked, ANY)\n" + "+PAGEFLAG(Error, error, ANY) TESTCLEARFLAG(Error, error, ANY)\n" + "+PAGEFLAG(Referenced, referenced, ANY) TESTCLEARFLAG(Referenced, referenced, ANY)\n" + "+\t__SETPAGEFLAG(Referenced, referenced, ANY)\n" + "+PAGEFLAG(Dirty, dirty, ANY) TESTSCFLAG(Dirty, dirty, ANY)\n" + "+\t__CLEARPAGEFLAG(Dirty, dirty, ANY)\n" + "+PAGEFLAG(LRU, lru, ANY) __CLEARPAGEFLAG(LRU, lru, ANY)\n" + "+PAGEFLAG(Active, active, ANY) __CLEARPAGEFLAG(Active, active, ANY)\n" + "+\tTESTCLEARFLAG(Active, active, ANY)\n" + "+__PAGEFLAG(Slab, slab, ANY)\n" + "+PAGEFLAG(Checked, checked, ANY)\t\t/* Used by some filesystems */\n" + "+PAGEFLAG(Pinned, pinned, ANY) TESTSCFLAG(Pinned, pinned, ANY)\t/* Xen */\n" + "+PAGEFLAG(SavePinned, savepinned, ANY);\t\t\t/* Xen */\n" + "+PAGEFLAG(Foreign, foreign, ANY);\t\t\t\t/* Xen */\n" + "+PAGEFLAG(Reserved, reserved, ANY) __CLEARPAGEFLAG(Reserved, reserved, ANY)\n" + "+PAGEFLAG(SwapBacked, swapbacked, ANY)\n" + "+\t__CLEARPAGEFLAG(SwapBacked, swapbacked, ANY)\n" + "+\t__SETPAGEFLAG(SwapBacked, swapbacked, ANY)\n" + "+\n" + "+__PAGEFLAG(SlobFree, slob_free, ANY)\n" + " \n" + " /*\n" + " * Private page markings that may be used by the filesystem that owns the page\n" + " * for its own purposes.\n" + " * - PG_private and PG_private_2 cause releasepage() and co to be invoked\n" + " */\n" + "-PAGEFLAG(Private, private) __SETPAGEFLAG(Private, private)\n" + "-\t__CLEARPAGEFLAG(Private, private)\n" + "-PAGEFLAG(Private2, private_2) TESTSCFLAG(Private2, private_2)\n" + "-PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1)\n" + "+PAGEFLAG(Private, private, ANY) __SETPAGEFLAG(Private, private, ANY)\n" + "+\t__CLEARPAGEFLAG(Private, private, ANY)\n" + "+PAGEFLAG(Private2, private_2, ANY) TESTSCFLAG(Private2, private_2, ANY)\n" + "+PAGEFLAG(OwnerPriv1, owner_priv_1, ANY)\n" + "+\tTESTCLEARFLAG(OwnerPriv1, owner_priv_1, ANY)\n" + " \n" + " /*\n" + " * Only test-and-set exist for PG_writeback. The unconditional operators are\n" + " * risky: they bypass page accounting.\n" + " */\n" + "-TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback)\n" + "-PAGEFLAG(MappedToDisk, mappedtodisk)\n" + "+TESTPAGEFLAG(Writeback, writeback, ANY) TESTSCFLAG(Writeback, writeback, ANY)\n" + "+PAGEFLAG(MappedToDisk, mappedtodisk, ANY)\n" + " \n" + " /* PG_readahead is only used for reads; PG_reclaim is only for writes */\n" + "-PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim)\n" + "-PAGEFLAG(Readahead, reclaim) TESTCLEARFLAG(Readahead, reclaim)\n" + "+PAGEFLAG(Reclaim, reclaim, ANY) TESTCLEARFLAG(Reclaim, reclaim, ANY)\n" + "+PAGEFLAG(Readahead, reclaim, ANY) TESTCLEARFLAG(Readahead, reclaim, ANY)\n" + " \n" + " #ifdef CONFIG_HIGHMEM\n" + " /*\n" + "@@ -253,31 +279,32 @@ PAGEFLAG_FALSE(HighMem)\n" + " #endif\n" + " \n" + " #ifdef CONFIG_SWAP\n" + "-PAGEFLAG(SwapCache, swapcache)\n" + "+PAGEFLAG(SwapCache, swapcache, ANY)\n" + " #else\n" + " PAGEFLAG_FALSE(SwapCache)\n" + " #endif\n" + " \n" + "-PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable)\n" + "-\tTESTCLEARFLAG(Unevictable, unevictable)\n" + "+PAGEFLAG(Unevictable, unevictable, ANY)\n" + "+\t__CLEARPAGEFLAG(Unevictable, unevictable, ANY)\n" + "+\tTESTCLEARFLAG(Unevictable, unevictable, ANY)\n" + " \n" + " #ifdef CONFIG_MMU\n" + "-PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked)\n" + "-\tTESTSCFLAG(Mlocked, mlocked) __TESTCLEARFLAG(Mlocked, mlocked)\n" + "+PAGEFLAG(Mlocked, mlocked, ANY) __CLEARPAGEFLAG(Mlocked, mlocked, ANY)\n" + "+\tTESTSCFLAG(Mlocked, mlocked, ANY) __TESTCLEARFLAG(Mlocked, mlocked, ANY)\n" + " #else\n" + " PAGEFLAG_FALSE(Mlocked) __CLEARPAGEFLAG_NOOP(Mlocked)\n" + " \tTESTSCFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked)\n" + " #endif\n" + " \n" + " #ifdef CONFIG_ARCH_USES_PG_UNCACHED\n" + "-PAGEFLAG(Uncached, uncached)\n" + "+PAGEFLAG(Uncached, uncached, ANY)\n" + " #else\n" + " PAGEFLAG_FALSE(Uncached)\n" + " #endif\n" + " \n" + " #ifdef CONFIG_MEMORY_FAILURE\n" + "-PAGEFLAG(HWPoison, hwpoison)\n" + "-TESTSCFLAG(HWPoison, hwpoison)\n" + "+PAGEFLAG(HWPoison, hwpoison, ANY)\n" + "+TESTSCFLAG(HWPoison, hwpoison, ANY)\n" + " #define __PG_HWPOISON (1UL << PG_hwpoison)\n" + " #else\n" + " PAGEFLAG_FALSE(HWPoison)\n" + "@@ -362,7 +389,7 @@ static inline void SetPageUptodate(struct page *page)\n" + " \tset_bit(PG_uptodate, &(page)->flags);\n" + " }\n" + " \n" + "-CLEARPAGEFLAG(Uptodate, uptodate)\n" + "+CLEARPAGEFLAG(Uptodate, uptodate, ANY)\n" + " \n" + " int test_clear_page_writeback(struct page *page);\n" + " int __test_set_page_writeback(struct page *page, bool keep_write);\n" + "@@ -382,7 +409,7 @@ static inline void set_page_writeback_keepwrite(struct page *page)\n" + " \ttest_set_page_writeback_keepwrite(page);\n" + " }\n" + " \n" + "-__PAGEFLAG(Head, head) CLEARPAGEFLAG(Head, head)\n" + "+__PAGEFLAG(Head, head, ANY) CLEARPAGEFLAG(Head, head, ANY)\n" + " \n" + " static inline int PageTail(struct page *page)\n" + " {\n" + "@@ -603,6 +630,10 @@ static inline int page_has_private(struct page *page)\n" + " \treturn !!(page->flags & PAGE_FLAGS_PRIVATE);\n" + " }\n" + " \n" + "+#undef ANY\n" + "+#undef HEAD\n" + "+#undef NO_TAIL\n" + "+#undef NO_COMPOUND\n" + " #endif /* !__GENERATING_BOUNDS_H */\n" + " \n" + " #endif\t/* PAGE_FLAGS_H */\n" + "-- \n" + 2.5.0 + "\01:4\0" + "fn\0mm-sanitize-page-mapping-for-tail-pages.patch\0" + "b\0" + ">From cdb3d7e7f717f3e96ee97c4b0a29a745701bd813 Mon Sep 17 00:00:00 2001\n" + "From: \"Kirill A. Shutemov\" <kirill.shutemov@linux.intel.com>\n" + "Date: Tue, 18 Aug 2015 09:49:51 +1000\n" + "Subject: [PATCH] mm: sanitize page->mapping for tail pages\n" + "\n" + "We don't define meaning of page->mapping for tail pages. Currently it's\n" + "always NULL, which can be inconsistent with head page and potentially lead\n" + "to problems.\n" + "\n" + "Let's poison the pointer to catch all illigal uses.\n" + "\n" + "page_rmapping(), page_mapping() and page_anon_vma() are changed to look on\n" + "head page.\n" + "\n" + "The only illegal use I've caught so far is __GPF_COMP pages from sound\n" + "subsystem, mapped with PTEs. do_shared_fault() is changed to use\n" + "page_rmapping() instead of direct access to fault_page->mapping.\n" + "\n" + "Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>\n" + "Cc: Andrea Arcangeli <aarcange@redhat.com>\n" + "Cc: Hugh Dickins <hughd@google.com>\n" + "Cc: Dave Hansen <dave.hansen@intel.com>\n" + "Cc: Mel Gorman <mgorman@suse.de>\n" + "Cc: Rik van Riel <riel@redhat.com>\n" + "Cc: Vlastimil Babka <vbabka@suse.cz>\n" + "Cc: Christoph Lameter <cl@linux.com>\n" + "Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>\n" + "Cc: Steve Capper <steve.capper@linaro.org>\n" + "Cc: \"Aneesh Kumar K.V\" <aneesh.kumar@linux.vnet.ibm.com>\n" + "Cc: Johannes Weiner <hannes@cmpxchg.org>\n" + "Cc: Michal Hocko <mhocko@suse.cz>\n" + "Cc: Jerome Marchand <jmarchan@redhat.com>\n" + "Signed-off-by: Andrew Morton <akpm@linux-foundation.org>\n" + "---\n" + " include/linux/poison.h | 4 ++++\n" + " mm/huge_memory.c | 2 +-\n" + " mm/memory.c | 2 +-\n" + " mm/page_alloc.c | 6 ++++++\n" + " mm/util.c | 10 ++++++----\n" + " 5 files changed, 18 insertions(+), 6 deletions(-)\n" + "\n" + "diff --git a/include/linux/poison.h b/include/linux/poison.h\n" + "index 2110a81c5e2a..7b2a7fcde6a3 100644\n" + "--- a/include/linux/poison.h\n" + "+++ b/include/linux/poison.h\n" + "@@ -32,6 +32,10 @@\n" + " /********** mm/debug-pagealloc.c **********/\n" + " #define PAGE_POISON 0xaa\n" + " \n" + "+/********** mm/page_alloc.c ************/\n" + "+\n" + "+#define TAIL_MAPPING\t((void *) 0x01014A11 + POISON_POINTER_DELTA)\n" + "+\n" + " /********** mm/slab.c **********/\n" + " /*\n" + " * Magic nums for obj red zoning.\n" + "diff --git a/mm/huge_memory.c b/mm/huge_memory.c\n" + "index 7ef15f8f8bf3..1a3accef0756 100644\n" + "--- a/mm/huge_memory.c\n" + "+++ b/mm/huge_memory.c\n" + "@@ -1772,7 +1772,7 @@ static void __split_huge_page_refcount(struct page *page,\n" + " \t\t*/\n" + " \t\tpage_tail->_mapcount = page->_mapcount;\n" + " \n" + "-\t\tBUG_ON(page_tail->mapping);\n" + "+\t\tBUG_ON(page_tail->mapping != TAIL_MAPPING);\n" + " \t\tpage_tail->mapping = page->mapping;\n" + " \n" + " \t\tpage_tail->index = page->index + i;\n" + "diff --git a/mm/memory.c b/mm/memory.c\n" + "index 6cd0b2160401..558ee16167d9 100644\n" + "--- a/mm/memory.c\n" + "+++ b/mm/memory.c\n" + "@@ -3087,7 +3087,7 @@ static int do_shared_fault(struct mm_struct *mm, struct vm_area_struct *vma,\n" + " \t * pinned by vma->vm_file's reference. We rely on unlock_page()'s\n" + " \t * release semantics to prevent the compiler from undoing this copying.\n" + " \t */\n" + "-\tmapping = fault_page->mapping;\n" + "+\tmapping = page_rmapping(fault_page);\n" + " \tunlock_page(fault_page);\n" + " \tif ((dirtied || vma->vm_ops->page_mkwrite) && mapping) {\n" + " \t\t/*\n" + "diff --git a/mm/page_alloc.c b/mm/page_alloc.c\n" + "index d752298a9e48..adefa3ad8e3e 100644\n" + "--- a/mm/page_alloc.c\n" + "+++ b/mm/page_alloc.c\n" + "@@ -470,6 +470,7 @@ void prep_compound_page(struct page *page, unsigned int order)\n" + " \tfor (i = 1; i < nr_pages; i++) {\n" + " \t\tstruct page *p = page + i;\n" + " \t\tset_page_count(p, 0);\n" + "+\t\tp->mapping = TAIL_MAPPING;\n" + " \t\tset_compound_head(p, page);\n" + " \t}\n" + " }\n" + "@@ -855,6 +856,10 @@ static int free_tail_pages_check(struct page *head_page, struct page *page)\n" + " \t\tret = 0;\n" + " \t\tgoto out;\n" + " \t}\n" + "+\tif (page->mapping != TAIL_MAPPING) {\n" + "+\t\tbad_page(page, \"corrupted mapping in tail page\", 0);\n" + "+\t\tgoto out;\n" + "+\t}\n" + " \tif (unlikely(!PageTail(page))) {\n" + " \t\tbad_page(page, \"PageTail not set\", 0);\n" + " \t\tgoto out;\n" + "@@ -865,6 +870,7 @@ static int free_tail_pages_check(struct page *head_page, struct page *page)\n" + " \t}\n" + " \tret = 0;\n" + " out:\n" + "+\tpage->mapping = NULL;\n" + " \tclear_compound_head(page);\n" + " \treturn ret;\n" + " }\n" + "diff --git a/mm/util.c b/mm/util.c\n" + "index 68ff8a5361e7..0c7f65e7ef5e 100644\n" + "--- a/mm/util.c\n" + "+++ b/mm/util.c\n" + "@@ -355,7 +355,9 @@ struct anon_vma *page_anon_vma(struct page *page)\n" + " \n" + " struct address_space *page_mapping(struct page *page)\n" + " {\n" + "-\tunsigned long mapping;\n" + "+\tstruct address_space *mapping;\n" + "+\n" + "+\tpage = compound_head(page);\n" + " \n" + " \t/* This happens if someone calls flush_dcache_page on slab page */\n" + " \tif (unlikely(PageSlab(page)))\n" + "@@ -368,10 +370,10 @@ struct address_space *page_mapping(struct page *page)\n" + " \t\treturn swap_address_space(entry);\n" + " \t}\n" + " \n" + "-\tmapping = (unsigned long)page->mapping;\n" + "-\tif (mapping & PAGE_MAPPING_FLAGS)\n" + "+\tmapping = page->mapping;\n" + "+\tif ((unsigned long)mapping & PAGE_MAPPING_FLAGS)\n" + " \t\treturn NULL;\n" + "-\treturn page->mapping;\n" + "+\treturn mapping;\n" + " }\n" + " \n" + " int overcommit_ratio_handler(struct ctl_table *table, int write,\n" + "-- \n" + 2.5.0 -cc19ab7e0f5b1882c16a3b7d24321fd8db8324c66a6fe38ce10f7720bafe4cf4 +fe7b87629fafbddd836479ca93e8bf50d41734d96cf4f66ed2d362b3c3a0927c
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.