Skip to content

Commit

Permalink
mm: memcontrol: basic memory statistics in cgroup2 memory controller
Browse files Browse the repository at this point in the history
Provide a cgroup2 memory.stat that provides statistics on LRU memory
and fault event counters. More consumers and breakdowns will follow.

Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Johannes Weiner authored and Linus Torvalds committed Jan 21, 2016
1 parent 44b7a8d commit 587d9f7
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
56 changes: 56 additions & 0 deletions Documentation/cgroup-v2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,62 @@ PAGE_SIZE multiple when read back.
the cgroup. This may not exactly match the number of
processes killed but should generally be close.

memory.stat

A read-only flat-keyed file which exists on non-root cgroups.

This breaks down the cgroup's memory footprint into different
types of memory, type-specific details, and other information
on the state and past events of the memory management system.

All memory amounts are in bytes.

The entries are ordered to be human readable, and new entries
can show up in the middle. Don't rely on items remaining in a
fixed position; use the keys to look up specific values!

anon

Amount of memory used in anonymous mappings such as
brk(), sbrk(), and mmap(MAP_ANONYMOUS)

file

Amount of memory used to cache filesystem data,
including tmpfs and shared memory.

file_mapped

Amount of cached filesystem data mapped with mmap()

file_dirty

Amount of cached filesystem data that was modified but
not yet written back to disk

file_writeback

Amount of cached filesystem data that was modified and
is currently being written back to disk

inactive_anon
active_anon
inactive_file
active_file
unevictable

Amount of memory, swap-backed and filesystem-backed,
on the internal memory management lists used by the
page reclaim algorithm

pgfault

Total number of page faults incurred

pgmajfault

Number of major page faults incurred

memory.swap.current

A read-only single value file which exists on non-root
Expand Down
68 changes: 68 additions & 0 deletions mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -2767,6 +2767,18 @@ static unsigned long tree_stat(struct mem_cgroup *memcg,
return val;
}

static unsigned long tree_events(struct mem_cgroup *memcg,
enum mem_cgroup_events_index idx)
{
struct mem_cgroup *iter;
unsigned long val = 0;

for_each_mem_cgroup_tree(iter, memcg)
val += mem_cgroup_read_events(iter, idx);

return val;
}

static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
{
unsigned long val;
Expand Down Expand Up @@ -5096,6 +5108,57 @@ static int memory_events_show(struct seq_file *m, void *v)
return 0;
}

static int memory_stat_show(struct seq_file *m, void *v)
{
struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
int i;

/*
* Provide statistics on the state of the memory subsystem as
* well as cumulative event counters that show past behavior.
*
* This list is ordered following a combination of these gradients:
* 1) generic big picture -> specifics and details
* 2) reflecting userspace activity -> reflecting kernel heuristics
*
* Current memory state:
*/

seq_printf(m, "anon %llu\n",
(u64)tree_stat(memcg, MEM_CGROUP_STAT_RSS) * PAGE_SIZE);
seq_printf(m, "file %llu\n",
(u64)tree_stat(memcg, MEM_CGROUP_STAT_CACHE) * PAGE_SIZE);

seq_printf(m, "file_mapped %llu\n",
(u64)tree_stat(memcg, MEM_CGROUP_STAT_FILE_MAPPED) *
PAGE_SIZE);
seq_printf(m, "file_dirty %llu\n",
(u64)tree_stat(memcg, MEM_CGROUP_STAT_DIRTY) *
PAGE_SIZE);
seq_printf(m, "file_writeback %llu\n",
(u64)tree_stat(memcg, MEM_CGROUP_STAT_WRITEBACK) *
PAGE_SIZE);

for (i = 0; i < NR_LRU_LISTS; i++) {
struct mem_cgroup *mi;
unsigned long val = 0;

for_each_mem_cgroup_tree(mi, memcg)
val += mem_cgroup_nr_lru_pages(mi, BIT(i));
seq_printf(m, "%s %llu\n",
mem_cgroup_lru_names[i], (u64)val * PAGE_SIZE);
}

/* Accumulated memory events */

seq_printf(m, "pgfault %lu\n",
tree_events(memcg, MEM_CGROUP_EVENTS_PGFAULT));
seq_printf(m, "pgmajfault %lu\n",
tree_events(memcg, MEM_CGROUP_EVENTS_PGMAJFAULT));

return 0;
}

static struct cftype memory_files[] = {
{
.name = "current",
Expand Down Expand Up @@ -5126,6 +5189,11 @@ static struct cftype memory_files[] = {
.file_offset = offsetof(struct mem_cgroup, events_file),
.seq_show = memory_events_show,
},
{
.name = "stat",
.flags = CFTYPE_NOT_ON_ROOT,
.seq_show = memory_stat_show,
},
{ } /* terminate */
};

Expand Down

0 comments on commit 587d9f7

Please sign in to comment.