进程管理之exit()

本文详细探讨了进程管理中exit()函数的关键步骤,重点解析了exit_mm过程,包括mm_release()用于处理vfork创建进程的特殊情况,以及put_mm()如何释放页面、页目录等资源。同时,解释了为何不释放task_struct结构的原因,以防止内核存储空间泄露。
摘要由CSDN通过智能技术生成
NORET_TYPE void do_exit(long code)
{
	struct task_struct *tsk = current;
	int group_dead;

	profile_task_exit(tsk);

	WARN_ON(atomic_read(&tsk->fs_excl));  //如果进程holding fs exclusive resources,则报错。但是还是不理解这个字段的作用
	WARN_ON(blk_needs_flush_plug(tsk));//保证task_struct中的plug字段是空的,或者plug字段指向的队列是空的。plug字段的意义是stack plugging

	if (unlikely(in_interrupt())) //中断服务程序是不应该调用do_exit的,因此要对其进行检查。
		panic("Aiee, killing interrupt handler!");
	if (unlikely(!tsk->pid)) //不能杀死idle进程和init进程。
		panic("Attempted to kill the idle task!");

	/*
	 * If do_exit is called because this processes oopsed, it's possible
	 * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
	 * continuing. Amongst other possible reasons, this is to prevent
	 * mm_release()->clear_child_tid() from writing to a user-controlled
	 * kernel address.
	 */
	set_fs(USER_DS);  //fs寄存器指向当前活动线程的TEB结构(线程结构)????

	tracehook_report_exit(&code); // possibly stop for a ptrace event notification

	validate_creds_for_do_exit(tsk); //check creds for do_exit().我们现在先不关心credential机制。

	/*
	 * We're taking recursive faults here in do_exit. Safest is to just
	 * leave this task alone and wait for reboot.
	 */
	if (unlikely(tsk->flags & PF_EXITING)) {
		printk(KERN_ALERT
			"Fixing recursive fault but reboot is needed!\n");
		/*
		 * We can do this unlocked here. The futex code uses
		 * this flag just to verify whether the pi state
		 * cleanup has been done or not. In the worst case it
		 * loops once more. We pretend that the cleanup was
		 * done as there is no way to return. Either the
		 * OWNER_DIED bit is set by now or we push the blocked
		 * task into the wait for ever nirwana as well.
		 */
		tsk->flags |= PF_EXITPIDONE;  //该进程正在被
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule();
	}

	exit_irq_thread();
    /*
     * Set the THREAD DIED flag to prevent further wakeups of the
     * soon to be gone threaded handler.
     */

	exit_signals(tsk);  /* sets PF_EXITING *//*以后再讨论信号量的事情*/ 
	/*
	 * tsk->flags are checked in the futex code to protect against
	 * an exiting task cleaning up the robust pi futexes.
	 */
	smp_mb();
	raw_spin_unlock_wait(&tsk->pi_lock);

	if (unlikely(in_atomic()))
		printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
				current->comm, task_pid_nr(current),
				preempt_count());

	acct_update_integrals(tsk); //update mm integral fields in task_struct.不过看源代码好像主要是设置task_struct中与时间相关的选项。
	/* sync mm's RSS info before statistics gathering */
	if (tsk->mm)
		sync_mm_rss(tsk, tsk->mm); //这个函数实现的机制并没有搞清楚,确切得说是没有搞清楚rss机制。
	group_dead = atomic_dec_and_test(&tsk->signal->live);
	if (group_dead) {
		hrtimer_cancel(&tsk->signal->real_timer);
		exit_itimers(tsk->signal);
		if (tsk->mm)
			setmax_mm_hiwater_rss(&tsk->signal->maxrss, tsk->mm);
	}
	acct_collect(code, group_dead); //collect accounting information into pacct_struct.
	if (group_dead)
		tty_audit_exit();
	if (unlikely(tsk->audit_context))
		audit_free(tsk);

	tsk->exit_code = code;
	taskstats_exit(tsk, group_dead); //Send pid data out on exit 

	exit_mm(tsk); //放弃进程占用的mm,如果没有其他进程使用该mm,则释放它。
	if (group_dead)
		acct_process();
	trace_sched_process_exit(tsk);

	e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值