Commit 673520f8 authored by Qi Zheng's avatar Qi Zheng Committed by Andrew Morton
Browse files

mm: memcontrol: add {pgscan,pgsteal}_{kswapd,direct} items in memory.stat of cgroup v2

There are already statistics of {pgscan,pgsteal}_kswapd and
{pgscan,pgsteal}_direct of memcg event here, but now only the sum of the
two is displayed in memory.stat of cgroup v2.

In order to obtain more accurate information during monitoring and
debugging, and to align with the display in /proc/vmstat, it better to
display {pgscan,pgsteal}_kswapd and {pgscan,pgsteal}_direct separately.

Also, for forward compatibility, we still display pgscan and pgsteal items
so that it won't break existing applications.

[zhengqi.arch@bytedance.com: add comment for memcg_vm_event_stat (suggested by Michal)]
  Link: https://lkml.kernel.org/r/20220606154028.55030-1-zhengqi.arch@bytedance.com
[zhengqi.arch@bytedance.com: fix the doc, thanks to Johannes]
  Link: https://lkml.kernel.org/r/20220607064803.79363-1-zhengqi.arch@bytedance.com
Link: https://lkml.kernel.org/r/20220604082209.55174-1-zhengqi.arch@bytedance.com


Signed-off-by: default avatarQi Zheng <zhengqi.arch@bytedance.com>
Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Acked-by: default avatarRoman Gushchin <roman.gushchin@linux.dev>
Acked-by: default avatarMuchun Song <songmuchun@bytedance.com>
Acked-by: default avatarShakeel Butt <shakeelb@google.com>
Acked-by: default avatarMichal Hocko <mhocko@suse.com>
Cc: Muchun Song <songmuchun@bytedance.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 153090f2
Loading
Loading
Loading
Loading
+18 −6
Original line number Original line Diff line number Diff line
@@ -1433,6 +1433,24 @@ PAGE_SIZE multiple when read back.
	  workingset_nodereclaim
	  workingset_nodereclaim
		Number of times a shadow node has been reclaimed
		Number of times a shadow node has been reclaimed


	  pgscan (npn)
		Amount of scanned pages (in an inactive LRU list)

	  pgsteal (npn)
		Amount of reclaimed pages

	  pgscan_kswapd (npn)
		Amount of scanned pages by kswapd (in an inactive LRU list)

	  pgscan_direct (npn)
		Amount of scanned pages directly  (in an inactive LRU list)

	  pgsteal_kswapd (npn)
		Amount of reclaimed pages by kswapd

	  pgsteal_direct (npn)
		Amount of reclaimed pages directly

	  pgfault (npn)
	  pgfault (npn)
		Total number of page faults incurred
		Total number of page faults incurred


@@ -1442,12 +1460,6 @@ PAGE_SIZE multiple when read back.
	  pgrefill (npn)
	  pgrefill (npn)
		Amount of scanned pages (in an active LRU list)
		Amount of scanned pages (in an active LRU list)


	  pgscan (npn)
		Amount of scanned pages (in an inactive LRU list)

	  pgsteal (npn)
		Amount of reclaimed pages

	  pgactivate (npn)
	  pgactivate (npn)
		Amount of pages moved to the active LRU list
		Amount of pages moved to the active LRU list


+27 −28
Original line number Original line Diff line number Diff line
@@ -1460,6 +1460,29 @@ static inline unsigned long memcg_page_state_output(struct mem_cgroup *memcg,
	return memcg_page_state(memcg, item) * memcg_page_state_unit(item);
	return memcg_page_state(memcg, item) * memcg_page_state_unit(item);
}
}


/* Subset of vm_event_item to report for memcg event stats */
static const unsigned int memcg_vm_event_stat[] = {
	PGSCAN_KSWAPD,
	PGSCAN_DIRECT,
	PGSTEAL_KSWAPD,
	PGSTEAL_DIRECT,
	PGFAULT,
	PGMAJFAULT,
	PGREFILL,
	PGACTIVATE,
	PGDEACTIVATE,
	PGLAZYFREE,
	PGLAZYFREED,
#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_ZSWAP)
	ZSWPIN,
	ZSWPOUT,
#endif
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
	THP_FAULT_ALLOC,
	THP_COLLAPSE_ALLOC,
#endif
};

static char *memory_stat_format(struct mem_cgroup *memcg)
static char *memory_stat_format(struct mem_cgroup *memcg)
{
{
	struct seq_buf s;
	struct seq_buf s;
@@ -1495,41 +1518,17 @@ static char *memory_stat_format(struct mem_cgroup *memcg)
	}
	}


	/* Accumulated memory events */
	/* Accumulated memory events */

	seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGFAULT),
		       memcg_events(memcg, PGFAULT));
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGMAJFAULT),
		       memcg_events(memcg, PGMAJFAULT));
	seq_buf_printf(&s, "%s %lu\n",  vm_event_name(PGREFILL),
		       memcg_events(memcg, PGREFILL));
	seq_buf_printf(&s, "pgscan %lu\n",
	seq_buf_printf(&s, "pgscan %lu\n",
		       memcg_events(memcg, PGSCAN_KSWAPD) +
		       memcg_events(memcg, PGSCAN_KSWAPD) +
		       memcg_events(memcg, PGSCAN_DIRECT));
		       memcg_events(memcg, PGSCAN_DIRECT));
	seq_buf_printf(&s, "pgsteal %lu\n",
	seq_buf_printf(&s, "pgsteal %lu\n",
		       memcg_events(memcg, PGSTEAL_KSWAPD) +
		       memcg_events(memcg, PGSTEAL_KSWAPD) +
		       memcg_events(memcg, PGSTEAL_DIRECT));
		       memcg_events(memcg, PGSTEAL_DIRECT));
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGACTIVATE),
		       memcg_events(memcg, PGACTIVATE));
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGDEACTIVATE),
		       memcg_events(memcg, PGDEACTIVATE));
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGLAZYFREE),
		       memcg_events(memcg, PGLAZYFREE));
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGLAZYFREED),
		       memcg_events(memcg, PGLAZYFREED));

#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_ZSWAP)
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(ZSWPIN),
		       memcg_events(memcg, ZSWPIN));
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(ZSWPOUT),
		       memcg_events(memcg, ZSWPOUT));
#endif


#ifdef CONFIG_TRANSPARENT_HUGEPAGE
	for (i = 0; i < ARRAY_SIZE(memcg_vm_event_stat); i++)
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(THP_FAULT_ALLOC),
		seq_buf_printf(&s, "%s %lu\n",
		       memcg_events(memcg, THP_FAULT_ALLOC));
			       vm_event_name(memcg_vm_event_stat[i]),
	seq_buf_printf(&s, "%s %lu\n", vm_event_name(THP_COLLAPSE_ALLOC),
			       memcg_events(memcg, memcg_vm_event_stat[i]));
		       memcg_events(memcg, THP_COLLAPSE_ALLOC));
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */


	/* The above should easily fit into one page */
	/* The above should easily fit into one page */
	WARN_ON_ONCE(seq_buf_has_overflowed(&s));
	WARN_ON_ONCE(seq_buf_has_overflowed(&s));