diff options
Diffstat (limited to 'mm/oom_kill.c')
| -rw-r--r-- | mm/oom_kill.c | 44 | 
1 files changed, 16 insertions, 28 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 9f09a1fde9f..ed0e1967736 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -180,10 +180,10 @@ static bool oom_unkillable_task(struct task_struct *p,   * predictable as possible.  The goal is to return the highest value for the   * task consuming the most memory to avoid subsequent oom failures.   */ -unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *memcg, -		      const nodemask_t *nodemask, unsigned long totalpages) +unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, +			  const nodemask_t *nodemask, unsigned long totalpages)  { -	long points; +	unsigned long points;  	if (oom_unkillable_task(p, memcg, nodemask))  		return 0; @@ -198,21 +198,11 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *memcg,  	}  	/* -	 * The memory controller may have a limit of 0 bytes, so avoid a divide -	 * by zero, if necessary. -	 */ -	if (!totalpages) -		totalpages = 1; - -	/*  	 * The baseline for the badness score is the proportion of RAM that each  	 * task's rss, pagetable and swap space use.  	 */ -	points = get_mm_rss(p->mm) + p->mm->nr_ptes; -	points += get_mm_counter(p->mm, MM_SWAPENTS); - -	points *= 1000; -	points /= totalpages; +	points = get_mm_rss(p->mm) + p->mm->nr_ptes + +		 get_mm_counter(p->mm, MM_SWAPENTS);  	task_unlock(p);  	/* @@ -220,23 +210,20 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *memcg,  	 * implementation used by LSMs.  	 */  	if (has_capability_noaudit(p, CAP_SYS_ADMIN)) -		points -= 30; +		points -= 30 * totalpages / 1000;  	/*  	 * /proc/pid/oom_score_adj ranges from -1000 to +1000 such that it may  	 * either completely disable oom killing or always prefer a certain  	 * task.  	 */ -	points += p->signal->oom_score_adj; +	points += p->signal->oom_score_adj * totalpages / 1000;  	/* -	 * Never return 0 for an eligible task that may be killed since it's -	 * possible that no single user task uses more than 0.1% of memory and -	 * no single admin tasks uses more than 3.0%. +	 * Never return 0 for an eligible task regardless of the root bonus and +	 * oom_score_adj (oom_score_adj can't be OOM_SCORE_ADJ_MIN here).  	 */ -	if (points <= 0) -		return 1; -	return (points < 1000) ? points : 1000; +	return points ? points : 1;  }  /* @@ -314,7 +301,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,  {  	struct task_struct *g, *p;  	struct task_struct *chosen = NULL; -	*ppoints = 0; +	unsigned long chosen_points = 0;  	do_each_thread(g, p) {  		unsigned int points; @@ -354,7 +341,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,  			 */  			if (p == current) {  				chosen = p; -				*ppoints = 1000; +				chosen_points = ULONG_MAX;  			} else if (!force_kill) {  				/*  				 * If this task is not being ptraced on exit, @@ -367,12 +354,13 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,  		}  		points = oom_badness(p, memcg, nodemask, totalpages); -		if (points > *ppoints) { +		if (points > chosen_points) {  			chosen = p; -			*ppoints = points; +			chosen_points = points;  		}  	} while_each_thread(g, p); +	*ppoints = chosen_points * 1000 / totalpages;  	return chosen;  } @@ -572,7 +560,7 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,  	}  	check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, order, NULL); -	limit = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT; +	limit = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT ? : 1;  	read_lock(&tasklist_lock);  	p = select_bad_process(&points, limit, memcg, NULL, false);  	if (p && PTR_ERR(p) != -1UL)  |