Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 338781
b: refs/heads/master
c: e1e12d2
h: refs/heads/master
i:
  338779: 9cea27d
v: v3
  • Loading branch information
David Rientjes authored and Linus Torvalds committed Dec 12, 2012
1 parent bac2af6 commit fd1d004
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a9c58b907dbc6821533dfc295b63caf111ff1f16
refs/heads/master: e1e12d2f3104be886073ac6c5c4678f30b1b9e51
19 changes: 17 additions & 2 deletions trunk/include/linux/oom.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,23 @@ enum oom_scan_t {
OOM_SCAN_SELECT, /* always select this thread first */
};

extern void compare_swap_oom_score_adj(short old_val, short new_val);
extern short test_set_oom_score_adj(short new_val);
/* Thread is the potential origin of an oom condition; kill first on oom */
#define OOM_FLAG_ORIGIN ((__force oom_flags_t)0x1)

static inline void set_current_oom_origin(void)
{
current->signal->oom_flags |= OOM_FLAG_ORIGIN;
}

static inline void clear_current_oom_origin(void)
{
current->signal->oom_flags &= ~OOM_FLAG_ORIGIN;
}

static inline bool oom_task_origin(const struct task_struct *p)
{
return !!(p->signal->oom_flags & OOM_FLAG_ORIGIN);
}

extern unsigned long oom_badness(struct task_struct *p,
struct mem_cgroup *memcg, const nodemask_t *nodemask,
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,7 @@ struct signal_struct {
struct rw_semaphore group_rwsem;
#endif

oom_flags_t oom_flags;
short oom_score_adj; /* OOM kill score adjustment */
short oom_score_adj_min; /* OOM kill score adjustment min value.
* Only settable by CAP_SYS_RESOURCE. */
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ typedef u32 dma_addr_t;
#endif
typedef unsigned __bitwise__ gfp_t;
typedef unsigned __bitwise__ fmode_t;
typedef unsigned __bitwise__ oom_flags_t;

#ifdef CONFIG_PHYS_ADDR_T_64BIT
typedef u64 phys_addr_t;
Expand Down
7 changes: 2 additions & 5 deletions trunk/mm/ksm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1919,12 +1919,9 @@ static ssize_t run_store(struct kobject *kobj, struct kobj_attribute *attr,
if (ksm_run != flags) {
ksm_run = flags;
if (flags & KSM_RUN_UNMERGE) {
short oom_score_adj;

oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX);
set_current_oom_origin();
err = unmerge_and_remove_all_rmap_items();
compare_swap_oom_score_adj(OOM_SCORE_ADJ_MAX,
oom_score_adj);
clear_current_oom_origin();
if (err) {
ksm_run = KSM_RUN_STOP;
count = err;
Expand Down
49 changes: 7 additions & 42 deletions trunk/mm/oom_kill.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,48 +44,6 @@ int sysctl_oom_kill_allocating_task;
int sysctl_oom_dump_tasks = 1;
static DEFINE_SPINLOCK(zone_scan_lock);

/*
* compare_swap_oom_score_adj() - compare and swap current's oom_score_adj
* @old_val: old oom_score_adj for compare
* @new_val: new oom_score_adj for swap
*
* Sets the oom_score_adj value for current to @new_val iff its present value is
* @old_val. Usually used to reinstate a previous value to prevent racing with
* userspacing tuning the value in the interim.
*/
void compare_swap_oom_score_adj(short old_val, short new_val)
{
struct sighand_struct *sighand = current->sighand;

spin_lock_irq(&sighand->siglock);
if (current->signal->oom_score_adj == old_val)
current->signal->oom_score_adj = new_val;
trace_oom_score_adj_update(current);
spin_unlock_irq(&sighand->siglock);
}

/**
* 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.
*/
short test_set_oom_score_adj(short new_val)
{
struct sighand_struct *sighand = current->sighand;
int old_val;

spin_lock_irq(&sighand->siglock);
old_val = current->signal->oom_score_adj;
current->signal->oom_score_adj = new_val;
trace_oom_score_adj_update(current);
spin_unlock_irq(&sighand->siglock);

return old_val;
}

#ifdef CONFIG_NUMA
/**
* has_intersects_mems_allowed() - check task eligiblity for kill
Expand Down Expand Up @@ -310,6 +268,13 @@ enum oom_scan_t oom_scan_process_thread(struct task_struct *task,
if (!task->mm)
return OOM_SCAN_CONTINUE;

/*
* If task is allocating a lot of memory and has been marked to be
* killed first if it triggers an oom, then select it.
*/
if (oom_task_origin(task))
return OOM_SCAN_SELECT;

if (task->flags & PF_EXITING && !force_kill) {
/*
* If this task is not being ptraced on exit, then wait for it
Expand Down
5 changes: 2 additions & 3 deletions trunk/mm/swapfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,6 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
struct address_space *mapping;
struct inode *inode;
struct filename *pathname;
short oom_score_adj;
int i, type, prev;
int err;

Expand Down Expand Up @@ -1557,9 +1556,9 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
p->flags &= ~SWP_WRITEOK;
spin_unlock(&swap_lock);

oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX);
set_current_oom_origin();
err = try_to_unuse(type, false, 0); /* force all pages to be unused */
compare_swap_oom_score_adj(OOM_SCORE_ADJ_MAX, oom_score_adj);
clear_current_oom_origin();

if (err) {
/* re-insert swap space back into swap_list */
Expand Down

0 comments on commit fd1d004

Please sign in to comment.