diff -NurpP --minimal linux-2.6.38.4-vs2.3.0.37-rc15/include/linux/memcontrol.h linux-2.6.38.4-vs2.3.0.37-rc15.1/include/linux/memcontrol.h --- linux-2.6.38.4-vs2.3.0.37-rc15/include/linux/memcontrol.h 2011-01-29 02:01:07.000000000 +0100 +++ linux-2.6.38.4-vs2.3.0.37-rc15.1/include/linux/memcontrol.h 2011-04-28 22:35:43.000000000 +0200 @@ -121,6 +121,8 @@ struct zone_reclaim_stat* mem_cgroup_get_reclaim_stat_from_page(struct page *page); extern void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p); +extern void mem_cgroup_oom_cnt(struct mem_cgroup *memcg); +extern void mem_cgroup_oom_kill(struct mem_cgroup *memcg); #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP extern int do_swap_account; @@ -323,6 +325,16 @@ mem_cgroup_print_oom_info(struct mem_cgr { } +static inline void +mem_cgroup_oom_cnt(struct mem_cgroup *memcg) +{ +} + +static inline void +mem_cgroup_oom_kill(struct mem_cgroup *memcg) +{ +} + static inline void mem_cgroup_inc_page_stat(struct page *page, enum mem_cgroup_page_stat_item idx) { diff -NurpP --minimal linux-2.6.38.4-vs2.3.0.37-rc15/mm/memcontrol.c linux-2.6.38.4-vs2.3.0.37-rc15.1/mm/memcontrol.c --- linux-2.6.38.4-vs2.3.0.37-rc15/mm/memcontrol.c 2011-02-17 02:17:51.000000000 +0100 +++ linux-2.6.38.4-vs2.3.0.37-rc15.1/mm/memcontrol.c 2011-04-28 22:33:11.000000000 +0200 @@ -240,6 +240,10 @@ struct mem_cgroup { /* OOM-Killer disable */ int oom_kill_disable; + /* number of OOM kill events */ + unsigned long long oom_cnt; + unsigned long long oom_kill; + /* set when res.limit == memsw.limit */ bool memsw_is_minimum; @@ -4193,6 +4197,52 @@ static int mem_cgroup_oom_control_write( return 0; } +void mem_cgroup_oom_cnt(struct mem_cgroup *memcg) +{ + memcg->oom_cnt++; +} + +static u64 mem_cgroup_oom_cnt_read(struct cgroup *cont, struct cftype *cft) +{ + struct mem_cgroup *mem = mem_cgroup_from_cont(cont); + u64 val; + + val = mem->oom_cnt; + return val; +} + +static int mem_cgroup_oom_cnt_reset(struct cgroup *cont, unsigned int event) +{ + struct mem_cgroup *mem; + + mem = mem_cgroup_from_cont(cont); + mem->oom_cnt = 0; + return 0; +} + +void mem_cgroup_oom_kill(struct mem_cgroup *memcg) +{ + memcg->oom_kill++; +} + +static u64 mem_cgroup_oom_kill_read(struct cgroup *cont, struct cftype *cft) +{ + struct mem_cgroup *mem = mem_cgroup_from_cont(cont); + u64 val; + + val = mem->oom_kill; + return val; +} + +static int mem_cgroup_oom_kill_reset(struct cgroup *cont, unsigned int event) +{ + struct mem_cgroup *mem; + + mem = mem_cgroup_from_cont(cont); + mem->oom_kill = 0; + return 0; +} + static struct cftype mem_cgroup_files[] = { { .name = "usage_in_bytes", @@ -4256,6 +4306,16 @@ static struct cftype mem_cgroup_files[] .unregister_event = mem_cgroup_oom_unregister_event, .private = MEMFILE_PRIVATE(_OOM_TYPE, OOM_CONTROL), }, + { + .name = "oom_cnt", + .read_u64 = mem_cgroup_oom_cnt_read, + .trigger = mem_cgroup_oom_cnt_reset, + }, + { + .name = "oom_kill", + .read_u64 = mem_cgroup_oom_kill_read, + .trigger = mem_cgroup_oom_kill_reset, + }, }; #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP @@ -4494,6 +4554,7 @@ mem_cgroup_create(struct cgroup_subsys * parent = mem_cgroup_from_cont(cont->parent); mem->use_hierarchy = parent->use_hierarchy; mem->oom_kill_disable = parent->oom_kill_disable; + mem->oom_cnt = 0; } if (parent && parent->use_hierarchy) { diff -NurpP --minimal linux-2.6.38.4-vs2.3.0.37-rc15/mm/oom_kill.c linux-2.6.38.4-vs2.3.0.37-rc15.1/mm/oom_kill.c --- linux-2.6.38.4-vs2.3.0.37-rc15/mm/oom_kill.c 2011-04-23 22:33:35.000000000 +0200 +++ linux-2.6.38.4-vs2.3.0.37-rc15.1/mm/oom_kill.c 2011-04-28 22:33:11.000000000 +0200 @@ -545,6 +545,9 @@ void mem_cgroup_out_of_memory(struct mem unsigned int points = 0; struct task_struct *p; + /* increment oom stats */ + mem_cgroup_oom_cnt(mem); + check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0, NULL); limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT; read_lock(&tasklist_lock);