Commit 61f94e18 authored by Vlastimil Babka's avatar Vlastimil Babka Committed by Linus Torvalds

mm, proc: add KReclaimable to /proc/meminfo

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.czSigned-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
Acked-by: default avatarRoman 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b29940c1
...@@ -858,6 +858,7 @@ Writeback: 0 kB ...@@ -858,6 +858,7 @@ Writeback: 0 kB
AnonPages: 861800 kB AnonPages: 861800 kB
Mapped: 280372 kB Mapped: 280372 kB
Shmem: 644 kB Shmem: 644 kB
KReclaimable: 168048 kB
Slab: 284364 kB Slab: 284364 kB
SReclaimable: 159856 kB SReclaimable: 159856 kB
SUnreclaim: 124508 kB SUnreclaim: 124508 kB
...@@ -925,6 +926,9 @@ AnonHugePages: Non-file backed huge pages mapped into userspace page tables ...@@ -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 ShmemHugePages: Memory used by shared memory (shmem) and tmpfs allocated
with huge pages with huge pages
ShmemPmdMapped: Shared memory mapped into userspace 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 Slab: in-kernel data structures cache
SReclaimable: Part of Slab, that might be reclaimed, such as caches SReclaimable: Part of Slab, that might be reclaimed, such as caches
SUnreclaim: Part of Slab, that cannot be reclaimed on memory pressure SUnreclaim: Part of Slab, that cannot be reclaimed on memory pressure
......
...@@ -67,8 +67,11 @@ static ssize_t node_read_meminfo(struct device *dev, ...@@ -67,8 +67,11 @@ static ssize_t node_read_meminfo(struct device *dev,
int nid = dev->id; int nid = dev->id;
struct pglist_data *pgdat = NODE_DATA(nid); struct pglist_data *pgdat = NODE_DATA(nid);
struct sysinfo i; struct sysinfo i;
unsigned long sreclaimable, sunreclaimable;
si_meminfo_node(&i, nid); si_meminfo_node(&i, nid);
sreclaimable = node_page_state(pgdat, NR_SLAB_RECLAIMABLE);
sunreclaimable = node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE);
n = sprintf(buf, n = sprintf(buf,
"Node %d MemTotal: %8lu kB\n" "Node %d MemTotal: %8lu kB\n"
"Node %d MemFree: %8lu kB\n" "Node %d MemFree: %8lu kB\n"
...@@ -118,6 +121,7 @@ static ssize_t node_read_meminfo(struct device *dev, ...@@ -118,6 +121,7 @@ static ssize_t node_read_meminfo(struct device *dev,
"Node %d NFS_Unstable: %8lu kB\n" "Node %d NFS_Unstable: %8lu kB\n"
"Node %d Bounce: %8lu kB\n" "Node %d Bounce: %8lu kB\n"
"Node %d WritebackTmp: %8lu kB\n" "Node %d WritebackTmp: %8lu kB\n"
"Node %d KReclaimable: %8lu kB\n"
"Node %d Slab: %8lu kB\n" "Node %d Slab: %8lu kB\n"
"Node %d SReclaimable: %8lu kB\n" "Node %d SReclaimable: %8lu kB\n"
"Node %d SUnreclaim: %8lu kB\n" "Node %d SUnreclaim: %8lu kB\n"
...@@ -138,20 +142,21 @@ static ssize_t node_read_meminfo(struct device *dev, ...@@ -138,20 +142,21 @@ static ssize_t node_read_meminfo(struct device *dev,
nid, K(node_page_state(pgdat, NR_UNSTABLE_NFS)), nid, K(node_page_state(pgdat, NR_UNSTABLE_NFS)),
nid, K(sum_zone_node_page_state(nid, NR_BOUNCE)), 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_WRITEBACK_TEMP)),
nid, K(node_page_state(pgdat, NR_SLAB_RECLAIMABLE) + nid, K(sreclaimable +
node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE)), node_page_state(pgdat, NR_KERNEL_MISC_RECLAIMABLE)),
nid, K(node_page_state(pgdat, NR_SLAB_RECLAIMABLE)), nid, K(sreclaimable + sunreclaimable),
nid, K(sreclaimable),
nid, K(sunreclaimable)
#ifdef CONFIG_TRANSPARENT_HUGEPAGE #ifdef CONFIG_TRANSPARENT_HUGEPAGE
nid, K(node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE)), ,
nid, K(node_page_state(pgdat, NR_ANON_THPS) * nid, K(node_page_state(pgdat, NR_ANON_THPS) *
HPAGE_PMD_NR), HPAGE_PMD_NR),
nid, K(node_page_state(pgdat, NR_SHMEM_THPS) * nid, K(node_page_state(pgdat, NR_SHMEM_THPS) *
HPAGE_PMD_NR), HPAGE_PMD_NR),
nid, K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) * nid, K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) *
HPAGE_PMD_NR)); HPAGE_PMD_NR)
#else
nid, K(node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE)));
#endif #endif
);
n += hugetlb_report_node_meminfo(nid, buf + n); n += hugetlb_report_node_meminfo(nid, buf + n);
return n; return n;
} }
......
...@@ -38,6 +38,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) ...@@ -38,6 +38,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
long cached; long cached;
long available; long available;
unsigned long pages[NR_LRU_LISTS]; unsigned long pages[NR_LRU_LISTS];
unsigned long sreclaimable, sunreclaim;
int lru; int lru;
si_meminfo(&i); si_meminfo(&i);
...@@ -53,6 +54,8 @@ static int meminfo_proc_show(struct seq_file *m, void *v) ...@@ -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); pages[lru] = global_node_page_state(NR_LRU_BASE + lru);
available = si_mem_available(); 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, "MemTotal: ", i.totalram);
show_val_kb(m, "MemFree: ", i.freeram); show_val_kb(m, "MemFree: ", i.freeram);
...@@ -94,14 +97,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v) ...@@ -94,14 +97,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
show_val_kb(m, "Mapped: ", show_val_kb(m, "Mapped: ",
global_node_page_state(NR_FILE_MAPPED)); global_node_page_state(NR_FILE_MAPPED));
show_val_kb(m, "Shmem: ", i.sharedram); show_val_kb(m, "Shmem: ", i.sharedram);
show_val_kb(m, "Slab: ", show_val_kb(m, "KReclaimable: ", sreclaimable +
global_node_page_state(NR_SLAB_RECLAIMABLE) + global_node_page_state(NR_KERNEL_MISC_RECLAIMABLE));
global_node_page_state(NR_SLAB_UNRECLAIMABLE)); show_val_kb(m, "Slab: ", sreclaimable + sunreclaim);
show_val_kb(m, "SReclaimable: ", sreclaimable);
show_val_kb(m, "SReclaimable: ", show_val_kb(m, "SUnreclaim: ", sunreclaim);
global_node_page_state(NR_SLAB_RECLAIMABLE));
show_val_kb(m, "SUnreclaim: ",
global_node_page_state(NR_SLAB_UNRECLAIMABLE));
seq_printf(m, "KernelStack: %8lu kB\n", seq_printf(m, "KernelStack: %8lu kB\n",
global_zone_page_state(NR_KERNEL_STACK_KB)); global_zone_page_state(NR_KERNEL_STACK_KB));
show_val_kb(m, "PageTables: ", show_val_kb(m, "PageTables: ",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment