memcg: aggregate memcg cache values in slabinfo
When we create caches in memcgs, we need to display their usage information somewhere. We'll adopt a scheme similar to /proc/meminfo, with aggregate totals shown in the global file, and per-group information stored in the group itself. For the time being, only reads are allowed in the per-group cache. Signed-off-by: Glauber Costa <glommer@parallels.com> Cc: Christoph Lameter <cl@linux.com> Cc: David Rientjes <rientjes@google.com> Cc: Frederic Weisbecker <fweisbec@redhat.com> Cc: Greg Thelen <gthelen@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: JoonSoo Kim <js1304@gmail.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Michal Hocko <mhocko@suse.cz> Cc: Pekka Enberg <penberg@cs.helsinki.fi> Cc: Rik van Riel <riel@redhat.com> Cc: Suleiman Souhlal <suleiman@google.com> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
2293315293
commit
749c54151a
@@ -322,7 +322,7 @@ struct kmem_cache *__init create_kmalloc_cache(const char *name, size_t size,
|
||||
|
||||
|
||||
#ifdef CONFIG_SLABINFO
|
||||
static void print_slabinfo_header(struct seq_file *m)
|
||||
void print_slabinfo_header(struct seq_file *m)
|
||||
{
|
||||
/*
|
||||
* Output format version, so at least we can change it
|
||||
@@ -366,16 +366,43 @@ static void s_stop(struct seq_file *m, void *p)
|
||||
mutex_unlock(&slab_mutex);
|
||||
}
|
||||
|
||||
static int s_show(struct seq_file *m, void *p)
|
||||
static void
|
||||
memcg_accumulate_slabinfo(struct kmem_cache *s, struct slabinfo *info)
|
||||
{
|
||||
struct kmem_cache *c;
|
||||
struct slabinfo sinfo;
|
||||
int i;
|
||||
|
||||
if (!is_root_cache(s))
|
||||
return;
|
||||
|
||||
for_each_memcg_cache_index(i) {
|
||||
c = cache_from_memcg(s, i);
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
memset(&sinfo, 0, sizeof(sinfo));
|
||||
get_slabinfo(c, &sinfo);
|
||||
|
||||
info->active_slabs += sinfo.active_slabs;
|
||||
info->num_slabs += sinfo.num_slabs;
|
||||
info->shared_avail += sinfo.shared_avail;
|
||||
info->active_objs += sinfo.active_objs;
|
||||
info->num_objs += sinfo.num_objs;
|
||||
}
|
||||
}
|
||||
|
||||
int cache_show(struct kmem_cache *s, struct seq_file *m)
|
||||
{
|
||||
struct kmem_cache *s = list_entry(p, struct kmem_cache, list);
|
||||
struct slabinfo sinfo;
|
||||
|
||||
memset(&sinfo, 0, sizeof(sinfo));
|
||||
get_slabinfo(s, &sinfo);
|
||||
|
||||
memcg_accumulate_slabinfo(s, &sinfo);
|
||||
|
||||
seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d",
|
||||
s->name, sinfo.active_objs, sinfo.num_objs, s->size,
|
||||
cache_name(s), sinfo.active_objs, sinfo.num_objs, s->size,
|
||||
sinfo.objects_per_slab, (1 << sinfo.cache_order));
|
||||
|
||||
seq_printf(m, " : tunables %4u %4u %4u",
|
||||
@@ -387,6 +414,15 @@ static int s_show(struct seq_file *m, void *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s_show(struct seq_file *m, void *p)
|
||||
{
|
||||
struct kmem_cache *s = list_entry(p, struct kmem_cache, list);
|
||||
|
||||
if (!is_root_cache(s))
|
||||
return 0;
|
||||
return cache_show(s, m);
|
||||
}
|
||||
|
||||
/*
|
||||
* slabinfo_op - iterator that generates /proc/slabinfo
|
||||
*
|
||||
|
Reference in New Issue
Block a user