diff options
Diffstat (limited to 'include/linux/page-flags.h')
| -rw-r--r-- | include/linux/page-flags.h | 173 | 
1 files changed, 143 insertions, 30 deletions
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 5f38c460367..8304959ad33 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -6,6 +6,8 @@  #define PAGE_FLAGS_H  #include <linux/types.h> +#include <linux/bug.h> +#include <linux/mmdebug.h>  #ifndef __GENERATING_BOUNDS_H  #include <linux/mm_types.h>  #include <generated/bounds.h> @@ -48,9 +50,6 @@   * struct page (these bits with information) are always mapped into kernel   * address space...   * - * PG_buddy is set to indicate that the page is free and in the buddy system - * (see mm/page_alloc.c). - *   * PG_hwpoison indicates that a page got corrupted in hardware and contains   * data with incorrect ECC bits that triggered a machine check. Accessing is   * not safe since it may cause another machine check. Don't touch! @@ -96,7 +95,6 @@ enum pageflags {  	PG_swapcache,		/* Swap page: swp_entry_t in private */  	PG_mappedtodisk,	/* Has blocks allocated on-disk */  	PG_reclaim,		/* To be reclaimed asap */ -	PG_buddy,		/* Page is free, on buddy lists */  	PG_swapbacked,		/* Page is backed by RAM/swap */  	PG_unevictable,		/* Page is "unevictable"  */  #ifdef CONFIG_MMU @@ -108,6 +106,9 @@ enum pageflags {  #ifdef CONFIG_MEMORY_FAILURE  	PG_hwpoison,		/* hardware poisoned page. Don't touch */  #endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +	PG_compound_lock, +#endif  	__NR_PAGEFLAGS,  	/* Filesystems */ @@ -125,9 +126,6 @@ enum pageflags {  	/* SLOB */  	PG_slob_free = PG_private, - -	/* SLUB */ -	PG_slub_frozen = PG_active,  };  #ifndef __GENERATING_BOUNDS_H @@ -136,7 +134,7 @@ enum pageflags {   * Macros to create function definitions for page flags   */  #define TESTPAGEFLAG(uname, lname)					\ -static inline int Page##uname(struct page *page) 			\ +static inline int Page##uname(const struct page *page)			\  			{ return test_bit(PG_##lname, &page->flags); }  #define SETPAGEFLAG(uname, lname)					\ @@ -174,7 +172,7 @@ static inline int __TestClearPage##uname(struct page *page)		\  	__SETPAGEFLAG(uname, lname)  __CLEARPAGEFLAG(uname, lname)  #define PAGEFLAG_FALSE(uname) 						\ -static inline int Page##uname(struct page *page) 			\ +static inline int Page##uname(const struct page *page)			\  			{ return 0; }  #define TESTSCFLAG(uname, lname)					\ @@ -197,9 +195,10 @@ static inline int __TestClearPage##uname(struct page *page) { return 0; }  struct page;	/* forward declaration */ -TESTPAGEFLAG(Locked, locked) TESTSETFLAG(Locked, locked) -PAGEFLAG(Error, error) +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) @@ -210,11 +209,10 @@ PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned)	/* Xen */  PAGEFLAG(SavePinned, savepinned);			/* Xen */  PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)  PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked) +	__SETPAGEFLAG(SwapBacked, swapbacked)  __PAGEFLAG(SlobFree, slob_free) -__PAGEFLAG(SlubFrozen, slub_frozen) -  /*   * Private page markings that may be used by the filesystem that owns the page   * for its own purposes. @@ -230,12 +228,11 @@ PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1)   * risky: they bypass page accounting.   */  TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback) -__PAGEFLAG(Buddy, buddy)  PAGEFLAG(MappedToDisk, mappedtodisk) -/* PG_readahead is only used for file reads; PG_reclaim is only for writes */ +/* PG_readahead is only used for reads; PG_reclaim is only for writes */  PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim) -PAGEFLAG(Readahead, reclaim)		/* Reminder to do async read-ahead */ +PAGEFLAG(Readahead, reclaim) TESTCLEARFLAG(Readahead, reclaim)  #ifdef CONFIG_HIGHMEM  /* @@ -308,21 +305,13 @@ static inline void __SetPageUptodate(struct page *page)  static inline void SetPageUptodate(struct page *page)  { -#ifdef CONFIG_S390 -	if (!test_and_set_bit(PG_uptodate, &page->flags)) -		page_clear_dirty(page, 0); -#else  	/*  	 * Memory barrier must be issued before setting the PG_uptodate bit,  	 * so that all previous stores issued in order to bring the page  	 * uptodate are actually visible before PageUptodate becomes true. -	 * -	 * s390 doesn't need an explicit smp_wmb here because the test and -	 * set bit already provides full barriers.  	 */  	smp_wmb();  	set_bit(PG_uptodate, &(page)->flags); -#endif  }  CLEARPAGEFLAG(Uptodate, uptodate) @@ -330,21 +319,33 @@ CLEARPAGEFLAG(Uptodate, uptodate)  extern void cancel_dirty_page(struct page *page, unsigned int account_size);  int test_clear_page_writeback(struct page *page); -int test_set_page_writeback(struct page *page); +int __test_set_page_writeback(struct page *page, bool keep_write); + +#define test_set_page_writeback(page)			\ +	__test_set_page_writeback(page, false) +#define test_set_page_writeback_keepwrite(page)	\ +	__test_set_page_writeback(page, true)  static inline void set_page_writeback(struct page *page)  {  	test_set_page_writeback(page);  } +static inline void set_page_writeback_keepwrite(struct page *page) +{ +	test_set_page_writeback_keepwrite(page); +} +  #ifdef CONFIG_PAGEFLAGS_EXTENDED  /*   * System with lots of page flags available. This allows separate   * flags for PageHead() and PageTail() checks of compound pages so that bit   * tests can be used in performance sensitive paths. PageCompound is - * generally not used in hot code paths. + * generally not used in hot code paths except arch/powerpc/mm/init_64.c + * and arch/powerpc/kvm/book3s_64_vio_hv.c which use it to detect huge pages + * and avoid handling those in real mode.   */ -__PAGEFLAG(Head, head) +__PAGEFLAG(Head, head) CLEARPAGEFLAG(Head, head)  __PAGEFLAG(Tail, tail)  static inline int PageCompound(struct page *page) @@ -352,6 +353,16 @@ static inline int PageCompound(struct page *page)  	return page->flags & ((1L << PG_head) | (1L << PG_tail));  } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline void ClearPageCompound(struct page *page) +{ +	BUG_ON(!PageHead(page)); +	ClearPageHead(page); +} +#endif + +#define PG_head_mask ((1L << PG_head)) +  #else  /*   * Reduce page flag use as much as possible by overlapping @@ -360,7 +371,7 @@ static inline int PageCompound(struct page *page)   * pages on the LRU and/or pagecache.   */  TESTPAGEFLAG(Compound, compound) -__PAGEFLAG(Head, compound) +__SETPAGEFLAG(Head, compound)  __CLEARPAGEFLAG(Head, compound)  /*   * PG_reclaim is used in combination with PG_compound to mark the @@ -372,8 +383,14 @@ __PAGEFLAG(Head, compound)   * PG_compound & PG_reclaim	=> Tail page   * PG_compound & ~PG_reclaim	=> Head page   */ +#define PG_head_mask ((1L << PG_compound))  #define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim)) +static inline int PageHead(struct page *page) +{ +	return ((page->flags & PG_head_tail_mask) == PG_head_mask); +} +  static inline int PageTail(struct page *page)  {  	return ((page->flags & PG_head_tail_mask) == PG_head_tail_mask); @@ -389,14 +406,109 @@ static inline void __ClearPageTail(struct page *page)  	page->flags &= ~PG_head_tail_mask;  } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline void ClearPageCompound(struct page *page) +{ +	BUG_ON((page->flags & PG_head_tail_mask) != (1 << PG_compound)); +	clear_bit(PG_compound, &page->flags); +} +#endif +  #endif /* !PAGEFLAGS_EXTENDED */ +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +/* + * PageHuge() only returns true for hugetlbfs pages, but not for + * normal or transparent huge pages. + * + * PageTransHuge() returns true for both transparent huge and + * hugetlbfs pages, but not normal pages. PageTransHuge() can only be + * called only in the core VM paths where hugetlbfs pages can't exist. + */ +static inline int PageTransHuge(struct page *page) +{ +	VM_BUG_ON_PAGE(PageTail(page), page); +	return PageHead(page); +} + +/* + * PageTransCompound returns true for both transparent huge pages + * and hugetlbfs pages, so it should only be called when it's known + * that hugetlbfs pages aren't involved. + */ +static inline int PageTransCompound(struct page *page) +{ +	return PageCompound(page); +} + +/* + * PageTransTail returns true for both transparent huge pages + * and hugetlbfs pages, so it should only be called when it's known + * that hugetlbfs pages aren't involved. + */ +static inline int PageTransTail(struct page *page) +{ +	return PageTail(page); +} + +#else + +static inline int PageTransHuge(struct page *page) +{ +	return 0; +} + +static inline int PageTransCompound(struct page *page) +{ +	return 0; +} + +static inline int PageTransTail(struct page *page) +{ +	return 0; +} +#endif + +/* + * If network-based swap is enabled, sl*b must keep track of whether pages + * were allocated from pfmemalloc reserves. + */ +static inline int PageSlabPfmemalloc(struct page *page) +{ +	VM_BUG_ON_PAGE(!PageSlab(page), page); +	return PageActive(page); +} + +static inline void SetPageSlabPfmemalloc(struct page *page) +{ +	VM_BUG_ON_PAGE(!PageSlab(page), page); +	SetPageActive(page); +} + +static inline void __ClearPageSlabPfmemalloc(struct page *page) +{ +	VM_BUG_ON_PAGE(!PageSlab(page), page); +	__ClearPageActive(page); +} + +static inline void ClearPageSlabPfmemalloc(struct page *page) +{ +	VM_BUG_ON_PAGE(!PageSlab(page), page); +	ClearPageActive(page); +} +  #ifdef CONFIG_MMU  #define __PG_MLOCKED		(1 << PG_mlocked)  #else  #define __PG_MLOCKED		0  #endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +#define __PG_COMPOUND_LOCK		(1 << PG_compound_lock) +#else +#define __PG_COMPOUND_LOCK		0 +#endif +  /*   * Flags checked when a page is freed.  Pages being freed should not have   * these flags set.  It they are, there is a problem. @@ -404,9 +516,10 @@ static inline void __ClearPageTail(struct page *page)  #define PAGE_FLAGS_CHECK_AT_FREE \  	(1 << PG_lru	 | 1 << PG_locked    | \  	 1 << PG_private | 1 << PG_private_2 | \ -	 1 << PG_buddy	 | 1 << PG_writeback | 1 << PG_reserved | \ +	 1 << PG_writeback | 1 << PG_reserved | \  	 1 << PG_slab	 | 1 << PG_swapcache | 1 << PG_active | \ -	 1 << PG_unevictable | __PG_MLOCKED | __PG_HWPOISON) +	 1 << PG_unevictable | __PG_MLOCKED | __PG_HWPOISON | \ +	 __PG_COMPOUND_LOCK)  /*   * Flags checked when a page is prepped for return by the page allocator.  | 
