mm, proc: add KReclaimable to /proc/meminfo
authorVlastimil Babka <vbabka@suse.cz>
Fri, 26 Oct 2018 22:05:50 +0000 (15:05 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 26 Oct 2018 23:26:32 +0000 (16:26 -0700)
The vmstat NR_KERNEL_MISC_RECLAIMABLE counter is for kernel non-slab
allocations that can be reclaimed via shrinker.  In /proc/meminfo, we can
show the sum of all reclaimable kernel allocations (including slab) as
"KReclaimable".  Add the same counter also to per-node meminfo under /sys

With this counter, users will have more complete information about kernel
memory usage.  Non-slab reclaimable pages (currently just the ION
allocator) will not be missing from /proc/meminfo, making users wonder
where part of their memory went.  More precisely, they already appear in
MemAvailable, but without the new counter, it's not obvious why the value
in MemAvailable doesn't fully correspond with the sum of other counters
participating in it.

Link: http://lkml.kernel.org/r/20180731090649.16028-6-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Roman Gushchin <guro@fb.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Laura Abbott <labbott@redhat.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Vijayanand Jitta <vjitta@codeaurora.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Documentation/filesystems/proc.txt
drivers/base/node.c
fs/proc/meminfo.c

index 22b4b00dee31290bde37b3abc63f4a0807f973cc..12a5e6e693b6e4f516ffb85d78677aff53ab81b0 100644 (file)
@@ -858,6 +858,7 @@ Writeback:           0 kB
 AnonPages:      861800 kB
 Mapped:         280372 kB
 Shmem:             644 kB
+KReclaimable:   168048 kB
 Slab:           284364 kB
 SReclaimable:   159856 kB
 SUnreclaim:     124508 kB
@@ -925,6 +926,9 @@ AnonHugePages: Non-file backed huge pages mapped into userspace page tables
 ShmemHugePages: Memory used by shared memory (shmem) and tmpfs allocated
               with huge pages
 ShmemPmdMapped: Shared memory mapped into userspace with huge pages
+KReclaimable: Kernel allocations that the kernel will attempt to reclaim
+              under memory pressure. Includes SReclaimable (below), and other
+              direct allocations with a shrinker.
         Slab: in-kernel data structures cache
 SReclaimable: Part of Slab, that might be reclaimed, such as caches
   SUnreclaim: Part of Slab, that cannot be reclaimed on memory pressure
index 1ac4c36e13bbd9a70a07ba310e01bc053614c103..86d6cd92ce3d8cc9ffa5b964d84e8e06d92bc163 100644 (file)
@@ -67,8 +67,11 @@ static ssize_t node_read_meminfo(struct device *dev,
        int nid = dev->id;
        struct pglist_data *pgdat = NODE_DATA(nid);
        struct sysinfo i;
+       unsigned long sreclaimable, sunreclaimable;
 
        si_meminfo_node(&i, nid);
+       sreclaimable = node_page_state(pgdat, NR_SLAB_RECLAIMABLE);
+       sunreclaimable = node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE);
        n = sprintf(buf,
                       "Node %d MemTotal:       %8lu kB\n"
                       "Node %d MemFree:        %8lu kB\n"
@@ -118,6 +121,7 @@ static ssize_t node_read_meminfo(struct device *dev,
                       "Node %d NFS_Unstable:   %8lu kB\n"
                       "Node %d Bounce:         %8lu kB\n"
                       "Node %d WritebackTmp:   %8lu kB\n"
+                      "Node %d KReclaimable:   %8lu kB\n"
                       "Node %d Slab:           %8lu kB\n"
                       "Node %d SReclaimable:   %8lu kB\n"
                       "Node %d SUnreclaim:     %8lu kB\n"
@@ -138,20 +142,21 @@ static ssize_t node_read_meminfo(struct device *dev,
                       nid, K(node_page_state(pgdat, NR_UNSTABLE_NFS)),
                       nid, K(sum_zone_node_page_state(nid, NR_BOUNCE)),
                       nid, K(node_page_state(pgdat, NR_WRITEBACK_TEMP)),
-                      nid, K(node_page_state(pgdat, NR_SLAB_RECLAIMABLE) +
-                             node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE)),
-                      nid, K(node_page_state(pgdat, NR_SLAB_RECLAIMABLE)),
+                      nid, K(sreclaimable +
+                             node_page_state(pgdat, NR_KERNEL_MISC_RECLAIMABLE)),
+                      nid, K(sreclaimable + sunreclaimable),
+                      nid, K(sreclaimable),
+                      nid, K(sunreclaimable)
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-                      nid, K(node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE)),
+                      ,
                       nid, K(node_page_state(pgdat, NR_ANON_THPS) *
                                       HPAGE_PMD_NR),
                       nid, K(node_page_state(pgdat, NR_SHMEM_THPS) *
                                       HPAGE_PMD_NR),
                       nid, K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) *
-                                      HPAGE_PMD_NR));
-#else
-                      nid, K(node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE)));
+                                      HPAGE_PMD_NR)
 #endif
+                      );
        n += hugetlb_report_node_meminfo(nid, buf + n);
        return n;
 }
index edda898714eb7bb23585241dc6631800c6ba1dfb..568d90e17c17d4d7358ee56c544638a140538a36 100644 (file)
@@ -38,6 +38,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
        long cached;
        long available;
        unsigned long pages[NR_LRU_LISTS];
+       unsigned long sreclaimable, sunreclaim;
        int lru;
 
        si_meminfo(&i);
@@ -53,6 +54,8 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
                pages[lru] = global_node_page_state(NR_LRU_BASE + lru);
 
        available = si_mem_available();
+       sreclaimable = global_node_page_state(NR_SLAB_RECLAIMABLE);
+       sunreclaim = global_node_page_state(NR_SLAB_UNRECLAIMABLE);
 
        show_val_kb(m, "MemTotal:       ", i.totalram);
        show_val_kb(m, "MemFree:        ", i.freeram);
@@ -94,14 +97,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
        show_val_kb(m, "Mapped:         ",
                    global_node_page_state(NR_FILE_MAPPED));
        show_val_kb(m, "Shmem:          ", i.sharedram);
-       show_val_kb(m, "Slab:           ",
-                   global_node_page_state(NR_SLAB_RECLAIMABLE) +
-                   global_node_page_state(NR_SLAB_UNRECLAIMABLE));
-
-       show_val_kb(m, "SReclaimable:   ",
-                   global_node_page_state(NR_SLAB_RECLAIMABLE));
-       show_val_kb(m, "SUnreclaim:     ",
-                   global_node_page_state(NR_SLAB_UNRECLAIMABLE));
+       show_val_kb(m, "KReclaimable:   ", sreclaimable +
+                   global_node_page_state(NR_KERNEL_MISC_RECLAIMABLE));
+       show_val_kb(m, "Slab:           ", sreclaimable + sunreclaim);
+       show_val_kb(m, "SReclaimable:   ", sreclaimable);
+       show_val_kb(m, "SUnreclaim:     ", sunreclaim);
        seq_printf(m, "KernelStack:    %8lu kB\n",
                   global_zone_page_state(NR_KERNEL_STACK_KB));
        show_val_kb(m, "PageTables:     ",