MM: Fix macro argument substitution in PageHead() and PageTail()
[sfrench/cifs-2.6.git] / include / linux / page-flags.h
index ae2d79f2107e35fc81c72bf435f223787f4e304f..b5b30f1c1e59e84c2d9877dbe6c03e6b7e01f94c 100644 (file)
 #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 */
 
 #if (BITS_PER_LONG > 32)
 /*
 #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)
@@ -170,6 +210,10 @@ static inline void SetPageUptodate(struct page *page)
 #define SetPageChecked(page)   set_bit(PG_checked, &(page)->flags)
 #define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags)
 
+#define PagePinned(page)       test_bit(PG_pinned, &(page)->flags)
+#define SetPagePinned(page)    set_bit(PG_pinned, &(page)->flags)
+#define ClearPagePinned(page)  clear_bit(PG_pinned, &(page)->flags)
+
 #define PageReserved(page)     test_bit(PG_reserved, &(page)->flags)
 #define SetPageReserved(page)  set_bit(PG_reserved, &(page)->flags)
 #define ClearPageReserved(page)        clear_bit(PG_reserved, &(page)->flags)
@@ -181,37 +225,15 @@ static inline void SetPageUptodate(struct page *page)
 #define __SetPagePrivate(page)  __set_bit(PG_private, &(page)->flags)
 #define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags)
 
+/*
+ * Only test-and-set exist for PG_writeback.  The unconditional operators are
+ * risky: they bypass page accounting.
+ */
 #define PageWriteback(page)    test_bit(PG_writeback, &(page)->flags)
-#define SetPageWriteback(page)                                         \
-       do {                                                            \
-               if (!test_and_set_bit(PG_writeback,                     \
-                               &(page)->flags))                        \
-                       inc_zone_page_state(page, NR_WRITEBACK);        \
-       } while (0)
-#define TestSetPageWriteback(page)                                     \
-       ({                                                              \
-               int ret;                                                \
-               ret = test_and_set_bit(PG_writeback,                    \
-                                       &(page)->flags);                \
-               if (!ret)                                               \
-                       inc_zone_page_state(page, NR_WRITEBACK);        \
-               ret;                                                    \
-       })
-#define ClearPageWriteback(page)                                       \
-       do {                                                            \
-               if (test_and_clear_bit(PG_writeback,                    \
-                               &(page)->flags))                        \
-                       dec_zone_page_state(page, NR_WRITEBACK);        \
-       } while (0)
-#define TestClearPageWriteback(page)                                   \
-       ({                                                              \
-               int ret;                                                \
-               ret = test_and_clear_bit(PG_writeback,                  \
-                               &(page)->flags);                        \
-               if (ret)                                                \
-                       dec_zone_page_state(page, NR_WRITEBACK);        \
-               ret;                                                    \
-       })
+#define TestSetPageWriteback(page) test_and_set_bit(PG_writeback,      \
+                                                       &(page)->flags)
+#define TestClearPageWriteback(page) test_and_clear_bit(PG_writeback,  \
+                                                       &(page)->flags)
 
 #define PageBuddy(page)                test_bit(PG_buddy, &(page)->flags)
 #define __SetPageBuddy(page)   __set_bit(PG_buddy, &(page)->flags)
@@ -221,6 +243,10 @@ static inline void SetPageUptodate(struct page *page)
 #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags)
 #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags)
 
+#define PageReadahead(page)    test_bit(PG_readahead, &(page)->flags)
+#define SetPageReadahead(page) set_bit(PG_readahead, &(page)->flags)
+#define ClearPageReadahead(page) clear_bit(PG_readahead, &(page)->flags)
+
 #define PageReclaim(page)      test_bit(PG_reclaim, &(page)->flags)
 #define SetPageReclaim(page)   set_bit(PG_reclaim, &(page)->flags)
 #define ClearPageReclaim(page) clear_bit(PG_reclaim, &(page)->flags)
@@ -240,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)
@@ -253,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)