调度器42—进程exit退出流程

基于Linux-5.10

一、do_exit()简要流程

1. 执行路径

各驱动和内核机制中直接调用
SYSCALL_DEFINE1(exit, int, error_code) //exit.c 将 (error_code&0xff)<<8 传给参数 code
    do_exit(code);
        if (unlikely(in_interrupt())) //当前进程关中断后退出了,panic。
            panic("Aiee, killing interrupt handler!");
        if (unlikely(!tsk->pid)) //当前进程关抢占后退出了,panic。
            panic("Attempted to kill the idle task!");
        exit_signals(tsk);
            tsk->flags |= PF_EXITING; //标记进程正在退出
        if (unlikely(is_global_init(tsk))) //init进程退出了,panic。
            panic("Attempted to kill init! exitcode=0x%08x\n", tsk->signal->group_exit_code ?: (int)code);
        tsk->exit_code = code; //更新退出码
        exit_notify(tsk, group_dead);
            tsk->exit_state = EXIT_ZOMBIE;
        exit_rcu(); //通知RCU进程退出了
        do_task_dead
            tsk->state |= TASK_DEAD;
            tsk->flags |= PF_NOFREEZE; /* Tell freezer to ignore us: */
            __schedule(false);

可以看到:

(1) 调用exit()的执行流程最终只是将进程状态设置为 TASK_DEAD,然后切走了,在这个流程中并没有释放 task_struct 结构。
(2) 关中断和原子上下文执行exit流程会报panic。

 

2. exit退出线程状态

基于msm-4.14

(1) 状态设置

    SYSCALL_DEFINE1(exit, int, error_code) //kernel/exit.c 等还有其它直接调用 do_exit()的路径
        do_exit((error_code&0xff)<<8)
            do_exit(long code) //kernel/exit.c
                tsk->exit_code = code;
                trace_sched_process_exit(tsk) //kernel/exit.c
                do_task_dead
                    set_special_state(TASK_DEAD);
                        current->state = TASK_DEAD; //将自己状态设置为 TASK_DEAD=0x80
                    current->flags |= PF_NOFREEZE;
                    __schedule(false);

但是,trace_sched_switch() 切走任务时打印的 prev_state=X(EXIT_DEAD) 而不是 prev_state=I(TASK_DEAD)

  <idle>-0     (-----) [004] d..2   118.380959: sched_switch: prev_comm=swapper/4 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=Navi_CPU next_pid=5859 next_prio=120
   <...>-5859  ( 2712) [004] ....   118.381093: sched_process_exit: comm=Navi_CPU pid=5859 prio=120
   <...>-5859  ( 2712) [004] d..2   118.381200: sched_switch: prev_comm=Navi_CPU prev_pid=5859 prev_prio=120 prev_state=X ==> next_comm=swapper/4 next_pid=0 next_prio=120

对应systrace显示现象:

其它状态和trace上对应的退出现象:

trace_sched_switch() 上的状态打印:
{ __TASK_STOPPED, "T" }, //trace显示蓝色的 Stopped
{ __TASK_TRACED, "t" }, //trace显示蓝色的 Traced
{ EXIT_DEAD, "X" }, //trace显示蓝色的 Exit (Dead)
{ EXIT_ZOMBIE, "Z" }, //trace显示蓝色的 Exit (Zombie)
{ TASK_PARKED, "P" }, //trace显示蓝色的 Parked
{ TASK_DEAD, "I" }) : //trace上竟然显示的是sleep状态!

 

posted on 2023-02-16 22:20  Hello-World3  阅读(186)  评论(0编辑  收藏  举报

导航