1087 lines · 28.8 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/sched/mm.h>#include <linux/sched/coredump.h>#include <linux/sched/task.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>#include <linux/kthread.h>#include <linux/init.h> #include <asm/tlb.h>#include "internal.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; DEFINE_MUTEX(oom_lock); #ifdef CONFIG_NUMA/** * has_intersects_mems_allowed() - check task eligiblity for kill * @start: 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 *start,					const nodemask_t *mask){	struct task_struct *tsk;	bool ret = false; 	rcu_read_lock();	for_each_thread(start, tsk) {		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.			 */			ret = mempolicy_nodemask_intersects(tsk, mask);		} else {			/*			 * This is not a mempolicy constrained oom, so only			 * check the mems of tsk's cpuset.			 */			ret = cpuset_mems_allowed_intersects(current, tsk);		}		if (ret)			break;	}	rcu_read_unlock(); 	return ret;}#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; 	rcu_read_lock(); 	for_each_thread(p, t) {		task_lock(t);		if (likely(t->mm))			goto found;		task_unlock(t);	}	t = NULL;found:	rcu_read_unlock(); 	return t;} /* * order == -1 means the oom kill is required by sysrq, otherwise only * for display purposes. */static inline bool is_sysrq_oom(struct oom_control *oc){	return oc->order == -1;} static inline bool is_memcg_oom(struct oom_control *oc){	return oc->memcg != NULL;} /* return true if the task is not adequate as candidate victim task. */static bool oom_unkillable_task(struct task_struct *p,		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;	long adj; 	if (oom_unkillable_task(p, memcg, nodemask))		return 0; 	p = find_lock_task_mm(p);	if (!p)		return 0; 	/*	 * Do not even consider tasks which are explicitly marked oom	 * unkillable or have been already oom reaped or the are in	 * the middle of vfork	 */	adj = (long)p->signal->oom_score_adj;	if (adj == OOM_SCORE_ADJ_MIN ||			test_bit(MMF_OOM_SKIP, &p->mm->flags) ||			in_vfork(p)) {		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) + get_mm_counter(p->mm, MM_SWAPENTS) +		atomic_long_read(&p->mm->nr_ptes) + mm_nr_pmds(p->mm);	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 -= (points * 3) / 100; 	/* Normalize to oom_score_adj units */	adj *= totalpages / 1000;	points += adj; 	/*	 * 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;} enum oom_constraint {	CONSTRAINT_NONE,	CONSTRAINT_CPUSET,	CONSTRAINT_MEMORY_POLICY,	CONSTRAINT_MEMCG,}; /* * Determine the type of allocation constraint. */static enum oom_constraint constrained_alloc(struct oom_control *oc){	struct zone *zone;	struct zoneref *z;	enum zone_type high_zoneidx = gfp_zone(oc->gfp_mask);	bool cpuset_limited = false;	int nid; 	if (is_memcg_oom(oc)) {		oc->totalpages = mem_cgroup_get_limit(oc->memcg) ?: 1;		return CONSTRAINT_MEMCG;	} 	/* Default to all available memory */	oc->totalpages = totalram_pages + total_swap_pages; 	if (!IS_ENABLED(CONFIG_NUMA))		return CONSTRAINT_NONE; 	if (!oc->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 (oc->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 (oc->nodemask &&	    !nodes_subset(node_states[N_MEMORY], *oc->nodemask)) {		oc->totalpages = total_swap_pages;		for_each_node_mask(nid, *oc->nodemask)			oc->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, oc->zonelist,			high_zoneidx, oc->nodemask)		if (!cpuset_zone_allowed(zone, oc->gfp_mask))			cpuset_limited = true; 	if (cpuset_limited) {		oc->totalpages = total_swap_pages;		for_each_node_mask(nid, cpuset_current_mems_allowed)			oc->totalpages += node_spanned_pages(nid);		return CONSTRAINT_CPUSET;	}	return CONSTRAINT_NONE;} static int oom_evaluate_task(struct task_struct *task, void *arg){	struct oom_control *oc = arg;	unsigned long points; 	if (oom_unkillable_task(task, NULL, oc->nodemask))		goto next; 	/*	 * This task already has access to memory reserves and is being killed.	 * Don't allow any other task to have access to the reserves unless	 * the task has MMF_OOM_SKIP because chances that it would release	 * any memory is quite low.	 */	if (!is_sysrq_oom(oc) && tsk_is_oom_victim(task)) {		if (test_bit(MMF_OOM_SKIP, &task->signal->oom_mm->flags))			goto next;		goto abort;	} 	/*	 * 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)) {		points = ULONG_MAX;		goto select;	} 	points = oom_badness(task, NULL, oc->nodemask, oc->totalpages);	if (!points || points < oc->chosen_points)		goto next; 	/* Prefer thread group leaders for display purposes */	if (points == oc->chosen_points && thread_group_leader(oc->chosen))		goto next;select:	if (oc->chosen)		put_task_struct(oc->chosen);	get_task_struct(task);	oc->chosen = task;	oc->chosen_points = points;next:	return 0;abort:	if (oc->chosen)		put_task_struct(oc->chosen);	oc->chosen = (void *)-1UL;	return 1;} /* * Simple selection loop. We choose the process with the highest number of * 'points'. In case scan was aborted, oc->chosen is set to -1. */static void select_bad_process(struct oom_control *oc){	if (is_memcg_oom(oc))		mem_cgroup_scan_tasks(oc->memcg, oom_evaluate_task, oc);	else {		struct task_struct *p; 		rcu_read_lock();		for_each_process(p)			if (oom_evaluate_task(p, oc))				break;		rcu_read_unlock();	} 	oc->chosen_points = oc->chosen_points * 1000 / oc->totalpages;} /** * dump_tasks - dump current memory state of all system tasks * @memcg: 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, nr_ptes, * swapents, oom_score_adj value, and name. */static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask){	struct task_struct *p;	struct task_struct *task; 	pr_info("[ pid ]   uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name\n");	rcu_read_lock();	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 %7ld %7ld %8lu         %5hd %s\n",			task->pid, from_kuid(&init_user_ns, task_uid(task)),			task->tgid, task->mm->total_vm, get_mm_rss(task->mm),			atomic_long_read(&task->mm->nr_ptes),			mm_nr_pmds(task->mm),			get_mm_counter(task->mm, MM_SWAPENTS),			task->signal->oom_score_adj, task->comm);		task_unlock(task);	}	rcu_read_unlock();} static void dump_header(struct oom_control *oc, struct task_struct *p){	pr_warn("%s invoked oom-killer: gfp_mask=%#x(%pGg), nodemask=",		current->comm, oc->gfp_mask, &oc->gfp_mask);	if (oc->nodemask)		pr_cont("%*pbl", nodemask_pr_args(oc->nodemask));	else		pr_cont("(null)");	pr_cont(",  order=%d, oom_score_adj=%hd\n",		oc->order, current->signal->oom_score_adj);	if (!IS_ENABLED(CONFIG_COMPACTION) && oc->order)		pr_warn("COMPACTION is disabled!!!\n"); 	cpuset_print_current_mems_allowed();	dump_stack();	if (oc->memcg)		mem_cgroup_print_oom_info(oc->memcg, p);	else		show_mem(SHOW_MEM_FILTER_NODES, oc->nodemask);	if (sysctl_oom_dump_tasks)		dump_tasks(oc->memcg, oc->nodemask);} /* * Number of OOM victims in flight */static atomic_t oom_victims = ATOMIC_INIT(0);static DECLARE_WAIT_QUEUE_HEAD(oom_victims_wait); static bool oom_killer_disabled __read_mostly; #define K(x) ((x) << (PAGE_SHIFT-10)) /* * task->mm can be NULL if the task is the exited group leader.  So to * determine whether the task is using a particular mm, we examine all the * task's threads: if one of those is using this mm then this task was also * using it. */bool process_shares_mm(struct task_struct *p, struct mm_struct *mm){	struct task_struct *t; 	for_each_thread(p, t) {		struct mm_struct *t_mm = READ_ONCE(t->mm);		if (t_mm)			return t_mm == mm;	}	return false;}  #ifdef CONFIG_MMU/* * OOM Reaper kernel thread which tries to reap the memory used by the OOM * victim (if that is possible) to help the OOM killer to move on. */static struct task_struct *oom_reaper_th;static DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait);static struct task_struct *oom_reaper_list;static DEFINE_SPINLOCK(oom_reaper_lock); static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm){	struct mmu_gather tlb;	struct vm_area_struct *vma;	bool ret = true; 	/*	 * We have to make sure to not race with the victim exit path	 * and cause premature new oom victim selection:	 * __oom_reap_task_mm		exit_mm	 *   mmget_not_zero	 *				  mmput	 *				    atomic_dec_and_test	 *				  exit_oom_victim	 *				[...]	 *				out_of_memory	 *				  select_bad_process	 *				    # no TIF_MEMDIE task selects new victim	 *  unmap_page_range # frees some memory	 */	mutex_lock(&oom_lock); 	if (!down_read_trylock(&mm->mmap_sem)) {		ret = false;		trace_skip_task_reaping(tsk->pid);		goto unlock_oom;	} 	/*	 * increase mm_users only after we know we will reap something so	 * that the mmput_async is called only when we have reaped something	 * and delayed __mmput doesn't matter that much

Lines 1–500 of 1087.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t