[Devel] [PATCH RHEL7 COMMIT] memcg/bc: account dcache size

Konstantin Khorenko khorenko at virtuozzo.com
Thu May 28 02:52:18 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.7
------>
commit 576fe2ff2d276037282fd791b8cde70b89964130
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Thu May 28 13:52:18 2015 +0400

    memcg/bc: account dcache size
    
    We need to show dcachesize stats in the UB API. Since we need to record
    max usage, we use a plain res_counter instead of going with per cpu
    counters. The following patch will make beancounter pull this value from
    memcg whenever necessary.
    
    Related to https://jira.sw.ru/browse/PSBM-20089
    
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
    Reviewed-by: Cyrill Gorcunov <gorcunov at odin.com>
---
 include/linux/memcontrol.h |  3 ---
 mm/memcontrol.c            | 44 ++++++++++++++++++++++++++++++++++++++++++--
 mm/slab.h                  |  8 +++++---
 3 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 5507be5..f5b3031 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -468,9 +468,6 @@ void __memcg_kmem_put_cache(struct kmem_cache *cachep);
 
 struct mem_cgroup *__mem_cgroup_from_kmem(void *ptr);
 
-int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size);
-void memcg_uncharge_kmem(struct mem_cgroup *memcg, u64 size);
-
 /**
  * memcg_kmem_newpage_charge: verify if a new kmem allocation is allowed.
  * @gfp: the gfp allocation flags.
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 75add14..0a8f816 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -279,6 +279,14 @@ struct mem_cgroup {
 	 */
 	struct res_counter kmem;
 
+	/*
+	 * the counter to account for dcache usage.
+	 *
+	 * Never limited, only needed for showing stats. We could use a per cpu
+	 * counter if we did not have to report max usage.
+	 */
+	struct res_counter dcache;
+
 	/* beancounter-related stats */
 	unsigned long long swap_max;
 	atomic_long_t mem_failcnt;
@@ -3028,7 +3036,7 @@ static int mem_cgroup_slabinfo_read(struct cgroup *cont, struct cftype *cft,
 }
 #endif
 
-int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size)
+static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size)
 {
 	struct res_counter *fail_res;
 	struct mem_cgroup *_memcg;
@@ -3076,7 +3084,7 @@ int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size)
 	return ret;
 }
 
-void memcg_uncharge_kmem(struct mem_cgroup *memcg, u64 size)
+static void memcg_uncharge_kmem(struct mem_cgroup *memcg, u64 size)
 {
 	res_counter_uncharge(&memcg->res, size);
 	if (do_swap_account)
@@ -3098,6 +3106,35 @@ void memcg_uncharge_kmem(struct mem_cgroup *memcg, u64 size)
 		css_put(&memcg->css);
 }
 
+int __memcg_charge_slab(struct kmem_cache *s, gfp_t gfp, unsigned size)
+{
+	struct mem_cgroup *memcg;
+	struct res_counter *fail_res;
+	int ret;
+
+	VM_BUG_ON(is_root_cache(s));
+	memcg = s->memcg_params.memcg;
+
+	ret = memcg_charge_kmem(memcg, gfp, size);
+	if (ret)
+		return ret;
+	if (s->flags & SLAB_RECLAIM_ACCOUNT)
+		res_counter_charge_nofail(&memcg->dcache, size, &fail_res);
+	return 0;
+}
+
+void __memcg_uncharge_slab(struct kmem_cache *s, unsigned size)
+{
+	struct mem_cgroup *memcg;
+
+	VM_BUG_ON(is_root_cache(s));
+	memcg = s->memcg_params.memcg;
+
+	memcg_uncharge_kmem(memcg, size);
+	if (s->flags & SLAB_RECLAIM_ACCOUNT)
+		res_counter_uncharge(&memcg->dcache, size);
+}
+
 /*
  * helper for acessing a memcg's index. It will be used as an index in the
  * child cache array in kmem_cache, and also to derive its name. This function
@@ -6181,6 +6218,7 @@ mem_cgroup_css_alloc(struct cgroup *cont)
 		res_counter_init(&memcg->res, NULL);
 		res_counter_init(&memcg->memsw, NULL);
 		res_counter_init(&memcg->kmem, NULL);
+		res_counter_init(&memcg->dcache, NULL);
 	}
 
 	memcg->last_scanned_node = MAX_NUMNODES;
@@ -6222,6 +6260,7 @@ mem_cgroup_css_online(struct cgroup *cont)
 		res_counter_init(&memcg->res, &parent->res);
 		res_counter_init(&memcg->memsw, &parent->memsw);
 		res_counter_init(&memcg->kmem, &parent->kmem);
+		res_counter_init(&memcg->dcache, &parent->dcache);
 
 		/*
 		 * No need to take a reference to the parent because cgroup
@@ -6231,6 +6270,7 @@ mem_cgroup_css_online(struct cgroup *cont)
 		res_counter_init(&memcg->res, NULL);
 		res_counter_init(&memcg->memsw, NULL);
 		res_counter_init(&memcg->kmem, NULL);
+		res_counter_init(&memcg->dcache, NULL);
 		/*
 		 * Deeper hierachy with use_hierarchy == false doesn't make
 		 * much sense so let cgroup subsystem know about this
diff --git a/mm/slab.h b/mm/slab.h
index 390a0b6..3d1b33e 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -217,6 +217,9 @@ static inline struct kmem_cache *memcg_root_cache(struct kmem_cache *s)
 	return s->memcg_params.root_cache;
 }
 
+extern int __memcg_charge_slab(struct kmem_cache *s, gfp_t gfp, unsigned size);
+extern void __memcg_uncharge_slab(struct kmem_cache *s, unsigned size);
+
 static __always_inline int memcg_charge_slab(struct kmem_cache *s,
 					     gfp_t gfp, int order)
 {
@@ -224,8 +227,7 @@ static __always_inline int memcg_charge_slab(struct kmem_cache *s,
 		return 0;
 	if (is_root_cache(s))
 		return 0;
-	return memcg_charge_kmem(s->memcg_params.memcg, gfp,
-				 PAGE_SIZE << order);
+	return __memcg_charge_slab(s, gfp, PAGE_SIZE << order);
 }
 
 static __always_inline void memcg_uncharge_slab(struct kmem_cache *s, int order)
@@ -234,7 +236,7 @@ static __always_inline void memcg_uncharge_slab(struct kmem_cache *s, int order)
 		return;
 	if (is_root_cache(s))
 		return;
-	memcg_uncharge_kmem(s->memcg_params.memcg, PAGE_SIZE << order);
+	__memcg_uncharge_slab(s, PAGE_SIZE << order);
 }
 
 extern void slab_init_memcg_params(struct kmem_cache *);



More information about the Devel mailing list