Merge branch 'linus' into cont_syslog
[safe/jmp/linux-2.6] / include / linux / page-flags.h
index ed7659a..5b59f35 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/types.h>
 #ifndef __GENERATING_BOUNDS_H
 #include <linux/mm_types.h>
-#include <linux/bounds.h>
+#include <generated/bounds.h>
 #endif /* !__GENERATING_BOUNDS_H */
 
 /*
@@ -51,6 +51,9 @@
  * 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!
  */
 
 /*
@@ -79,31 +82,53 @@ enum pageflags {
        PG_active,
        PG_slab,
        PG_owner_priv_1,        /* Owner use. If pagecache, fs may use*/
-       PG_checked = PG_owner_priv_1, /* Used by some filesystems */
-       PG_pinned = PG_owner_priv_1, /* Xen pinned pagetable */
        PG_arch_1,
        PG_reserved,
        PG_private,             /* If pagecache, has fs-private data */
+       PG_private_2,           /* If pagecache, has fs aux data */
        PG_writeback,           /* Page is under writeback */
+#ifdef CONFIG_PAGEFLAGS_EXTENDED
+       PG_head,                /* A head page */
+       PG_tail,                /* A tail page */
+#else
        PG_compound,            /* A compound page */
+#endif
        PG_swapcache,           /* Swap page: swp_entry_t in private */
        PG_mappedtodisk,        /* Has blocks allocated on-disk */
        PG_reclaim,             /* To be reclaimed asap */
-       /* PG_readahead is only used for file reads; PG_reclaim is only for writes */
-       PG_readahead = PG_reclaim, /* Reminder to do async read-ahead */
        PG_buddy,               /* Page is free, on buddy lists */
-
-#if (BITS_PER_LONG > 32)
-/*
- * 64-bit-only flags build down from bit 31
- *
- * 32 bit  -------------------------------| FIELDS |       FLAGS         |
- * 64 bit  |           FIELDS             | ??????         FLAGS         |
- *         63                            32                              0
- */
-       PG_uncached = 31,               /* Page has been mapped as uncached */
+       PG_swapbacked,          /* Page is backed by RAM/swap */
+       PG_unevictable,         /* Page is "unevictable"  */
+#ifdef CONFIG_MMU
+       PG_mlocked,             /* Page is vma mlocked */
+#endif
+#ifdef CONFIG_ARCH_USES_PG_UNCACHED
+       PG_uncached,            /* Page has been mapped as uncached */
 #endif
-       __NR_PAGEFLAGS
+#ifdef CONFIG_MEMORY_FAILURE
+       PG_hwpoison,            /* hardware poisoned page. Don't touch */
+#endif
+       __NR_PAGEFLAGS,
+
+       /* Filesystems */
+       PG_checked = PG_owner_priv_1,
+
+       /* Two page bits are conscripted by FS-Cache to maintain local caching
+        * state.  These bits are set on pages belonging to the netfs's inodes
+        * when those inodes are being locally cached.
+        */
+       PG_fscache = PG_private_2,      /* page backed by cache */
+
+       /* XEN */
+       PG_pinned = PG_owner_priv_1,
+       PG_savepinned = PG_dirty,
+
+       /* SLOB */
+       PG_slob_free = PG_private,
+
+       /* SLUB */
+       PG_slub_frozen = PG_active,
+       PG_slub_debug = PG_error,
 };
 
 #ifndef __GENERATING_BOUNDS_H
@@ -139,6 +164,9 @@ static inline int TestSetPage##uname(struct page *page)                     \
 static inline int TestClearPage##uname(struct page *page)              \
                { return test_and_clear_bit(PG_##lname, &page->flags); }
 
+#define __TESTCLEARFLAG(uname, lname)                                  \
+static inline int __TestClearPage##uname(struct page *page)            \
+               { return __test_and_clear_bit(PG_##lname, &page->flags); }
 
 #define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname)              \
        SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)
@@ -146,23 +174,58 @@ static inline int TestClearPage##uname(struct page *page)         \
 #define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname)            \
        __SETPAGEFLAG(uname, lname)  __CLEARPAGEFLAG(uname, lname)
 
+#define PAGEFLAG_FALSE(uname)                                          \
+static inline int Page##uname(struct page *page)                       \
+                       { return 0; }
+
 #define TESTSCFLAG(uname, lname)                                       \
        TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname)
 
+#define SETPAGEFLAG_NOOP(uname)                                                \
+static inline void SetPage##uname(struct page *page) {  }
+
+#define CLEARPAGEFLAG_NOOP(uname)                                      \
+static inline void ClearPage##uname(struct page *page) {  }
+
+#define __CLEARPAGEFLAG_NOOP(uname)                                    \
+static inline void __ClearPage##uname(struct page *page) {  }
+
+#define TESTCLEARFLAG_FALSE(uname)                                     \
+static inline int TestClearPage##uname(struct page *page) { return 0; }
+
+#define __TESTCLEARFLAG_FALSE(uname)                                   \
+static inline int __TestClearPage##uname(struct page *page) { return 0; }
+
 struct page;   /* forward declaration */
 
-PAGEFLAG(Locked, locked) TESTSCFLAG(Locked, locked)
+TESTPAGEFLAG(Locked, locked) TESTSETFLAG(Locked, locked)
 PAGEFLAG(Error, error)
 PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(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)               /* Xen pinned pagetable */
+PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned)    /* Xen */
+PAGEFLAG(SavePinned, savepinned);                      /* Xen */
 PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
-PAGEFLAG(Private, private) __CLEARPAGEFLAG(Private, private)
-       __SETPAGEFLAG(Private, private)
+PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
+
+__PAGEFLAG(SlobFree, slob_free)
+
+__PAGEFLAG(SlubFrozen, slub_frozen)
+__PAGEFLAG(SlubDebug, slub_debug)
+
+/*
+ * 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)
 
 /*
  * Only test-and-set exist for PG_writeback.  The unconditional operators are
@@ -174,34 +237,53 @@ PAGEFLAG(MappedToDisk, mappedtodisk)
 
 /* PG_readahead is only used for file reads; PG_reclaim is only for writes */
 PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim)
