]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/page-flags.h
pageflags: get rid of FLAGS_RESERVED
[linux-2.6-omap-h63xx.git] / include / linux / page-flags.h
index 209d3a47f50f24b5ccbf29c6b3dd965ebb79d2d8..00e55e23b7775bd1221e031a1338212a4ebfb176 100644 (file)
@@ -6,7 +6,10 @@
 #define PAGE_FLAGS_H
 
 #include <linux/types.h>
+#ifndef __GENERATING_BOUNDS_H
 #include <linux/mm_types.h>
+#include <linux/bounds.h>
+#endif /* !__GENERATING_BOUNDS_H */
 
 /*
  * Various page->flags bits:
  * extends from the high bits downwards.
  *
  *  | FIELD | ... | FLAGS |
- *  N-1     ^             0
- *          (N-FLAGS_RESERVED)
+ *  N-1           ^       0
+ *               (NR_PAGEFLAGS)
  *
- * The fields area is reserved for fields mapping zone, node and SPARSEMEM
- * section.  The boundry between these two areas is defined by
- * FLAGS_RESERVED which defines the width of the fields section
- * (see linux/mmzone.h).  New flags must _not_ overlap with this area.
+ * The fields area is reserved for fields mapping zone, node (for NUMA) and
+ * SPARSEMEM section (for variants of SPARSEMEM that require section ids like
+ * SPARSEMEM_EXTREME with !SPARSEMEM_VMEMMAP).
  */
-#define PG_locked               0      /* Page is locked. Don't touch. */
-#define PG_error                1
-#define PG_referenced           2
-#define PG_uptodate             3
-
-#define PG_dirty                4
-#define PG_lru                  5
-#define PG_active               6
-#define PG_slab                         7      /* slab debug (Suparna wants this) */
-
-#define PG_owner_priv_1                 8      /* Owner use. If pagecache, fs may use*/
-#define PG_arch_1               9
-#define PG_reserved            10
-#define PG_private             11      /* If pagecache, has fs-private data */
-
-#define PG_writeback           12      /* Page is under writeback */
-#define PG_compound            14      /* Part of a compound page */
-#define PG_swapcache           15      /* Swap page: swp_entry_t in private */
-
-#define PG_mappedtodisk                16      /* Has blocks allocated on-disk */
-#define PG_reclaim             17      /* To be reclaimed asap */
-#define PG_buddy               19      /* Page is free, on buddy lists */
-
-/* PG_readahead is only used for file reads; PG_reclaim is only for writes */
-#define PG_readahead           PG_reclaim /* Reminder to do async read-ahead */
-
-/* PG_owner_priv_1 users should have descriptive aliases */
-#define PG_checked             PG_owner_priv_1 /* Used by some filesystems */
-#define PG_pinned              PG_owner_priv_1 /* Xen pinned pagetable */
+enum pageflags {
+       PG_locked,              /* Page is locked. Don't touch. */
+       PG_error,
+       PG_referenced,
+       PG_uptodate,
+       PG_dirty,
+       PG_lru,
+       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_writeback,           /* Page is under writeback */
+       PG_compound,            /* A compound page */
+       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  |           FIELDS             | ??????         FLAGS         |
  *         63                            32                              0
  */
-#define PG_uncached            31      /* Page has been mapped as uncached */
+       PG_uncached = 31,               /* Page has been mapped as uncached */
 #endif
+       __NR_PAGEFLAGS
+};
+
+#ifndef __GENERATING_BOUNDS_H
 
 /*
  * Manipulation of page state flags
 #define ClearPageReferenced(page)      clear_bit(PG_referenced, &(page)->flags)
 #define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
 
-#define PageUptodate(page)     test_bit(PG_uptodate, &(page)->flags)
+static inline int PageUptodate(struct page *page)
+{
+       int ret = test_bit(PG_uptodate, &(page)->flags);
+
+       /*
+        * Must ensure that the data we read out of the page is loaded
+        * _after_ we've loaded page->flags to check for PageUptodate.
+        * We can skip the barrier if the page is not uptodate, because
+        * we wouldn't be reading anything from it.
+        *
+        * See SetPageUptodate() for the other side of the story.
+        */
+       if (ret)
+               smp_rmb();
+
+       return ret;
+}
+
+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)
 {
+#ifdef CONFIG_S390
        if (!test_and_set_bit(PG_uptodate, &page->flags))
                page_clear_dirty(page);
-}
 #else
-#define SetPageUptodate(page)  set_bit(PG_uptodate, &(page)->flags)
+       /*
+        * 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
+}
+
 #define ClearPageUptodate(page)        clear_bit(PG_uptodate, &(page)->flags)
 
 #define PageDirty(page)                test_bit(PG_dirty, &(page)->flags)
@@ -230,7 +266,7 @@ static inline void SetPageUptodate(struct page *page)
 
 #define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim))
 
-#define PageTail(page) ((page->flags & PG_head_tail_mask) \
+#define PageTail(page) (((page)->flags & PG_head_tail_mask)    \
                                == PG_head_tail_mask)
 
 static inline void __SetPageTail(struct page *page)
@@ -243,7 +279,7 @@ static inline void __ClearPageTail(struct page *page)
        page->flags &= ~PG_head_tail_mask;
 }
 
-#define PageHead(page) ((page->flags & PG_head_tail_mask) \
+#define PageHead(page) (((page)->flags & PG_head_tail_mask)    \
                                == (1L << PG_compound))
 #define __SetPageHead(page)    __SetPageCompound(page)
 #define __ClearPageHead(page)  __ClearPageCompound(page)
@@ -272,4 +308,5 @@ static inline void set_page_writeback(struct page *page)
        test_set_page_writeback(page);
 }
 
+#endif /* !__GENERATING_BOUNDS_H */
 #endif /* PAGE_FLAGS_H */