diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2009-01-07 21:08:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 11:31:09 -0500 |
commit | fee7b548e6f2bd4bfd03a1a45d3afd593de7d5e9 (patch) | |
tree | 90a8b610298013c6ce2d9bb7970b8e6d2a66f488 /mm/memcontrol.c | |
parent | c772be939e078afd2505ede7d596a30f8f61de95 (diff) |
memcg: show real limit under hierarchy mode
Show "real" limit of memcg. This helps my debugging and maybe useful for
users.
While testing hierarchy like this
mount -t cgroup none /cgroup -t memory
mkdir /cgroup/A
set use_hierarchy==1 to "A"
mkdir /cgroup/A/01
mkdir /cgroup/A/01/02
mkdir /cgroup/A/01/03
mkdir /cgroup/A/01/03/04
mkdir /cgroup/A/08
mkdir /cgroup/A/08/01
....
and set each own limit to them, "real" limit of each memcg is unclear.
This patch shows real limit by checking all ancestors.
Changelog: (v1) -> (v2)
- remove "if" and use "min(a,b)"
Acked-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c7d78eca8363..8d2e5c8a25b1 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1782,6 +1782,34 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, | |||
1782 | return ret; | 1782 | return ret; |
1783 | } | 1783 | } |
1784 | 1784 | ||
1785 | static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg, | ||
1786 | unsigned long long *mem_limit, unsigned long long *memsw_limit) | ||
1787 | { | ||
1788 | struct cgroup *cgroup; | ||
1789 | unsigned long long min_limit, min_memsw_limit, tmp; | ||
1790 | |||
1791 | min_limit = res_counter_read_u64(&memcg->res, RES_LIMIT); | ||
1792 | min_memsw_limit = res_counter_read_u64(&memcg->memsw, RES_LIMIT); | ||
1793 | cgroup = memcg->css.cgroup; | ||
1794 | if (!memcg->use_hierarchy) | ||
1795 | goto out; | ||
1796 | |||
1797 | while (cgroup->parent) { | ||
1798 | cgroup = cgroup->parent; | ||
1799 | memcg = mem_cgroup_from_cont(cgroup); | ||
1800 | if (!memcg->use_hierarchy) | ||
1801 | break; | ||
1802 | tmp = res_counter_read_u64(&memcg->res, RES_LIMIT); | ||
1803 | min_limit = min(min_limit, tmp); | ||
1804 | tmp = res_counter_read_u64(&memcg->memsw, RES_LIMIT); | ||
1805 | min_memsw_limit = min(min_memsw_limit, tmp); | ||
1806 | } | ||
1807 | out: | ||
1808 | *mem_limit = min_limit; | ||
1809 | *memsw_limit = min_memsw_limit; | ||
1810 | return; | ||
1811 | } | ||
1812 | |||
1785 | static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) | 1813 | static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) |
1786 | { | 1814 | { |
1787 | struct mem_cgroup *mem; | 1815 | struct mem_cgroup *mem; |
@@ -1855,6 +1883,13 @@ static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, | |||
1855 | cb->fill(cb, "unevictable", unevictable * PAGE_SIZE); | 1883 | cb->fill(cb, "unevictable", unevictable * PAGE_SIZE); |
1856 | 1884 | ||
1857 | } | 1885 | } |
1886 | { | ||
1887 | unsigned long long limit, memsw_limit; | ||
1888 | memcg_get_hierarchical_limit(mem_cont, &limit, &memsw_limit); | ||
1889 | cb->fill(cb, "hierarchical_memory_limit", limit); | ||
1890 | if (do_swap_account) | ||
1891 | cb->fill(cb, "hierarchical_memsw_limit", memsw_limit); | ||
1892 | } | ||
1858 | 1893 | ||
1859 | #ifdef CONFIG_DEBUG_VM | 1894 | #ifdef CONFIG_DEBUG_VM |
1860 | cb->fill(cb, "inactive_ratio", calc_inactive_ratio(mem_cont, NULL)); | 1895 | cb->fill(cb, "inactive_ratio", calc_inactive_ratio(mem_cont, NULL)); |