770 lines · 22.2 KB · C
RawDownload
/* *  linux/mm/oom_kill.c *  *  Copyright (C)  1998,2000  Rik van Riel *	Thanks go out to Claus Fischer for some serious inspiration and *	for goading me into coding this file... *  Copyright (C)  2010  Google, Inc. *	Rewritten by David Rientjes * *  The routines in this file are used to kill a process when *  we're seriously out of memory. This gets called from __alloc_pages() *  in mm/page_alloc.c when we really run out of memory. * *  Since we won't call these routines often (on a well-configured *  machine) this file will double as a 'coding guide' and a signpost *  for newbie kernel hackers. It features several pointers to major *  kernel subsystems and hints as to where to find out what things do. */ #include <linux/oom.h>#include <linux/mm.h>#include <linux/err.h>#include <linux/gfp.h>#include <linux/sched.h>#include <linux/swap.h>#include <linux/timex.h>#include <linux/jiffies.h>#include <linux/cpuset.h>#include <linux/export.h>#include <linux/notifier.h>#include <linux/memcontrol.h>#include <linux/mempolicy.h>#include <linux/security.h>#include <linux/ptrace.h>#include <linux/freezer.h>#include <linux/ftrace.h>#include <linux/ratelimit.h> #define CREATE_TRACE_POINTS#include <trace/events/oom.h> int sysctl_panic_on_oom;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(int old_val, int 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. */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;	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 * @tsk: task struct of which task to consider * @mask: nodemask passed to page allocator for mempolicy ooms * * Task eligibility is determined by whether or not a candidate task, @tsk, * shares the same mempolicy nodes as current if it is bound by such a policy * and whether or not it has the same set of allowed cpuset nodes. */static bool has_intersects_mems_allowed(struct task_struct *tsk,					const nodemask_t *mask){	struct task_struct *start = tsk; 	do {		if (mask) {			/*			 * If this is a mempolicy constrained oom, tsk's			 * cpuset is irrelevant.  Only return true if its			 * mempolicy intersects current, otherwise it may be			 * needlessly killed.			 */			if (mempolicy_nodemask_intersects(tsk, mask))				return true;		} else {			/*			 * This is not a mempolicy constrained oom, so only			 * check the mems of tsk's cpuset.			 */			if (cpuset_mems_allowed_intersects(current, tsk))				return true;		}	} while_each_thread(start, tsk); 	return false;}#elsestatic bool has_intersects_mems_allowed(struct task_struct *tsk,					const nodemask_t *mask){	return true;}#endif /* CONFIG_NUMA */ /* * The process p may have detached its own ->mm while exiting or through * use_mm(), but one or more of its subthreads may still have a valid * pointer.  Return p, or any of its subthreads with a valid ->mm, with * task_lock() held. */struct task_struct *find_lock_task_mm(struct task_struct *p){	struct task_struct *t = p; 	do {		task_lock(t);		if (likely(t->mm))			return t;		task_unlock(t);	} while_each_thread(p, t); 	return NULL;} /* return true if the task is not adequate as candidate victim task. */static bool oom_unkillable_task(struct task_struct *p,		const struct mem_cgroup *memcg, const nodemask_t *nodemask){	if (is_global_init(p))		return true;	if (p->flags & PF_KTHREAD)		return true; 	/* When mem_cgroup_out_of_memory() and p is not member of the group */	if (memcg && !task_in_mem_cgroup(p, memcg))		return true; 	/* p may not have freeable memory in nodemask */	if (!has_intersects_mems_allowed(p, nodemask))		return true; 	return false;} /** * oom_badness - heuristic function to determine which candidate task to kill * @p: task struct of which task we should calculate * @totalpages: total present RAM allowed for page allocation * * The heuristic for determining which task to kill is made to be as simple and * predictable as possible.  The goal is to return the highest value for the * task consuming the most memory to avoid subsequent oom failures. */unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,			  const nodemask_t *nodemask, unsigned long totalpages){	long points; 	if (oom_unkillable_task(p, memcg, nodemask))		return 0; 	p = find_lock_task_mm(p);	if (!p)		return 0; 	if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) {		task_unlock(p);		return 0;	} 	/*	 * 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 +		 get_mm_counter(p->mm, MM_SWAPENTS);	task_unlock(p); 	/*	 * Root processes get 3% bonus, just like the __vm_enough_memory()	 * implementation used by LSMs.	 */	if (has_capability_noaudit(p, CAP_SYS_ADMIN))		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 * totalpages / 1000; 	/*	 * 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).	 */	return points > 0 ? points : 1;} /* * Determine the type of allocation constraint. */#ifdef CONFIG_NUMAstatic enum oom_constraint constrained_alloc(struct zonelist *zonelist,				gfp_t gfp_mask, nodemask_t *nodemask,				unsigned long *totalpages){	struct zone *zone;	struct zoneref *z;	enum zone_type high_zoneidx = gfp_zone(gfp_mask);	bool cpuset_limited = false;	int nid; 	/* Default to all available memory */	*totalpages = totalram_pages + total_swap_pages; 	if (!zonelist)		return CONSTRAINT_NONE;	/*	 * Reach here only when __GFP_NOFAIL is used. So, we should avoid	 * to kill current.We have to random task kill in this case.	 * Hopefully, CONSTRAINT_THISNODE...but no way to handle it, now.	 */	if (gfp_mask & __GFP_THISNODE)		return CONSTRAINT_NONE; 	/*	 * This is not a __GFP_THISNODE allocation, so a truncated nodemask in	 * the page allocator means a mempolicy is in effect.  Cpuset policy	 * is enforced in get_page_from_freelist().	 */	if (nodemask && !nodes_subset(node_states[N_HIGH_MEMORY], *nodemask)) {		*totalpages = total_swap_pages;		for_each_node_mask(nid, *nodemask)			*totalpages += node_spanned_pages(nid);		return CONSTRAINT_MEMORY_POLICY;	} 	/* Check this allocation failure is caused by cpuset's wall function */	for_each_zone_zonelist_nodemask(zone, z, zonelist,			high_zoneidx, nodemask)		if (!cpuset_zone_allowed_softwall(zone, gfp_mask))			cpuset_limited = true; 	if (cpuset_limited) {		*totalpages = total_swap_pages;		for_each_node_mask(nid, cpuset_current_mems_allowed)			*totalpages += node_spanned_pages(nid);		return CONSTRAINT_CPUSET;	}	return CONSTRAINT_NONE;}#elsestatic enum oom_constraint constrained_alloc(struct zonelist *zonelist,				gfp_t gfp_mask, nodemask_t *nodemask,				unsigned long *totalpages){	*totalpages = totalram_pages + total_swap_pages;	return CONSTRAINT_NONE;}#endif /* * Simple selection loop. We chose the process with the highest * number of 'points'. We expect the caller will lock the tasklist. * * (not docbooked, we don't want this one cluttering up the manual) */static struct task_struct *select_bad_process(unsigned int *ppoints,		unsigned long totalpages, struct mem_cgroup *memcg,		const nodemask_t *nodemask, bool force_kill){	struct task_struct *g, *p;	struct task_struct *chosen = NULL;	unsigned long chosen_points = 0; 	do_each_thread(g, p) {		unsigned int points; 		if (p->exit_state)			continue;		if (oom_unkillable_task(p, memcg, nodemask))			continue; 		/*		 * This task already has access to memory reserves and is		 * being killed. Don't allow any other task access to the		 * memory reserve.		 *		 * Note: this may have a chance of deadlock if it gets		 * blocked waiting for another task which itself is waiting		 * for memory. Is there a better alternative?		 */		if (test_tsk_thread_flag(p, TIF_MEMDIE)) {			if (unlikely(frozen(p)))				__thaw_task(p);			if (!force_kill)				return ERR_PTR(-1UL);		}		if (!p->mm)			continue; 		if (p->flags & PF_EXITING) {			/*			 * If p is the current task and is in the process of			 * releasing memory, we allow the "kill" to set			 * TIF_MEMDIE, which will allow it to gain access to			 * memory reserves.  Otherwise, it may stall forever.			 *			 * The loop isn't broken here, however, in case other			 * threads are found to have already been oom killed.			 */			if (p == current) {				chosen = p;				chosen_points = ULONG_MAX;			} else if (!force_kill) {				/*				 * If this task is not being ptraced on exit,				 * then wait for it to finish before killing				 * some other task unnecessarily.				 */				if (!(p->group_leader->ptrace & PT_TRACE_EXIT))					return ERR_PTR(-1UL);			}		} 		points = oom_badness(p, memcg, nodemask, totalpages);		if (points > chosen_points) {			chosen = p;			chosen_points = points;		}	} while_each_thread(g, p); 	*ppoints = chosen_points * 1000 / totalpages;	return chosen;} /** * dump_tasks - dump current memory state of all system tasks * @mem: current's memory controller, if constrained * @nodemask: nodemask passed to page allocator for mempolicy ooms * * Dumps the current memory state of all eligible tasks.  Tasks not in the same * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes * are not shown. * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj * value, oom_score_adj value, and name. * * Call with tasklist_lock read-locked. */static void dump_tasks(const struct mem_cgroup *memcg, const nodemask_t *nodemask){	struct task_struct *p;	struct task_struct *task; 	pr_info("[ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name\n");	for_each_process(p) {		if (oom_unkillable_task(p, memcg, nodemask))			continue; 		task = find_lock_task_mm(p);		if (!task) {			/*			 * This is a kthread or all of p's threads have already			 * detached their mm's.  There's no need to report			 * them; they can't be oom killed anyway.			 */			continue;		} 		pr_info("[%5d] %5d %5d %8lu %8lu %3u     %3d         %5d %s\n",			task->pid, from_kuid(&init_user_ns, task_uid(task)),			task->tgid, task->mm->total_vm, get_mm_rss(task->mm),			task_cpu(task), task->signal->oom_adj,			task->signal->oom_score_adj, task->comm);		task_unlock(task);	}} static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,			struct mem_cgroup *memcg, const nodemask_t *nodemask){	task_lock(current);	pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "		"oom_adj=%d, oom_score_adj=%d\n",		current->comm, gfp_mask, order, current->signal->oom_adj,		current->signal->oom_score_adj);	cpuset_print_task_mems_allowed(current);	task_unlock(current);	dump_stack();	mem_cgroup_print_oom_info(memcg, p);	show_mem(SHOW_MEM_FILTER_NODES);	if (sysctl_oom_dump_tasks)		dump_tasks(memcg, nodemask);} #define K(x) ((x) << (PAGE_SHIFT-10))static void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,			     unsigned int points, unsigned long totalpages,			     struct mem_cgroup *memcg, nodemask_t *nodemask,			     const char *message){	struct task_struct *victim = p;	struct task_struct *child;	struct task_struct *t = p;	struct mm_struct *mm;	unsigned int victim_points = 0;	static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL,					      DEFAULT_RATELIMIT_BURST); 	/*	 * If the task is already exiting, don't alarm the sysadmin or kill	 * its children or threads, just set TIF_MEMDIE so it can die quickly	 */	if (p->flags & PF_EXITING) {		set_tsk_thread_flag(p, TIF_MEMDIE);		return;	} 	if (__ratelimit(&oom_rs))		dump_header(p, gfp_mask, order, memcg, nodemask); 	task_lock(p);	pr_err("%s: Kill process %d (%s) score %d or sacrifice child\n",		message, task_pid_nr(p), p->comm, points);	task_unlock(p); 	/*	 * If any of p's children has a different mm and is eligible for kill,	 * the one with the highest oom_badness() score is sacrificed for its	 * parent.  This attempts to lose the minimal amount of work done while	 * still freeing memory.	 */	do {		list_for_each_entry(child, &t->children, sibling) {			unsigned int child_points; 			if (child->mm == p->mm)				continue;			/*			 * oom_badness() returns 0 if the thread is unkillable			 */			child_points = oom_badness(child, memcg, nodemask,								totalpages);			if (child_points > victim_points) {				victim = child;				victim_points = child_points;			}		}	} while_each_thread(p, t); 	victim = find_lock_task_mm(victim);	if (!victim)		return; 	/* mm cannot safely be dereferenced after task_unlock(victim) */	mm = victim->mm;	pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",		task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),		K(get_mm_counter(victim->mm, MM_ANONPAGES)),		K(get_mm_counter(victim->mm, MM_FILEPAGES)));	task_unlock(victim); 	/*	 * Kill all user processes sharing victim->mm in other thread groups, if	 * any.  They don't get access to memory reserves, though, to avoid	 * depletion of all memory.  This prevents mm->mmap_sem livelock when an	 * oom killed thread cannot exit because it requires the semaphore and	 * its contended by another thread trying to allocate memory itself.	 * That thread will now get access to memory reserves since it has a	 * pending fatal signal.

Lines 1–500 of 770.