[Devel] [PATCH rh7 6/6] ub: introduce ub_total_pages

Vladimir Davydov vdavydov at parallels.com
Sun Jun 7 04:57:18 PDT 2015


Now we do not need that hackish mem_cgroup_total_pages, which returns
the maximal number of pages allowed by the limit set upon the top level
cgroup the current resides in. Now we can simply get the limit from the
memory cgroup that is bound to a beancounter using beancounter.memory.
This patch therefore reworks mem_cgroup_total_pages, allowing to pass a
cgroup of interest to it, and introduces ub_total_pages, which returns
the limit of a given beancounter.

Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 fs/proc/base.c             |  5 +++--
 include/bc/beancounter.h   |  1 +
 include/linux/memcontrol.h |  6 ------
 kernel/bc/beancounter.c    | 13 +++++++++++++
 kernel/bc/io_acct.c        |  2 +-
 mm/memcontrol.c            | 28 ++--------------------------
 mm/shmem.c                 |  7 +++----
 7 files changed, 23 insertions(+), 39 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 360169a1b648..4a3915674c52 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -449,9 +449,10 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
 	unsigned long totalpages = totalram_pages + total_swap_pages;
 	unsigned long points = 0;
 	struct mem_cgroup *memcg = NULL;
+	struct user_beancounter *ub = get_exec_ub();
 
-	if (!ve_is_super(get_exec_env())) {
-		totalpages = min(totalpages, mem_cgroup_total_pages(true));
+	if (ub != get_ub0()) {
+		totalpages = min(totalpages, ub_total_pages(ub, true));
 		memcg = OOM_BADNESS_DUMMY_MEMCG;
 	}
 
diff --git a/include/bc/beancounter.h b/include/bc/beancounter.h
index 6d5505212c85..340d09727baa 100644
--- a/include/bc/beancounter.h
+++ b/include/bc/beancounter.h
@@ -317,6 +317,7 @@ extern void ub_sync_memcg(struct user_beancounter *ub);
 extern void ub_page_stat(struct user_beancounter *ub,
 			 const nodemask_t *nodemask,
 			 unsigned long *pages);
+extern unsigned long ub_total_pages(struct user_beancounter *ub, bool swap);
 
 extern const char *ub_rnames[];
 /*
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 4980f9f16d6f..661e60c13eea 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -127,7 +127,6 @@ 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_total_pages(bool swap);
 
 #ifdef CONFIG_MEMCG_SWAP
 extern int do_swap_account;
@@ -401,11 +400,6 @@ static inline void mem_cgroup_replace_page_cache(struct page *oldpage,
 				struct page *newpage)
 {
 }
-
-static inline unsigned long mem_cgroup_total_pages(swap)
-{
-	return ULONG_MAX;
-}
 #endif /* CONFIG_MEMCG */
 
 #if !defined(CONFIG_MEMCG) || !defined(CONFIG_DEBUG_VM)
diff --git a/kernel/bc/beancounter.c b/kernel/bc/beancounter.c
index 7d20f734fad4..81f5518d3340 100644
--- a/kernel/bc/beancounter.c
+++ b/kernel/bc/beancounter.c
@@ -216,6 +216,8 @@ extern int mem_cgroup_apply_beancounter(struct mem_cgroup *memcg,
 					struct user_beancounter *ub);
 extern void mem_cgroup_get_nr_pages(struct mem_cgroup *memcg, int nid,
 				    unsigned long *pages);
+extern unsigned long mem_cgroup_total_pages(struct mem_cgroup *memcg,
+					    bool swap);
 
 /*
  * Update memcg limits according to beancounter configuration.
@@ -259,6 +261,17 @@ void ub_page_stat(struct user_beancounter *ub, const nodemask_t *nodemask,
 	css_put(css);
 }
 
+unsigned long ub_total_pages(struct user_beancounter *ub, bool swap)
+{
+	struct cgroup_subsys_state *css;
+	unsigned long ret;
+
+	css = ub_get_mem_css(ub);
+	ret = mem_cgroup_total_pages(mem_cgroup_from_cont(css->cgroup), swap);
+	css_put(css);
+	return ret;
+}
+
 void init_beancounter_precharge(struct user_beancounter *ub, int resource)
 {
 	/* limit maximum precharge with one half of current resource excess */
diff --git a/kernel/bc/io_acct.c b/kernel/bc/io_acct.c
index 50f8fb781703..db3926d2827f 100644
--- a/kernel/bc/io_acct.c
+++ b/kernel/bc/io_acct.c
@@ -135,7 +135,7 @@ int ub_dirty_limits(unsigned long *pbackground,
 	if (!dirty_ratio)
 		return 0;
 
-	available_memory = mem_cgroup_total_pages(false);
+	available_memory = ub_total_pages(ub, false);
 	if (available_memory == ULONG_MAX || available_memory == 0)
 		return 0;
 
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6beded785d39..0efcc57b9bae 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1630,36 +1630,12 @@ 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().
- *
- * If @swap is true, this function returns the total number of memory + swap
- * pages available.
- */
-unsigned long mem_cgroup_total_pages(bool swap)
+unsigned long mem_cgroup_total_pages(struct mem_cgroup *memcg, bool swap)
 {
-	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;
+	unsigned long long limit;
 
 	limit = swap ? res_counter_read_u64(&memcg->memsw, RES_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);
diff --git a/mm/shmem.c b/mm/shmem.c
index 88a6552775c0..11426378afa3 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -106,13 +106,12 @@ enum sgp_type {
 #ifdef CONFIG_TMPFS
 static unsigned long tmpfs_ram_pages(void)
 {
-	unsigned long memcg_rampages;
+	struct user_beancounter *ub = get_exec_ub();
 
-	if (ve_is_super(get_exec_env()))
+	if (ub == get_ub0())
 		return totalram_pages;
 
-	memcg_rampages = mem_cgroup_total_pages(false);
-	return min(totalram_pages, memcg_rampages);
+	return min(totalram_pages, ub_total_pages(ub, false));
 }
 
 static unsigned long shmem_default_max_blocks(void)
-- 
2.1.4




More information about the Devel mailing list