调度器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) 编辑 收藏 举报