[Devel] [PATCH RHEL7 COMMIT] ub: simplify memcg synchronization

Konstantin Khorenko khorenko at virtuozzo.com
Mon May 25 03:27:27 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.5
------>
commit ae16e7f436ae461a50a65f05576109fdad70dbb4
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Mon May 25 14:27:27 2015 +0400

    ub: simplify memcg synchronization
    
    Instead of getting physpages, swappages, and kmemsize stats from memcg
    in the arguments of mem_cgroup_fill_ub_parms, make the latter update the
    corresponding user_beancounter->ub_parms directly, which greatly
    simplifies the code and makes it easier to move more resource types to
    memcg side (think of oomguarpages).
    
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 include/bc/beancounter.h |  5 +----
 kernel/bc/beancounter.c  | 26 +++++++++-----------------
 kernel/bc/proc.c         | 23 ++++-------------------
 kernel/bc/vm_pages.c     | 22 ++++++++++------------
 mm/memcontrol.c          | 20 ++++++++++++--------
 5 files changed, 36 insertions(+), 60 deletions(-)

diff --git a/include/bc/beancounter.h b/include/bc/beancounter.h
index 202a5f5..e0ef5ec 100644
--- a/include/bc/beancounter.h
+++ b/include/bc/beancounter.h
@@ -319,10 +319,7 @@ extern void uncharge_warn(struct user_beancounter *ub, const char *resource,
 
 extern int ub_update_mem_cgroup_limits(struct user_beancounter *ub);
 
-extern void ub_get_mem_cgroup_parms(struct user_beancounter *ub,
-				    struct ubparm *physpages,
-				    struct ubparm *swappages,
-				    struct ubparm *kmemsize);
+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);
diff --git a/kernel/bc/beancounter.c b/kernel/bc/beancounter.c
index 3b5a20f..d94fb32 100644
--- a/kernel/bc/beancounter.c
+++ b/kernel/bc/beancounter.c
@@ -202,31 +202,18 @@ int ub_update_mem_cgroup_limits(struct user_beancounter *ub)
 	return ret;
 }
 
-extern void mem_cgroup_fill_ub_parms(struct cgroup *cg,
-		struct ubparm *p, struct ubparm *s, struct ubparm *k);
+extern void mem_cgroup_sync_beancounter(struct cgroup *cg,
+					struct user_beancounter *ub);
 
