All of lore.kernel.org
 help / color / mirror / Atom feed
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.