[Devel] [PATCH rh7 03/11] ub: simplify memcg synchronization
Vladimir Davydov
vdavydov at parallels.com
Wed May 20 02:00:40 PDT 2015
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 202a5f537cda..e0ef5ec195fa 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 3b5a20f5a4c8..d94fb32cd22c 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 46ea074c182a..02b5cfb0c306 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 b1eedd29e17f..e0e3c4550ceb 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 01a8e5a5cfd5..75add1495418 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)
--
1.7.10.4
More information about the Devel
mailing list