[RFC][PATCH 7/7] tracing/mm: add memcg field

From: Wu Fengguang
Date: Sun Aug 28 2011 - 23:57:39 EST


Dump the memcg id associated with a pagecache page.

The downside is, the page_memcg_id() is a pretty heavy weight function
that needs to lock/unlock the page..

CC: Balbir Singh <balbir@xxxxxxxxxxxxxxxxxx>
CC: Daisuke Nishimura <nishimura@xxxxxxxxxxxxxxxxx>
CC: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx>
Signed-off-by: Wu Fengguang <fengguang.wu@xxxxxxxxx>
---
include/linux/memcontrol.h | 6 ++++++
include/trace/events/mm.h | 16 +++++++++++-----
kernel/trace/trace_mm.c | 12 +++++++++---
mm/memcontrol.c | 18 ++++++++++++++++++
4 files changed, 44 insertions(+), 8 deletions(-)

--- linux-mmotm.orig/include/linux/memcontrol.h 2011-08-29 10:55:48.000000000 +0800
+++ linux-mmotm/include/linux/memcontrol.h 2011-08-29 10:55:53.000000000 +0800
@@ -91,6 +91,7 @@ extern void mem_cgroup_uncharge_cache_pa
extern void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask);
int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *memcg);

+extern unsigned short page_memcg_id(struct page *page);
extern struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page);
extern struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p);
extern struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm);
@@ -199,6 +200,11 @@ static inline int mem_cgroup_try_charge_
return 0;
}

+static inline unsigned short page_memcg_id(struct page *page)
+{
+ return 0;
+}
+
static inline void mem_cgroup_commit_charge_swapin(struct page *page,
struct mem_cgroup *ptr)
{
--- linux-mmotm.orig/mm/memcontrol.c 2011-08-29 10:55:48.000000000 +0800
+++ linux-mmotm/mm/memcontrol.c 2011-08-29 10:59:28.000000000 +0800
@@ -591,6 +591,24 @@ mem_cgroup_largest_soft_limit_node(struc
return mz;
}

+unsigned short page_memcg_id(struct page *page)
+{
+ struct mem_cgroup *memcg;
+ struct cgroup_subsys_state *css;
+ unsigned short id = 0;
+
+ lock_page(page);
+ memcg = try_get_mem_cgroup_from_page(page);
+ if (memcg) {
+ css = mem_cgroup_css(memcg);
+ id = css_id(css);
+ css_put(css);
+ }
+ unlock_page(page);
+
+ return id;
+}
+
/*
* Implementation Note: reading percpu statistics for memcg.
*
--- linux-mmotm.orig/include/trace/events/mm.h 2011-08-29 10:55:52.000000000 +0800
+++ linux-mmotm/include/trace/events/mm.h 2011-08-29 10:55:53.000000000 +0800
@@ -34,6 +34,7 @@ TRACE_EVENT(dump_page_frame,
__field( unsigned long, flags )
__field( unsigned int, count )
__field( unsigned int, mapcount )
+ __field( unsigned int, memcg )
__field( unsigned long, private )
__field( unsigned long, mapping )
__field( unsigned long, index )
@@ -46,17 +47,19 @@ TRACE_EVENT(dump_page_frame,
__entry->flags = page->flags;
__entry->count = atomic_read(&page->_count);
__entry->mapcount = page_mapcount(page);
+ __entry->memcg = page_memcg_id(page);
__entry->private = page->private;
__entry->mapping = (unsigned long)page->mapping;
__entry->index = page->index;
),

TP_printk("pfn=%lu page=%p count=%u mapcount=%u "
- "private=%lx mapping=%lx index=%lx flags=%s",
+ "memcg=%u private=%lx mapping=%lx index=%lx flags=%s",
__entry->pfn,
__entry->page,
__entry->count,
__entry->mapcount,
+ __entry->memcg,
__entry->private,
__entry->mapping,
__entry->index,
@@ -68,9 +71,9 @@ TRACE_EVENT(dump_page_frame,

TRACE_EVENT(dump_page_cache,

- TP_PROTO(struct page *page, unsigned long len),
+ TP_PROTO(struct page *page, unsigned long len, unsigned int memcg),

- TP_ARGS(page, len),
+ TP_ARGS(page, len, memcg),

TP_STRUCT__entry(
__field( unsigned long, index )
@@ -78,6 +81,7 @@ TRACE_EVENT(dump_page_cache,
__field( u64, flags )
__field( unsigned int, count )
__field( unsigned int, mapcount )
+ __field( unsigned int, memcg )
),

TP_fast_assign(
@@ -86,10 +90,11 @@ TRACE_EVENT(dump_page_cache,
__entry->flags = stable_page_flags(page);
__entry->count = atomic_read(&page->_count);
__entry->mapcount = page_mapcount(page);
+ __entry->memcg = memcg;
),

TP_printk("index=%lu len=%lu flags=%c%c%c%c%c%c%c%c%c%c%c "
- "count=%u mapcount=%u",
+ "count=%u mapcount=%u memcg=%u",
__entry->index,
__entry->len,
__entry->flags & (1ULL << KPF_MMAP) ? 'M' : '_',
@@ -104,7 +109,8 @@ TRACE_EVENT(dump_page_cache,
__entry->flags & (1ULL << KPF_MAPPEDTODISK) ? 'd' : '_',
__entry->flags & (1ULL << KPF_PRIVATE) ? 'P' : '_',
__entry->count,
- __entry->mapcount)
+ __entry->mapcount,
+ __entry->memcg)
);


--- linux-mmotm.orig/kernel/trace/trace_mm.c 2011-08-29 10:56:02.000000000 +0800
+++ linux-mmotm/kernel/trace/trace_mm.c 2011-08-29 11:01:04.000000000 +0800
@@ -155,6 +155,8 @@ static void dump_pagecache(struct addres
struct page *page;
unsigned long start = 0;
unsigned long len = 0;
+ unsigned int memcg0;
+ unsigned int memcg;
int i;

for (;;) {
@@ -165,23 +167,27 @@ static void dump_pagecache(struct addres

if (nr_pages == 0) {
if (len)
- trace_dump_page_cache(page0, len);
+ trace_dump_page_cache(page0, len, memcg0);
return;
}

for (i = 0; i < nr_pages; i++) {
page = pages[i];
+ memcg = page_memcg_id(page);

if (len &&
page->index == start + len &&
- pages_similar(page0, page))
+ pages_similar(page0, page) &&
+ memcg0 == memcg)
len++;
else {
if (len)
- trace_dump_page_cache(page0, len);
+ trace_dump_page_cache(page0, len,
+ memcg0);
page0 = page;
start = page->index;
len = 1;
+ memcg0 = memcg;
}
}
cond_resched();


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/