-void ub_get_mem_cgroup_parms(struct user_beancounter *ub,
-			     struct ubparm *physpages,
-			     struct ubparm *swappages,
-			     struct ubparm *kmemsize)
+void ub_sync_memcg(struct user_beancounter *ub)
 {
 	struct cgroup *cg;
-	struct ubparm parms[3];
-
-	memset(parms, 0, sizeof(parms));
 
 	cg = ub_cgroup_open(mem_cgroup_root, ub);
 	if (!IS_ERR_OR_NULL(cg)) {
-		mem_cgroup_fill_ub_parms(cg, &parms[0], &parms[1], &parms[2]);
+		mem_cgroup_sync_beancounter(cg, ub);
 		ub_cgroup_close(mem_cgroup_root, cg);
 	}
-
-	if (physpages)
-		*physpages = parms[0];
-	if (swappages)
-		*swappages = parms[1];
-	if (kmemsize)
-		*kmemsize = parms[2];
 }
 
 extern void mem_cgroup_get_nr_pages(struct cgroup *cg, int nid,
@@ -445,6 +432,11 @@ static inline int bc_verify_held(struct user_beancounter *ub)
 	ub_stat_mod(ub, writeback_pages, __ub_percpu_sum(ub, writeback_pages));
 	uncharge_beancounter_precharge(ub);
 
+	/* accounted by memcg */
+	ub->ub_parms[UB_KMEMSIZE].held = 0;
+	ub->ub_parms[UB_PHYSPAGES].held = 0;
+	ub->ub_parms[UB_SWAPPAGES].held = 0;
+
 	clean = 1;
 	for (i = 0; i < UB_RESOURCES; i++)
 		clean &= verify_res(ub, ub_rnames[i], ub->ub_parms[i].held);
diff --git a/kernel/bc/proc.c b/kernel/bc/proc.c
index 46ea074..02b5cfb 100644
--- a/kernel/bc/proc.c
+++ b/kernel/bc/proc.c
@@ -45,27 +45,10 @@ static const char *res_fmt = "%10s%c %-12s %20lu %20lu %20lu %20lu %20lu\n";
 static void ub_show_res(struct seq_file *f, struct user_beancounter *ub,
 		int r, int precharge, int show_uid)
 {
+	struct ubparm *p;
 	unsigned long held;
-	struct ubparm *p, v;
-	bool precharge_valid = false;
-
-	p = &v;
-	switch (r) {
-	case UB_PHYSPAGES:
-		ub_get_mem_cgroup_parms(ub, p, NULL, NULL);
-		break;
-	case UB_SWAPPAGES:
-		ub_get_mem_cgroup_parms(ub, NULL, p, NULL);
-		break;
-	case UB_KMEMSIZE:
-		ub_get_mem_cgroup_parms(ub, NULL, NULL, p);
-		break;
-	default:
-		p = &ub->ub_parms[r];
-		precharge_valid = true;
-		break;
-	}
 
+	p = &ub->ub_parms[r];
 	held = p->held;
 	held = (held > precharge) ? (held - precharge) : 0;
 
@@ -85,6 +68,7 @@ static void __show_resources(struct seq_file *f, struct user_beancounter *ub,
 {
 	int i, precharge[UB_RESOURCES];
 
+	ub_sync_memcg(ub);
 	ub_precharge_snapshot(ub, precharge);
 
 	for (i = 0; i < UB_RESOURCES_COMPAT; i++)
@@ -300,6 +284,7 @@ static int ub_show(struct seq_file *f, void *v)
 	int i, precharge[UB_RESOURCES];
 	struct user_beancounter *ub = v;
 
+	ub_sync_memcg(ub);
 	ub_precharge_snapshot(ub, precharge);
 
 	for (i = 0; i < UB_RESOURCES_COMPAT; i++)
diff --git a/kernel/bc/vm_pages.c b/kernel/bc/vm_pages.c
index b1eedd2..e0e3c45 100644
--- a/kernel/bc/vm_pages.c
+++ b/kernel/bc/vm_pages.c
@@ -140,7 +140,6 @@ static int bc_fill_sysinfo(struct user_beancounter *ub,
 {
 	unsigned long used, total;
 	unsigned long totalram, totalswap;
-	struct ubparm physpages, swappages;
 
 	/* No virtualization */
 	if (meminfo_val == VE_MEMINFO_SYSTEM)
@@ -151,10 +150,10 @@ static int bc_fill_sysinfo(struct user_beancounter *ub,
 
 	memset(si, 0, sizeof(*si));
 
-	ub_get_mem_cgroup_parms(ub, &physpages, &swappages, NULL);
+	ub_sync_memcg(ub);
 
-	total = physpages.limit;
-	used = physpages.held;
+	total = ub->ub_parms[UB_PHYSPAGES].limit;
+	used = ub->ub_parms[UB_PHYSPAGES].held;
 
 	if (total == UB_MAXVALUE)
 		total = totalram;
@@ -162,8 +161,8 @@ static int bc_fill_sysinfo(struct user_beancounter *ub,
 	si->totalram = total;
 	si->freeram = (total > used ? total - used : 0);
 
-	total = swappages.limit;
-	used = swappages.held;
+	total = ub->ub_parms[UB_SWAPPAGES].limit;
+	used = ub->ub_parms[UB_SWAPPAGES].held;
 
 	if (total == UB_MAXVALUE)
 		total = totalswap;
@@ -181,13 +180,12 @@ static int bc_fill_meminfo(struct user_beancounter *ub,
 {
 	int cpu, ret;
 	long dcache;
-	struct ubparm kmemsize;
 
 	ret = bc_fill_sysinfo(ub, meminfo_val, mi->si);
 	if (ret & NOTIFY_STOP_MASK)
 		goto out;
 
-	ub_get_mem_cgroup_parms(ub, NULL, NULL, &kmemsize);
+	ub_sync_memcg(ub);
 	ub_page_stat(ub, &node_online_map, mi->pages);
 
 	mi->cached = min(mi->si->totalram - mi->si->freeram,
@@ -212,7 +210,8 @@ static int bc_fill_meminfo(struct user_beancounter *ub,
 
 	mi->slab_reclaimable = DIV_ROUND_UP(max(0L, dcache), PAGE_SIZE);
 	mi->slab_unreclaimable =
-		DIV_ROUND_UP(max(0L, (long)kmemsize.held - dcache), PAGE_SIZE);
+		DIV_ROUND_UP(max(0L, (long)ub->ub_parms[UB_KMEMSIZE].held -
+							dcache), PAGE_SIZE);
 out:
 	return ret;
 }
@@ -276,12 +275,11 @@ static int bc_vmaux_show(struct seq_file *f, void *v)
 	struct user_beancounter *ub;
 	struct ub_percpu_struct *ub_pcpu;
 	unsigned long swapin, swapout, vswapin, vswapout;
-	struct ubparm physpages;
 	int i;
 
 	ub = seq_beancounter(f);
 
-	ub_get_mem_cgroup_parms(ub, &physpages, NULL, NULL);
+	ub_sync_memcg(ub);
 
 	swapin = swapout = vswapin = vswapout = 0;
 	for_each_possible_cpu(i) {
@@ -301,7 +299,7 @@ static int bc_vmaux_show(struct seq_file *f, void *v)
 	seq_printf(f, bc_proc_lu_fmt, "vswapin", vswapin);
 	seq_printf(f, bc_proc_lu_fmt, "vswapout", vswapout);
 
-	seq_printf(f, bc_proc_lu_fmt, "ram", physpages.held);
+	seq_printf(f, bc_proc_lu_fmt, "ram", ub->ub_parms[UB_PHYSPAGES].held);
 
 	return 0;
 }
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 01a8e5a..75add14 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5152,11 +5152,15 @@ static int mem_cgroup_move_charge_write(struct cgroup *cgrp,
 
 #include <bc/beancounter.h>
 
-void mem_cgroup_fill_ub_parms(struct cgroup *cg,
-		struct ubparm *p, struct ubparm *s, struct ubparm *k)
+void mem_cgroup_sync_beancounter(struct cgroup *cg, struct user_beancounter *ub)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_cont(cg);
-	unsigned long long lim;
+	unsigned long long lim, held, maxheld;
+	volatile struct ubparm *k, *p, *s;
+
+	k = &ub->ub_parms[UB_KMEMSIZE];
+	p = &ub->ub_parms[UB_PHYSPAGES];
+	s = &ub->ub_parms[UB_SWAPPAGES];
 
 	p->held	= res_counter_read_u64(&memcg->res, RES_USAGE) >> PAGE_SHIFT;
 	p->maxheld = res_counter_read_u64(&memcg->res, RES_MAX_USAGE) >> PAGE_SHIFT;
@@ -5174,9 +5178,9 @@ void mem_cgroup_fill_ub_parms(struct cgroup *cg,
 		min_t(unsigned long long, lim, UB_MAXVALUE);
 	k->barrier = k->limit = lim;
 
-	s->held	= res_counter_read_u64(&memcg->memsw, RES_USAGE) >> PAGE_SHIFT;
-	s->held -= p->held;
-	s->maxheld = memcg->swap_max >> PAGE_SHIFT;
+	held = (res_counter_read_u64(&memcg->memsw, RES_USAGE) -
+		res_counter_read_u64(&memcg->res, RES_USAGE)) >> PAGE_SHIFT;
+	maxheld = memcg->swap_max >> PAGE_SHIFT;
 	s->failcnt = atomic_long_read(&memcg->swap_failcnt);
 	lim = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
 	lim = lim == RESOURCE_MAX ? UB_MAXVALUE :
@@ -5187,8 +5191,8 @@ void mem_cgroup_fill_ub_parms(struct cgroup *cg,
 
 	/* Due to global reclaim, memory.memsw.usage can be greater than
 	 * (memory.memsw.limit - memory.limit). */
-	s->held = min(s->held, s->limit);
-	s->maxheld = min(s->maxheld, s->limit);
+	s->held = min(held, lim);
+	s->maxheld = min(maxheld, lim);
 }
 
 int mem_cgroup_apply_beancounter(struct cgroup *cg, struct user_beancounter *ub)



More information about the Devel mailing list