From 9217f6db08e9a634a42265f5934dd1e38e8eca69 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 24 May 2011 17:11:40 -0700 Subject: [PATCH] --- yaml --- r: 250877 b: refs/heads/master c: 72788c385604523422592249c19cba0187021e9b h: refs/heads/master i: 250875: a40ad80af3970faae6edf30da77a7e2eead4b2da v: v3 --- [refs] | 2 +- trunk/include/linux/oom.h | 2 ++ trunk/include/linux/sched.h | 1 - trunk/mm/ksm.c | 7 +++++-- trunk/mm/oom_kill.c | 36 +++++++++++++++++++++++++++--------- trunk/mm/swapfile.c | 6 ++++-- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index c82af492d62e..0a24618f4287 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c6a140bf164829769499b5e50d380893da39b29e +refs/heads/master: 72788c385604523422592249c19cba0187021e9b diff --git a/trunk/include/linux/oom.h b/trunk/include/linux/oom.h index 5e3aa8311c5e..4952fb874ad3 100644 --- a/trunk/include/linux/oom.h +++ b/trunk/include/linux/oom.h @@ -40,6 +40,8 @@ enum oom_constraint { CONSTRAINT_MEMCG, }; +extern int test_set_oom_score_adj(int new_val); + extern unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, const nodemask_t *nodemask, unsigned long totalpages); extern int try_set_zonelist_oom(struct zonelist *zonelist, gfp_t gfp_flags); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index aaf71e08222c..44b8faaac7c0 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1753,7 +1753,6 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define PF_FROZEN 0x00010000 /* frozen for system suspend */ #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000 /* I am kswapd */ -#define PF_OOM_ORIGIN 0x00080000 /* Allocating much memory to others */ #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ diff --git a/trunk/mm/ksm.c b/trunk/mm/ksm.c index 942dfc73a2ff..d708b3ef2260 100644 --- a/trunk/mm/ksm.c +++ b/trunk/mm/ksm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -1894,9 +1895,11 @@ static ssize_t run_store(struct kobject *kobj, struct kobj_attribute *attr, if (ksm_run != flags) { ksm_run = flags; if (flags & KSM_RUN_UNMERGE) { - current->flags |= PF_OOM_ORIGIN; + int oom_score_adj; + + oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX); err = unmerge_and_remove_all_rmap_items(); - current->flags &= ~PF_OOM_ORIGIN; + test_set_oom_score_adj(oom_score_adj); if (err) { ksm_run = KSM_RUN_STOP; count = err; diff --git a/trunk/mm/oom_kill.c b/trunk/mm/oom_kill.c index f52e85c80e8d..e4b0991ca351 100644 --- a/trunk/mm/oom_kill.c +++ b/trunk/mm/oom_kill.c @@ -38,6 +38,33 @@ int sysctl_oom_kill_allocating_task; int sysctl_oom_dump_tasks = 1; static DEFINE_SPINLOCK(zone_scan_lock); +/** + * test_set_oom_score_adj() - set current's oom_score_adj and return old value + * @new_val: new oom_score_adj value + * + * Sets the oom_score_adj value for current to @new_val with proper + * synchronization and returns the old value. Usually used to temporarily + * set a value, save the old value in the caller, and then reinstate it later. + */ +int test_set_oom_score_adj(int new_val) +{ + struct sighand_struct *sighand = current->sighand; + int old_val; + + spin_lock_irq(&sighand->siglock); + old_val = current->signal->oom_score_adj; + if (new_val != old_val) { + if (new_val == OOM_SCORE_ADJ_MIN) + atomic_inc(¤t->mm->oom_disable_count); + else if (old_val == OOM_SCORE_ADJ_MIN) + atomic_dec(¤t->mm->oom_disable_count); + current->signal->oom_score_adj = new_val; + } + spin_unlock_irq(&sighand->siglock); + + return old_val; +} + #ifdef CONFIG_NUMA /** * has_intersects_mems_allowed() - check task eligiblity for kill @@ -154,15 +181,6 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, return 0; } - /* - * When the PF_OOM_ORIGIN bit is set, it indicates the task should have - * priority for oom killing. - */ - if (p->flags & PF_OOM_ORIGIN) { - task_unlock(p); - return 1000; - } - /* * The memory controller may have a limit of 0 bytes, so avoid a divide * by zero, if necessary. diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index 8c6b3ce38f09..d537d29e9b7b 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -1555,6 +1556,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) struct address_space *mapping; struct inode *inode; char *pathname; + int oom_score_adj; int i, type, prev; int err; @@ -1613,9 +1615,9 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) p->flags &= ~SWP_WRITEOK; spin_unlock(&swap_lock); - current->flags |= PF_OOM_ORIGIN; + oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX); err = try_to_unuse(type); - current->flags &= ~PF_OOM_ORIGIN; + test_set_oom_score_adj(oom_score_adj); if (err) { /*