1717 lines · 42.2 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* *  linux/kernel/exit.c * *  Copyright (C) 1991, 1992  Linus Torvalds */ #include <linux/mm.h>#include <linux/slab.h>#include <linux/sched/autogroup.h>#include <linux/sched/mm.h>#include <linux/sched/stat.h>#include <linux/sched/task.h>#include <linux/sched/task_stack.h>#include <linux/sched/cputime.h>#include <linux/interrupt.h>#include <linux/module.h>#include <linux/capability.h>#include <linux/completion.h>#include <linux/personality.h>#include <linux/tty.h>#include <linux/iocontext.h>#include <linux/key.h>#include <linux/cpu.h>#include <linux/acct.h>#include <linux/tsacct_kern.h>#include <linux/file.h>#include <linux/fdtable.h>#include <linux/freezer.h>#include <linux/binfmts.h>#include <linux/nsproxy.h>#include <linux/pid_namespace.h>#include <linux/ptrace.h>#include <linux/profile.h>#include <linux/mount.h>#include <linux/proc_fs.h>#include <linux/kthread.h>#include <linux/mempolicy.h>#include <linux/taskstats_kern.h>#include <linux/delayacct.h>#include <linux/cgroup.h>#include <linux/syscalls.h>#include <linux/signal.h>#include <linux/posix-timers.h>#include <linux/cn_proc.h>#include <linux/mutex.h>#include <linux/futex.h>#include <linux/pipe_fs_i.h>#include <linux/audit.h> /* for audit_free() */#include <linux/resource.h>#include <linux/blkdev.h>#include <linux/task_io_accounting_ops.h>#include <linux/tracehook.h>#include <linux/fs_struct.h>#include <linux/init_task.h>#include <linux/perf_event.h>#include <trace/events/sched.h>#include <linux/hw_breakpoint.h>#include <linux/oom.h>#include <linux/writeback.h>#include <linux/shm.h>#include <linux/kcov.h>#include <linux/random.h>#include <linux/rcuwait.h>#include <linux/compat.h> #include <linux/uaccess.h>#include <asm/unistd.h>#include <asm/pgtable.h>#include <asm/mmu_context.h> static void __unhash_process(struct task_struct *p, bool group_dead){	nr_threads--;	detach_pid(p, PIDTYPE_PID);	if (group_dead) {		detach_pid(p, PIDTYPE_TGID);		detach_pid(p, PIDTYPE_PGID);		detach_pid(p, PIDTYPE_SID); 		list_del_rcu(&p->tasks);		list_del_init(&p->sibling);		__this_cpu_dec(process_counts);	}	list_del_rcu(&p->thread_group);	list_del_rcu(&p->thread_node);} /* * This function expects the tasklist_lock write-locked. */static void __exit_signal(struct task_struct *tsk){	struct signal_struct *sig = tsk->signal;	bool group_dead = thread_group_leader(tsk);	struct sighand_struct *sighand;	struct tty_struct *uninitialized_var(tty);	u64 utime, stime; 	sighand = rcu_dereference_check(tsk->sighand,					lockdep_tasklist_lock_is_held());	spin_lock(&sighand->siglock); #ifdef CONFIG_POSIX_TIMERS	posix_cpu_timers_exit(tsk);	if (group_dead) {		posix_cpu_timers_exit_group(tsk);	} else {		/*		 * This can only happen if the caller is de_thread().		 * FIXME: this is the temporary hack, we should teach		 * posix-cpu-timers to handle this case correctly.		 */		if (unlikely(has_group_leader_pid(tsk)))			posix_cpu_timers_exit_group(tsk);	}#endif 	if (group_dead) {		tty = sig->tty;		sig->tty = NULL;	} else {		/*		 * If there is any task waiting for the group exit		 * then notify it:		 */		if (sig->notify_count > 0 && !--sig->notify_count)			wake_up_process(sig->group_exit_task); 		if (tsk == sig->curr_target)			sig->curr_target = next_thread(tsk);	} 	add_device_randomness((const void*) &tsk->se.sum_exec_runtime,			      sizeof(unsigned long long)); 	/*	 * Accumulate here the counters for all threads as they die. We could	 * skip the group leader because it is the last user of signal_struct,	 * but we want to avoid the race with thread_group_cputime() which can	 * see the empty ->thread_head list.	 */	task_cputime(tsk, &utime, &stime);	write_seqlock(&sig->stats_lock);	sig->utime += utime;	sig->stime += stime;	sig->gtime += task_gtime(tsk);	sig->min_flt += tsk->min_flt;	sig->maj_flt += tsk->maj_flt;	sig->nvcsw += tsk->nvcsw;	sig->nivcsw += tsk->nivcsw;	sig->inblock += task_io_get_inblock(tsk);	sig->oublock += task_io_get_oublock(tsk);	task_io_accounting_add(&sig->ioac, &tsk->ioac);	sig->sum_sched_runtime += tsk->se.sum_exec_runtime;	sig->nr_threads--;	__unhash_process(tsk, group_dead);	write_sequnlock(&sig->stats_lock); 	/*	 * Do this under ->siglock, we can race with another thread	 * doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals.	 */	flush_sigqueue(&tsk->pending);	tsk->sighand = NULL;	spin_unlock(&sighand->siglock); 	__cleanup_sighand(sighand);	clear_tsk_thread_flag(tsk, TIF_SIGPENDING);	if (group_dead) {		flush_sigqueue(&sig->shared_pending);		tty_kref_put(tty);	}} static void delayed_put_task_struct(struct rcu_head *rhp){	struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); 	perf_event_delayed_put(tsk);	trace_sched_process_free(tsk);	put_task_struct(tsk);} void put_task_struct_rcu_user(struct task_struct *task){	if (refcount_dec_and_test(&task->rcu_users))		call_rcu(&task->rcu, delayed_put_task_struct);} void release_task(struct task_struct *p){	struct task_struct *leader;	int zap_leader;repeat:	/* don't need to get the RCU readlock here - the process is dead and	 * can't be modifying its own credentials. But shut RCU-lockdep up */	rcu_read_lock();	atomic_dec(&__task_cred(p)->user->processes);	rcu_read_unlock(); 	proc_flush_task(p);	cgroup_release(p); 	write_lock_irq(&tasklist_lock);	ptrace_release_task(p);	__exit_signal(p); 	/*	 * If we are the last non-leader member of the thread	 * group, and the leader is zombie, then notify the	 * group leader's parent process. (if it wants notification.)	 */	zap_leader = 0;	leader = p->group_leader;	if (leader != p && thread_group_empty(leader)			&& leader->exit_state == EXIT_ZOMBIE) {		/*		 * If we were the last child thread and the leader has		 * exited already, and the leader's parent ignores SIGCHLD,		 * then we are the one who should release the leader.		 */		zap_leader = do_notify_parent(leader, leader->exit_signal);		if (zap_leader)			leader->exit_state = EXIT_DEAD;	} 	write_unlock_irq(&tasklist_lock);	release_thread(p);	put_task_struct_rcu_user(p); 	p = leader;	if (unlikely(zap_leader))		goto repeat;} void rcuwait_wake_up(struct rcuwait *w){	struct task_struct *task; 	rcu_read_lock(); 	/*	 * Order condition vs @task, such that everything prior to the load	 * of @task is visible. This is the condition as to why the user called	 * rcuwait_trywake() in the first place. Pairs with set_current_state()	 * barrier (A) in rcuwait_wait_event().	 *	 *    WAIT                WAKE	 *    [S] tsk = current	  [S] cond = true	 *        MB (A)	      MB (B)	 *    [L] cond		  [L] tsk	 */	smp_mb(); /* (B) */ 	task = rcu_dereference(w->task);	if (task)		wake_up_process(task);	rcu_read_unlock();} /* * Determine if a process group is "orphaned", according to the POSIX * definition in 2.2.2.52.  Orphaned process groups are not to be affected * by terminal-generated stop signals.  Newly orphaned process groups are * to receive a SIGHUP and a SIGCONT. * * "I ask you, have you ever known what it is to be an orphan?" */static int will_become_orphaned_pgrp(struct pid *pgrp,					struct task_struct *ignored_task){	struct task_struct *p; 	do_each_pid_task(pgrp, PIDTYPE_PGID, p) {		if ((p == ignored_task) ||		    (p->exit_state && thread_group_empty(p)) ||		    is_global_init(p->real_parent))			continue; 		if (task_pgrp(p->real_parent) != pgrp &&		    task_session(p->real_parent) == task_session(p))			return 0;	} while_each_pid_task(pgrp, PIDTYPE_PGID, p); 	return 1;} int is_current_pgrp_orphaned(void){	int retval; 	read_lock(&tasklist_lock);	retval = will_become_orphaned_pgrp(task_pgrp(current), NULL);	read_unlock(&tasklist_lock); 	return retval;} static bool has_stopped_jobs(struct pid *pgrp){	struct task_struct *p; 	do_each_pid_task(pgrp, PIDTYPE_PGID, p) {		if (p->signal->flags & SIGNAL_STOP_STOPPED)			return true;	} while_each_pid_task(pgrp, PIDTYPE_PGID, p); 	return false;} /* * Check to see if any process groups have become orphaned as * a result of our exiting, and if they have any stopped jobs, * send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2) */static voidkill_orphaned_pgrp(struct task_struct *tsk, struct task_struct *parent){	struct pid *pgrp = task_pgrp(tsk);	struct task_struct *ignored_task = tsk; 	if (!parent)		/* exit: our father is in a different pgrp than		 * we are and we were the only connection outside.		 */		parent = tsk->real_parent;	else		/* reparent: our child is in a different pgrp than		 * we are, and it was the only connection outside.		 */		ignored_task = NULL; 	if (task_pgrp(parent) != pgrp &&	    task_session(parent) == task_session(tsk) &&	    will_become_orphaned_pgrp(pgrp, ignored_task) &&	    has_stopped_jobs(pgrp)) {		__kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);		__kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp);	}} #ifdef CONFIG_MEMCG/* * A task is exiting.   If it owned this mm, find a new owner for the mm. */void mm_update_next_owner(struct mm_struct *mm){	struct task_struct *c, *g, *p = current; retry:	/*	 * If the exiting or execing task is not the owner, it's	 * someone else's problem.	 */	if (mm->owner != p)		return;	/*	 * The current owner is exiting/execing and there are no other	 * candidates.  Do not leave the mm pointing to a possibly	 * freed task structure.	 */	if (atomic_read(&mm->mm_users) <= 1) {		WRITE_ONCE(mm->owner, NULL);		return;	} 	read_lock(&tasklist_lock);	/*	 * Search in the children	 */	list_for_each_entry(c, &p->children, sibling) {		if (c->mm == mm)			goto assign_new_owner;	} 	/*	 * Search in the siblings	 */	list_for_each_entry(c, &p->real_parent->children, sibling) {		if (c->mm == mm)			goto assign_new_owner;	} 	/*	 * Search through everything else, we should not get here often.	 */	for_each_process(g) {		if (g->flags & PF_KTHREAD)			continue;		for_each_thread(g, c) {			if (c->mm == mm)				goto assign_new_owner;			if (c->mm)				break;		}	}	read_unlock(&tasklist_lock);	/*	 * We found no owner yet mm_users > 1: this implies that we are	 * most likely racing with swapoff (try_to_unuse()) or /proc or	 * ptrace or page migration (get_task_mm()).  Mark owner as NULL.	 */	WRITE_ONCE(mm->owner, NULL);	return; assign_new_owner:	BUG_ON(c == p);	get_task_struct(c);	/*	 * The task_lock protects c->mm from changing.	 * We always want mm->owner->mm == mm	 */	task_lock(c);	/*	 * Delay read_unlock() till we have the task_lock()	 * to ensure that c does not slip away underneath us	 */	read_unlock(&tasklist_lock);	if (c->mm != mm) {		task_unlock(c);		put_task_struct(c);		goto retry;	}	WRITE_ONCE(mm->owner, c);	task_unlock(c);	put_task_struct(c);}#endif /* CONFIG_MEMCG */ /* * Turn us into a lazy TLB process if we * aren't already.. */static void exit_mm(void){	struct mm_struct *mm = current->mm;	struct core_state *core_state; 	exit_mm_release(current, mm);	if (!mm)		return;	sync_mm_rss(mm);	/*	 * Serialize with any possible pending coredump.	 * We must hold mmap_sem around checking core_state	 * and clearing tsk->mm.  The core-inducing thread	 * will increment ->nr_threads for each thread in the	 * group with ->mm != NULL.	 */	down_read(&mm->mmap_sem);	core_state = mm->core_state;	if (core_state) {		struct core_thread self; 		up_read(&mm->mmap_sem); 		self.task = current;		self.next = xchg(&core_state->dumper.next, &self);		/*		 * Implies mb(), the result of xchg() must be visible		 * to core_state->dumper.		 */		if (atomic_dec_and_test(&core_state->nr_threads))			complete(&core_state->startup); 		for (;;) {			set_current_state(TASK_UNINTERRUPTIBLE);			if (!self.task) /* see coredump_finish() */				break;			freezable_schedule();		}		__set_current_state(TASK_RUNNING);		down_read(&mm->mmap_sem);	}	mmgrab(mm);	BUG_ON(mm != current->active_mm);	/* more a memory barrier than a real lock */	task_lock(current);	current->mm = NULL;	up_read(&mm->mmap_sem);	enter_lazy_tlb(mm, current);	task_unlock(current);	mm_update_next_owner(mm);	mmput(mm);	if (test_thread_flag(TIF_MEMDIE))		exit_oom_victim();} static struct task_struct *find_alive_thread(struct task_struct *p){	struct task_struct *t; 	for_each_thread(p, t) {		if (!(t->flags & PF_EXITING))			return t;	}	return NULL;} 

Lines 1–500 of 1717.