tools/vm/page-types.c: support swap entry
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Thu, 17 Mar 2016 21:17:47 +0000 (14:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 17 Mar 2016 22:09:34 +0000 (15:09 -0700)
/proc/pid/pagemap (pte_to_pagemap_entry() internally) already reports
about swap entry, so let's make the in-kernel utility aware of it.

Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Vladimir Davydov <vdavydov@parallels.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
tools/vm/page-types.c

index 5a6016224bb9c9c4bbe5f7b28c37738f0edec5a3..ec62ab4d8b5559a08f9b5ce95c35d73b8cad93f1 100644 (file)
@@ -61,6 +61,8 @@
 #define PM_PFRAME_BITS         55
 #define PM_PFRAME_MASK         ((1LL << PM_PFRAME_BITS) - 1)
 #define PM_PFRAME(x)           ((x) & PM_PFRAME_MASK)
+#define MAX_SWAPFILES_SHIFT    5
+#define PM_SWAP_OFFSET(x)      (((x) & PM_PFRAME_MASK) >> MAX_SWAPFILES_SHIFT)
 #define PM_SOFT_DIRTY          (1ULL << 55)
 #define PM_MMAP_EXCLUSIVE      (1ULL << 56)
 #define PM_FILE                        (1ULL << 61)
@@ -92,7 +94,8 @@
 #define KPF_SLOB_FREE          49
 #define KPF_SLUB_FROZEN                50
 #define KPF_SLUB_DEBUG         51
-#define KPF_FILE               62
+#define KPF_FILE               61
+#define KPF_SWAP               62
 #define KPF_MMAP_EXCLUSIVE     63
 
 #define KPF_ALL_BITS           ((uint64_t)~0ULL)
@@ -146,6 +149,7 @@ static const char * const page_flag_names[] = {
        [KPF_SLUB_DEBUG]        = "E:slub_debug",
 
        [KPF_FILE]              = "F:file",
+       [KPF_SWAP]              = "w:swap",
        [KPF_MMAP_EXCLUSIVE]    = "1:mmap_exclusive",
 };
 
@@ -297,6 +301,10 @@ static unsigned long pagemap_pfn(uint64_t val)
        return pfn;
 }
 
+static unsigned long pagemap_swap_offset(uint64_t val)
+{
+       return val & PM_SWAP ? PM_SWAP_OFFSET(val) : 0;
+}
 
 /*
  * page flag names
@@ -452,6 +460,8 @@ static uint64_t expand_overloaded_flags(uint64_t flags, uint64_t pme)
                flags |= BIT(SOFTDIRTY);
        if (pme & PM_FILE)
                flags |= BIT(FILE);
+       if (pme & PM_SWAP)
+               flags |= BIT(SWAP);
        if (pme & PM_MMAP_EXCLUSIVE)
                flags |= BIT(MMAP_EXCLUSIVE);
 
@@ -613,6 +623,22 @@ static void walk_pfn(unsigned long voffset,
        }
 }
 
+static void walk_swap(unsigned long voffset, uint64_t pme)
+{
+       uint64_t flags = kpageflags_flags(0, pme);
+
+       if (!bit_mask_ok(flags))
+               return;
+
+       if (opt_list == 1)
+               show_page_range(voffset, pagemap_swap_offset(pme), 1, flags);
+       else if (opt_list == 2)
+               show_page(voffset, pagemap_swap_offset(pme), flags);
+
+       nr_pages[hash_slot(flags)]++;
+       total_pages++;
+}
+
 #define PAGEMAP_BATCH  (64 << 10)
 static void walk_vma(unsigned long index, unsigned long count)
 {
@@ -632,6 +658,8 @@ static void walk_vma(unsigned long index, unsigned long count)
                        pfn = pagemap_pfn(buf[i]);
                        if (pfn)
                                walk_pfn(index + i, pfn, 1, buf[i]);
+                       if (buf[i] & PM_SWAP)
+                               walk_swap(index + i, buf[i]);
                }
 
                index += pages;