-PAGEFLAG(Readahead, readahead)         /* Reminder to do async read-ahead */
+PAGEFLAG(Readahead, reclaim)           /* Reminder to do async read-ahead */
 
 #ifdef CONFIG_HIGHMEM
 /*
  * Must use a macro here due to header dependency issues. page_zone() is not
  * available at this point.
  */
-#define PageHighMem(__p) is_highmem(page_zone(page))
+#define PageHighMem(__p) is_highmem(page_zone(__p))
 #else
-static inline int PageHighMem(struct page *page)
-{
-       return 0;
-}
+PAGEFLAG_FALSE(HighMem)
 #endif
 
 #ifdef CONFIG_SWAP
 PAGEFLAG(SwapCache, swapcache)
 #else
-static inline int PageSwapCache(struct page *page)
-{
-       return 0;
-}
+PAGEFLAG_FALSE(SwapCache)
+       SETPAGEFLAG_NOOP(SwapCache) CLEARPAGEFLAG_NOOP(SwapCache)
+#endif
+
+PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable)
+       TESTCLEARFLAG(Unevictable, unevictable)
+
+#ifdef CONFIG_MMU
+PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked)
+       TESTSCFLAG(Mlocked, mlocked) __TESTCLEARFLAG(Mlocked, mlocked)
+#else
+PAGEFLAG_FALSE(Mlocked) SETPAGEFLAG_NOOP(Mlocked)
+       TESTCLEARFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked)
 #endif
 
-#if (BITS_PER_LONG > 32)
+#ifdef CONFIG_ARCH_USES_PG_UNCACHED
 PAGEFLAG(Uncached, uncached)
+#else
+PAGEFLAG_FALSE(Uncached)
+#endif
+
+#ifdef CONFIG_MEMORY_FAILURE
+PAGEFLAG(HWPoison, hwpoison)
+TESTSCFLAG(HWPoison, hwpoison)
+#define __PG_HWPOISON (1UL << PG_hwpoison)
+#else
+PAGEFLAG_FALSE(HWPoison)
+#define __PG_HWPOISON 0
 #endif
 
+u64 stable_page_flags(struct page *page);
+
 static inline int PageUptodate(struct page *page)
 {
        int ret = test_bit(PG_uptodate, &(page)->flags);
@@ -224,9 +306,6 @@ static inline void __SetPageUptodate(struct page *page)
 {
        smp_wmb();
        __set_bit(PG_uptodate, &(page)->flags);
-#ifdef CONFIG_S390
-       page_clear_dirty(page);
-#endif
 }
 
 static inline void SetPageUptodate(struct page *page)
@@ -260,6 +339,28 @@ static inline void set_page_writeback(struct page *page)
        test_set_page_writeback(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.
+ */
+__PAGEFLAG(Head, head)
+__PAGEFLAG(Tail, tail)
+
+static inline int PageCompound(struct page *page)
+{
+       return page->flags & ((1L << PG_head) | (1L << PG_tail));
+
+}
+#else
+/*
+ * Reduce page flag use as much as possible by overlapping
+ * compound page flags with the flags used for page cache pages. Possible
+ * because PageCompound is always set for compound pages and not for
+ * pages on the LRU and/or pagecache.
+ */
 TESTPAGEFLAG(Compound, compound)
 __PAGEFLAG(Head, compound)
 
@@ -290,5 +391,46 @@ static inline void __ClearPageTail(struct page *page)
        page->flags &= ~PG_head_tail_mask;
 }
 
+#endif /* !PAGEFLAGS_EXTENDED */
+
+#ifdef CONFIG_MMU
+#define __PG_MLOCKED           (1 << PG_mlocked)
+#else
+#define __PG_MLOCKED           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.
+ */
+#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_slab    | 1 << PG_swapcache | 1 << PG_active | \
+        1 << PG_unevictable | __PG_MLOCKED | __PG_HWPOISON)
+
+/*
+ * Flags checked when a page is prepped for return by the page allocator.
+ * Pages being prepped should not have any flags set.  It they are set,
+ * there has been a kernel bug or struct page corruption.
+ */
+#define PAGE_FLAGS_CHECK_AT_PREP       ((1 << NR_PAGEFLAGS) - 1)
+
+#define PAGE_FLAGS_PRIVATE                             \
+       (1 << PG_private | 1 << PG_private_2)
+/**
+ * page_has_private - Determine if page has private stuff
+ * @page: The page to be checked
+ *
+ * Determine if a page has private stuff, indicating that release routines
+ * should be invoked upon it.
+ */
+static inline int page_has_private(struct page *page)
+{
+       return !!(page->flags & PAGE_FLAGS_PRIVATE);
+}
+
 #endif /* !__GENERATING_BOUNDS_H */
+
 #endif /* PAGE_FLAGS_H */