Commit d42f3245 authored by Roman Gushchin's avatar Roman Gushchin Committed by Linus Torvalds
Browse files

mm: memcg: convert vmstat slab counters to bytes



In order to prepare for per-object slab memory accounting, convert
NR_SLAB_RECLAIMABLE and NR_SLAB_UNRECLAIMABLE vmstat items to bytes.

To make it obvious, rename them to NR_SLAB_RECLAIMABLE_B and
NR_SLAB_UNRECLAIMABLE_B (similar to NR_KERNEL_STACK_KB).

Internally global and per-node counters are stored in pages, however memcg
and lruvec counters are stored in bytes.  This scheme may look weird, but
only for now.  As soon as slab pages will be shared between multiple
cgroups, global and node counters will reflect the total number of slab
pages.  However memcg and lruvec counters will be used for per-memcg slab
memory tracking, which will take separate kernel objects in the account.
Keeping global and node counters in pages helps to avoid additional
overhead.

The size of slab memory shouldn't exceed 4Gb on 32-bit machines, so it
will fit into atomic_long_t we use for vmstats.

Signed-off-by: default avatarRoman Gushchin <guro@fb.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Reviewed-by: default avatarShakeel Butt <shakeelb@google.com>
Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
Cc: Christoph Lameter <cl@linux.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Link: http://lkml.kernel.org/r/20200623174037.3951353-4-guro@fb.com


Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ea426c2a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -368,8 +368,8 @@ static ssize_t node_read_meminfo(struct device *dev,
	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);
	sreclaimable = node_page_state_pages(pgdat, NR_SLAB_RECLAIMABLE_B);
	sunreclaimable = node_page_state_pages(pgdat, NR_SLAB_UNRECLAIMABLE_B);
	n = sprintf(buf,
		       "Node %d MemTotal:       %8lu kB\n"
		       "Node %d MemFree:        %8lu kB\n"
+2 −2
Original line number Diff line number Diff line
@@ -52,8 +52,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);
	sreclaimable = global_node_page_state_pages(NR_SLAB_RECLAIMABLE_B);
	sunreclaim = global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);

	show_val_kb(m, "MemTotal:       ", i.totalram);
	show_val_kb(m, "MemFree:        ", i.freeram);
+13 −3
Original line number Diff line number Diff line
@@ -174,8 +174,8 @@ enum node_stat_item {
	NR_INACTIVE_FILE,	/*  "     "     "   "       "         */
	NR_ACTIVE_FILE,		/*  "     "     "   "       "         */
	NR_UNEVICTABLE,		/*  "     "     "   "       "         */
	NR_SLAB_RECLAIMABLE,
	NR_SLAB_UNRECLAIMABLE,
	NR_SLAB_RECLAIMABLE_B,
	NR_SLAB_UNRECLAIMABLE_B,
	NR_ISOLATED_ANON,	/* Temporary isolated pages from anon lru */
	NR_ISOLATED_FILE,	/* Temporary isolated pages from file lru */
	WORKINGSET_NODES,
@@ -213,7 +213,17 @@ enum node_stat_item {
 */
static __always_inline bool vmstat_item_in_bytes(int idx)
{
	return false;
	/*
	 * Global and per-node slab counters track slab pages.
	 * It's expected that changes are multiples of PAGE_SIZE.
	 * Internally values are stored in pages.
	 *
	 * Per-memcg and per-lruvec counters track memory, consumed
	 * by individual slab objects. These counters are actually
	 * byte-precise.
	 */
	return (idx == NR_SLAB_RECLAIMABLE_B ||
		idx == NR_SLAB_UNRECLAIMABLE_B);
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -1663,7 +1663,7 @@ static unsigned long minimum_image_size(unsigned long saveable)
{
	unsigned long size;

	size = global_node_page_state(NR_SLAB_RECLAIMABLE)
	size = global_node_page_state_pages(NR_SLAB_RECLAIMABLE_B)
		+ global_node_page_state(NR_ACTIVE_ANON)
		+ global_node_page_state(NR_INACTIVE_ANON)
		+ global_node_page_state(NR_ACTIVE_FILE)
+4 −7
Original line number Diff line number Diff line
@@ -1391,9 +1391,8 @@ static char *memory_stat_format(struct mem_cgroup *memcg)
		       (u64)memcg_page_state(memcg, MEMCG_KERNEL_STACK_KB) *
		       1024);
	seq_buf_printf(&s, "slab %llu\n",
		       (u64)(memcg_page_state(memcg, NR_SLAB_RECLAIMABLE) +
			     memcg_page_state(memcg, NR_SLAB_UNRECLAIMABLE)) *
		       PAGE_SIZE);
		       (u64)(memcg_page_state(memcg, NR_SLAB_RECLAIMABLE_B) +
			     memcg_page_state(memcg, NR_SLAB_UNRECLAIMABLE_B)));
	seq_buf_printf(&s, "sock %llu\n",
		       (u64)memcg_page_state(memcg, MEMCG_SOCK) *
		       PAGE_SIZE);
@@ -1423,11 +1422,9 @@ static char *memory_stat_format(struct mem_cgroup *memcg)
			       PAGE_SIZE);

	seq_buf_printf(&s, "slab_reclaimable %llu\n",
		       (u64)memcg_page_state(memcg, NR_SLAB_RECLAIMABLE) *
		       PAGE_SIZE);
		       (u64)memcg_page_state(memcg, NR_SLAB_RECLAIMABLE_B));
	seq_buf_printf(&s, "slab_unreclaimable %llu\n",
		       (u64)memcg_page_state(memcg, NR_SLAB_UNRECLAIMABLE) *
		       PAGE_SIZE);
		       (u64)memcg_page_state(memcg, NR_SLAB_UNRECLAIMABLE_B));

	/* Accumulated memory events */

Loading