--- linux-2.6.36-vs2.3.0.36.37/include/linux/memcontrol.h 2010-10-21 13:09:36.000000000 +0200 +++ linux-2.6.36-vs2.3.0.36.37.3/include/linux/memcontrol.h 2010-10-28 13:08:41.000000000 +0200 @@ -116,6 +116,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; @@ -300,6 +302,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_update_file_mapped(struct page *page, int val) { --- linux-2.6.36-vs2.3.0.36.37/mm/memcontrol.c 2010-10-21 13:09:36.000000000 +0200 +++ linux-2.6.36-vs2.3.0.36.37.3/mm/memcontrol.c 2010-10-28 13:08:41.000000000 +0200 @@ -230,6 +230,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; @@ -3887,6 +3891,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", @@ -3950,6 +4000,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 @@ -4188,6 +4248,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) { --- linux-2.6.36-vs2.3.0.36.37/mm/oom_kill.c 2010-10-21 14:57:29.000000000 +0200 +++ linux-2.6.36-vs2.3.0.36.37.3/mm/oom_kill.c 2010-10-28 13:13:07.000000000 +0200 @@ -534,6 +534,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);