]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - include/linux/page-flags.h
mm: clean up non-standard page->_mapcount users
[karo-tx-linux.git] / include / linux / page-flags.h
index 6b052aa7b5b79de6712ee36fe3a424f6f93bd548..96084ee74ee8fc11b6a325f66dfeb5bd5dcac2b4 100644 (file)
@@ -129,6 +129,9 @@ enum pageflags {
 
        /* Compound pages. Stored in first tail page's flags */
        PG_double_map = PG_private_2,
+
+       /* non-lru isolated movable page */
+       PG_isolated = PG_reclaim,
 };
 
 #ifndef __GENERATING_BOUNDS_H
@@ -357,19 +360,26 @@ PAGEFLAG(Idle, idle, PF_ANY)
  * with the PAGE_MAPPING_ANON bit set to distinguish it.  See rmap.h.
  *
  * On an anonymous page in a VM_MERGEABLE area, if CONFIG_KSM is enabled,
- * the PAGE_MAPPING_KSM bit may be set along with the PAGE_MAPPING_ANON bit;
- * and then page->mapping points, not to an anon_vma, but to a private
+ * the PAGE_MAPPING_MOVABLE bit may be set along with the PAGE_MAPPING_ANON
+ * bit; and then page->mapping points, not to an anon_vma, but to a private
  * structure which KSM associates with that merged page.  See ksm.h.
  *
- * PAGE_MAPPING_KSM without PAGE_MAPPING_ANON is currently never used.
+ * PAGE_MAPPING_KSM without PAGE_MAPPING_ANON is used for non-lru movable
+ * page and then page->mapping points a struct address_space.
  *
  * Please note that, confusingly, "page_mapping" refers to the inode
  * address_space which maps the page from disk; whereas "page_mapped"
  * refers to user virtual address space into which the page is mapped.
  */
-#define PAGE_MAPPING_ANON      1
-#define PAGE_MAPPING_KSM       2
-#define PAGE_MAPPING_FLAGS     (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM)
+#define PAGE_MAPPING_ANON      0x1
+#define PAGE_MAPPING_MOVABLE   0x2
+#define PAGE_MAPPING_KSM       (PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
+#define PAGE_MAPPING_FLAGS     (PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
+
+static __always_inline int PageMappingFlags(struct page *page)
+{
+       return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) != 0;
+}
 
 static __always_inline int PageAnon(struct page *page)
 {
@@ -377,6 +387,12 @@ static __always_inline int PageAnon(struct page *page)
        return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0;
 }
 
+static __always_inline int __PageMovable(struct page *page)
+{
+       return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==
+                               PAGE_MAPPING_MOVABLE;
+}
+
 #ifdef CONFIG_KSM
 /*
  * A KSM page is one of those write-protected "shared pages" or "merged pages"
@@ -388,7 +404,7 @@ static __always_inline int PageKsm(struct page *page)
 {
        page = compound_head(page);
        return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==
-                               (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM);
+                               PAGE_MAPPING_KSM;
 }
 #else
 TESTPAGEFLAG_FALSE(Ksm)
@@ -474,7 +490,7 @@ static inline void ClearPageCompound(struct page *page)
 }
 #endif
 
-#define PG_head_mask ((1L << PG_head))
+#define PG_head_mask ((1UL << PG_head))
 
 #ifdef CONFIG_HUGETLB_PAGE
 int PageHuge(struct page *page);
@@ -588,53 +604,46 @@ TESTPAGEFLAG_FALSE(DoubleMap)
 #endif
 
 /*
- * PageBuddy() indicate that the page is free and in the buddy system
- * (see mm/page_alloc.c).
- *
- * PAGE_BUDDY_MAPCOUNT_VALUE must be <= -2 but better not too close to
- * -2 so that an underflow of the page_mapcount() won't be mistaken
- * for a genuine PAGE_BUDDY_MAPCOUNT_VALUE. -128 can be created very
- * efficiently by most CPU architectures.
+ * For pages that are never mapped to userspace, page->mapcount may be
+ * used for storing extra information about page type. Any value used
+ * for this purpose must be <= -2, but it's better start not too close
+ * to -2 so that an underflow of the page_mapcount() won't be mistaken
+ * for a special page.
  */
