[Devel] [PATCH rh7 1/3] memcg: add function to get container's ram size

Vladimir Davydov vdavydov at parallels.com
Thu May 21 08:27:15 PDT 2015


Sometimes we need to get the ram size of the container the current
process belongs to and we cannot open the memory cgroup by name as we
usually do (e.g. see ub_dirty_limits). This patch adds a function for
this purpose, mem_cgroup_ram_pages.

In this function we implicitly assume that each container lives in its
own top level memory cgroup. If it is changed (e.g. we move all
containers to /machine.slice), then we must rework this function (as
well as all the code in beancounters that gets stats from memcg). One
way to do that is allow the userspace assign a memory cgroup to a ve or
beancounter cgroup and get the memory cgroup of a container from
get_exec_env() or get_exec_ub().

Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 include/linux/memcontrol.h |    6 ++++++
 mm/memcontrol.c            |   31 +++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 5393f5f3b7d5..1382e4939a21 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -127,6 +127,7 @@ extern void mem_cgroup_print_oom_info(struct mem_cgroup *memcg,
 					struct task_struct *p);
 extern void mem_cgroup_replace_page_cache(struct page *oldpage,
 					struct page *newpage);
+unsigned long mem_cgroup_ram_pages(void);
 
 #ifdef CONFIG_MEMCG_SWAP
 extern int do_swap_account;
@@ -400,6 +401,11 @@ static inline void mem_cgroup_replace_page_cache(struct page *oldpage,
 				struct page *newpage)
 {
 }
+
+static inline unsigned long mem_cgroup_ram_pages(void)
+{
+	return ULONG_MAX;
+}
 #endif /* CONFIG_MEMCG */
 
 #if !defined(CONFIG_MEMCG) || !defined(CONFIG_DEBUG_VM)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6ef83fbd1a58..d8f9b5561222 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1620,6 +1620,37 @@ void mem_cgroup_note_oom_kill(struct mem_cgroup *root_memcg,
 		css_put(&memcg_to_put->css);
 }
 
+/*
+ * XXX: This function returns the limit of the topmost memory cgroup the
+ * current process belongs to (ULONG_MAX if unlimited). It is used to get the
+ * number of memory pages available to a Virtuozzo container. Here we
+ * implicitly assume that each container lives in its own top level memory
+ * cgroup. If it is changed, this function must be reworked. E.g. we could
+ * assign a memory cgroup to each ve or beancounter cgroup and get the memory
+ * cgroup of a container from get_exec_env() or get_exec_ub().
+ */
+unsigned long mem_cgroup_ram_pages(void)
+{
+	struct mem_cgroup *memcg_to_put, *memcg, *parent;
+	unsigned long long limit = RESOURCE_MAX;
+
+	memcg_to_put = memcg = try_get_mem_cgroup_from_mm(current->mm);
+	if (!memcg || memcg == root_mem_cgroup)
+		goto out;
+
+	while ((parent = parent_mem_cgroup(memcg)) &&
+	       parent != root_mem_cgroup)
+		memcg = parent;
+
+	limit = res_counter_read_u64(&memcg->res, RES_LIMIT);
+out:
+	if (memcg_to_put)
+		css_put(&memcg_to_put->css);
+	if (limit == RESOURCE_MAX)
+		return ULONG_MAX;
+	return min_t(unsigned long long, ULONG_MAX, limit >> PAGE_SHIFT);
+}
+
 #define mem_cgroup_from_res_counter(counter, member)	\
 	container_of(counter, struct mem_cgroup, member)
 
-- 
1.7.10.4




More information about the Devel mailing list