mm: clean up non-standard page->_mapcount users
authorVladimir Davydov <vdavydov@virtuozzo.com>
Tue, 26 Jul 2016 22:24:18 +0000 (15:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 Jul 2016 23:19:19 +0000 (16:19 -0700)
 - Add a proper comment to page->_mapcount.

 - Introduce a macro for generating helper functions.

 - Place all special page->_mapcount values next to each other so that
   readers can see all possible values and so we don't get duplicates.

Link: http://lkml.kernel.org/r/502f49000e0b63e6c62e338fac6b420bf34fb526.1464079537.git.vdavydov@virtuozzo.com
Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/mm_types.h
include/linux/page-flags.h
scripts/tags.sh

index a50ad735d518c150fd49b4c35c9ba55d22c70e7c..79472b22d23f0866cd251e3e5e47c902522994e0 100644 (file)
@@ -85,6 +85,11 @@ struct page {
                                /*
                                 * Count of ptes mapped in mms, to show when
                                 * page is mapped & limit reverse map searches.
+                                *
+                                * Extra information about page type may be
+                                * stored here for pages that are never mapped,
+                                * in which case the value MUST BE <= -2.
+                                * See page-flags.h for more details.
                                 */
                                atomic_t _mapcount;
 
index f36dbb3a3060c37d9618041e3bc93da981581e5e..96084ee74ee8fc11b6a325f66dfeb5bd5dcac2b4 100644 (file)
@@ -604,54 +604,45 @@ 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);
 
 /*
index f72f48f638ae00fec7e2c2e1703c0678098af075..ed7eef24ef89946b9fc4ffb2098ff769d0531f93 100755 (executable)
@@ -185,6 +185,9 @@ regex_c=(
        '/\<CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/ClearPage\1/'
        '/\<__CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/__ClearPage\1/'
        '/\<TESTCLEARFLAG_FALSE(\([[:alnum:]_]*\).*/TestClearPage\1/'
+       '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/Page\1/'
+       '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__SetPage\1/'
+       '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__ClearPage\1/'
        '/^TASK_PFA_TEST([^,]*, *\([[:alnum:]_]*\))/task_\1/'
        '/^TASK_PFA_SET([^,]*, *\([[:alnum:]_]*\))/task_set_\1/'
        '/^TASK_PFA_CLEAR([^,]*, *\([[:alnum:]_]*\))/task_clear_\1/'