-#define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
-
-static inline int PageBuddy(struct page *page)
-{
-       return atomic_read(&page->_mapcount) == PAGE_BUDDY_MAPCOUNT_VALUE;
+#define PAGE_MAPCOUNT_OPS(uname, lname)                                        \
+static __always_inline int Page##uname(struct page *page)              \
+{                                                                      \
+       return atomic_read(&page->_mapcount) ==                         \
+                               PAGE_##lname##_MAPCOUNT_VALUE;          \
+}                                                                      \
+static __always_inline void __SetPage##uname(struct page *page)                \
+{                                                                      \
+       VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page);      \
+       atomic_set(&page->_mapcount, PAGE_##lname##_MAPCOUNT_VALUE);    \
+}                                                                      \
+static __always_inline void __ClearPage##uname(struct page *page)      \
+{                                                                      \
+       VM_BUG_ON_PAGE(!Page##uname(page), page);                       \
+       atomic_set(&page->_mapcount, -1);                               \
 }
 
-static inline void __SetPageBuddy(struct page *page)
-{
-       VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page);
-       atomic_set(&page->_mapcount, PAGE_BUDDY_MAPCOUNT_VALUE);
-}
+/*
+ * PageBuddy() indicate that the page is free and in the buddy system
+ * (see mm/page_alloc.c).
+ */
+#define PAGE_BUDDY_MAPCOUNT_VALUE              (-128)
+PAGE_MAPCOUNT_OPS(Buddy, BUDDY)
 
-static inline void __ClearPageBuddy(struct page *page)
-{
-       VM_BUG_ON_PAGE(!PageBuddy(page), page);
-       atomic_set(&page->_mapcount, -1);
-}
+/*
+ * PageBalloon() is set on pages that are on the balloon page list
+ * (see mm/balloon_compaction.c).
+ */
+#define PAGE_BALLOON_MAPCOUNT_VALUE            (-256)
+PAGE_MAPCOUNT_OPS(Balloon, BALLOON)
 
 extern bool is_free_buddy_page(struct page *page);
 
-#define PAGE_BALLOON_MAPCOUNT_VALUE (-256)
-
-static inline int PageBalloon(struct page *page)
-{
-       return atomic_read(&page->_mapcount) == PAGE_BALLOON_MAPCOUNT_VALUE;
-}
-
-static inline void __SetPageBalloon(struct page *page)
-{
-       VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page);
-       atomic_set(&page->_mapcount, PAGE_BALLOON_MAPCOUNT_VALUE);
-}
-
-static inline void __ClearPageBalloon(struct page *page)
-{
-       VM_BUG_ON_PAGE(!PageBalloon(page), page);
-       atomic_set(&page->_mapcount, -1);
-}
+__PAGEFLAG(Isolated, isolated, PF_ANY);
 
 /*
  * If network-based swap is enabled, sl*b must keep track of whether pages
@@ -665,7 +674,7 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)
 }
 
 #ifdef CONFIG_MMU
-#define __PG_MLOCKED           (1 << PG_mlocked)
+#define __PG_MLOCKED           (1UL << PG_mlocked)
 #else
 #define __PG_MLOCKED           0
 #endif
@@ -675,11 +684,11 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)
  * 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_writeback | 1 << PG_reserved | \
-        1 << PG_slab    | 1 << PG_swapcache | 1 << PG_active | \
-        1 << PG_unevictable | __PG_MLOCKED)
+       (1UL << PG_lru   | 1UL << PG_locked    | \
+        1UL << PG_private | 1UL << PG_private_2 | \
+        1UL << PG_writeback | 1UL << PG_reserved | \
+        1UL << PG_slab  | 1UL << PG_swapcache | 1UL << PG_active | \
+        1UL << PG_unevictable | __PG_MLOCKED)
 
 /*
  * Flags checked when a page is prepped for return by the page allocator.
@@ -690,10 +699,10 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)
  * alloc-free cycle to prevent from reusing the page.
  */
 #define PAGE_FLAGS_CHECK_AT_PREP       \
-       (((1 << NR_PAGEFLAGS) - 1) & ~__PG_HWPOISON)
+       (((1UL << NR_PAGEFLAGS) - 1) & ~__PG_HWPOISON)
 
 #define PAGE_FLAGS_PRIVATE                             \
-       (1 << PG_private | 1 << PG_private_2)
+       (1UL << PG_private | 1UL << PG_private_2)
 /**
  * page_has_private - Determine if page has private stuff
  * @page: The page to be checked