[Devel] [PATCH rh7 1/2] memcg: account dcache size
Vladimir Davydov
vdavydov at parallels.com
Fri May 22 04:08:24 PDT 2015
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.
Signed-off-by: Vladimir Davydov <vdavydov at parallels.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 1382e4939a21..d434d6c2cf27 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -487,9 +487,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 d8f9b5561222..1871108bba17 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;
@@ -3140,7 +3148,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;
@@ -3188,7 +3196,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)
@@ -3210,6 +3218,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
@@ -6345,6 +6382,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;
@@ -6386,6 +6424,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
@@ -6395,6 +6434,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 390a0b6f3760..3d1b33ec732b 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 *);
--
1.7.10.4
More information about the Devel
mailing list