mm: optimize compound_head() by avoiding a shared page flag
[sfrench/cifs-2.6.git] / include / linux / page-flags.h
index 9d7921dd50f0c19a3d500d4aeb8bc64a7d8242b9..a3c8b60a9c3a72519ef2356a5bf4b2ecb9000c35 100644 (file)
@@ -6,6 +6,7 @@
 #define PAGE_FLAGS_H
 
 #include <linux/types.h>
+#include <linux/mm_types.h>
 
 /*
  * Various page->flags bits:
@@ -76,7 +77,7 @@
 #define PG_active               6
 #define PG_slab                         7      /* slab debug (Suparna wants this) */
 
-#define PG_checked              8      /* kill me in 2.5.<early>. */
+#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 */
@@ -91,6 +92,8 @@
 #define PG_nosave_free         18      /* Used for system suspend/resume */
 #define PG_buddy               19      /* Page is free, on buddy lists */
 
+/* PG_owner_priv_1 users should have descriptive aliases */
+#define PG_checked             PG_owner_priv_1 /* Used by some filesystems */
 
 #if (BITS_PER_LONG > 32)
 /*
 
 #define PageUptodate(page)     test_bit(PG_uptodate, &(page)->flags)
 #ifdef CONFIG_S390
-#define SetPageUptodate(_page) \
-       do {                                                                  \
-               struct page *__page = (_page);                                \
-               if (!test_and_set_bit(PG_uptodate, &__page->flags))           \
-                       page_test_and_clear_dirty(_page);                     \
-       } while (0)
+static inline void SetPageUptodate(struct page *page)
+{
+       if (!test_and_set_bit(PG_uptodate, &page->flags))
+               page_clear_dirty(page);
+}
 #else
 #define SetPageUptodate(page)  set_bit(PG_uptodate, &(page)->flags)
 #endif
 #define __SetPageCompound(page)        __set_bit(PG_compound, &(page)->flags)
 #define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags)
 
+/*
+ * PG_reclaim is used in combination with PG_compound to mark the
+ * head and tail of a compound page
+ *
+ * PG_compound & PG_reclaim    => Tail page
+ * PG_compound & ~PG_reclaim   => Head page
+ */
+
+#define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim))
+
+#define PageTail(page) ((page->flags & PG_head_tail_mask) \
+                               == PG_head_tail_mask)
+
+static inline void __SetPageTail(struct page *page)
+{
+       page->flags |= PG_head_tail_mask;
+}
+
+static inline void __ClearPageTail(struct page *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)
+
 #ifdef CONFIG_SWAP
 #define PageSwapCache(page)    test_bit(PG_swapcache, &(page)->flags)
 #define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags)
 
 struct page;   /* forward declaration */
 
-int test_clear_page_dirty(struct page *page);
+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);
 
-static inline void clear_page_dirty(struct page *page)
-{
-       test_clear_page_dirty(page);
-}
-
 static inline void set_page_writeback(struct page *page)
 {
        test_set_page_writeback(page);