diff -NurpP --minimal linux-2.6.35.7-vs2.3.0.36.32/include/linux/memcontrol.h linux-2.6.35.7-vs2.3.0.36.32.oom3/include/linux/memcontrol.h --- linux-2.6.35.7-vs2.3.0.36.32/include/linux/memcontrol.h 2010-10-03 17:00:24.000000000 +0200 +++ linux-2.6.35.7-vs2.3.0.36.32.oom3/include/linux/memcontrol.h 2010-10-05 13:19:14.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; @@ -304,6 +306,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) { diff -NurpP --minimal linux-2.6.35.7-vs2.3.0.36.32/mm/memcontrol.c linux-2.6.35.7-vs2.3.0.36.32.oom3/mm/memcontrol.c --- linux-2.6.35.7-vs2.3.0.36.32/mm/memcontrol.c 2010-10-03 17:00:24.000000000 +0200 +++ linux-2.6.35.7-vs2.3.0.36.32.oom3/mm/memcontrol.c 2010-10-05 12:55:51.000000000 +0200 @@ -229,6 +229,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; @@ -3812,6 +3816,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", @@ -3875,6 +3925,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 @@ -4113,6 +4173,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.35.7-vs2.3.0.36.32/mm/oom_kill.c linux-2.6.35.7-vs2.3.0.36.32.oom3/mm/oom_kill.c --- linux-2.6.35.7-vs2.3.0.36.32/mm/oom_kill.c 2010-10-03 17:00:24.000000000 +0200 +++ linux-2.6.35.7-vs2.3.0.36.32.oom3/mm/oom_kill.c 2010-10-05 13:00:18.000000000 +0200 @@ -459,6 +459,7 @@ static int oom_kill_process(struct task_ const char *message) { struct task_struct *c; + int res; if (printk_ratelimit()) dump_header(p, gfp_mask, order, mem); @@ -481,10 +482,18 @@ static int oom_kill_process(struct task_ continue; if (mem && !task_in_mem_cgroup(c, mem)) continue; - if (!oom_kill_task(c)) - return 0; + if (oom_kill_task(c)) + continue; + + mem_cgroup_oom_kill(mem); + return 0; } - return oom_kill_task(p); + + res = oom_kill_task(p); + if (!res) + mem_cgroup_oom_kill(mem); + + return res; } #ifdef CONFIG_CGROUP_MEM_RES_CTLR @@ -501,6 +510,9 @@ retry: if (!p || PTR_ERR(p) == -1UL) goto out; + /* increment oom stats */ + mem_cgroup_oom_cnt(mem); + if (oom_kill_process(p, gfp_mask, 0, points, mem, "Memory cgroup out of memory")) goto retry;