/proc/kpagecount: return 0 for special pages that are never mapped
authorAnthony Yznaga <anthony.yznaga@oracle.com>
Fri, 28 Dec 2018 08:37:31 +0000 (00:37 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Dec 2018 20:11:50 +0000 (12:11 -0800)
Certain pages that are never mapped to userspace have a type indicated in
the page_type field of their struct pages (e.g.  PG_buddy).  page_type
overlaps with _mapcount so set the count to 0 and avoid calling
page_mapcount() for these pages.

[anthony.yznaga@oracle.com: incorporate feedback from Matthew Wilcox]
Link: http://lkml.kernel.org/r/1544481313-27318-1-git-send-email-anthony.yznaga@oracle.com
Link: http://lkml.kernel.org/r/1543963526-27917-1-git-send-email-anthony.yznaga@oracle.com
Signed-off-by: Anthony Yznaga <anthony.yznaga@oracle.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Matthew Wilcox <willy@infradead.org>
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: David Rientjes <rientjes@google.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Alexander Duyck <alexander.h.duyck@linux.intel.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Miles Chen <miles.chen@mediatek.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/proc/page.c
include/linux/page-flags.h

index 6c517b11acf829b5a1e2729f9d4748cb9cd56025..40b05e0d427464aef7670d299b059aa50b322e94 100644 (file)
@@ -46,7 +46,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
                        ppage = pfn_to_page(pfn);
                else
                        ppage = NULL;
-               if (!ppage || PageSlab(ppage))
+               if (!ppage || PageSlab(ppage) || page_has_type(ppage))
                        pcount = 0;
                else
                        pcount = page_mapcount(ppage);
index 50ce1bddaf56c20176ef51b772170efa0fdfda40..39b4494e29f1fa8805cb3f51125576a82de7b816 100644 (file)
@@ -669,6 +669,7 @@ PAGEFLAG_FALSE(DoubleMap)
 
 #define PAGE_TYPE_BASE 0xf0000000
 /* Reserve             0x0000007f to catch underflows of page_mapcount */
+#define PAGE_MAPCOUNT_RESERVE  -128
 #define PG_buddy       0x00000080
 #define PG_balloon     0x00000100
 #define PG_kmemcg      0x00000200
@@ -677,6 +678,11 @@ PAGEFLAG_FALSE(DoubleMap)
 #define PageType(page, flag)                                           \
        ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
 
+static inline int page_has_type(struct page *page)
+{
+       return (int)page->page_type < PAGE_MAPCOUNT_RESERVE;
+}
+
 #define PAGE_TYPE_OPS(uname, lname)                                    \
 static __always_inline int Page##uname(struct page *page)              \
 {                                                                      \