I find some time to edit my answer to make it more clear. If there are still some problem, please tell me, we can discuss and make it more clear. Let's dive into the end of task :
there are two system calls : exit_group()
and exit()
, and all of them will go to do_exit()
, which will do the following things.
- set
PF_EXTING
which means the task is deleting
- remove the task descriptor from timer by
del_timer_sync()
- call
exit_mm(), exit_sem(), __exit_fs()
and others to release structure of that task
- call perf_event_exit_task(tsk);
- decrease the ref count
- set
exit_code
to _exit()/exit_group()
or error
- call
exit_notify()
- update relationship with parent and child
- check
exit_signal
, send SIGCHLD
- if task is not traced or return value is -1, set the exit_state to
EXIT_DEAD
, call release_task()
to recycle other memory and decrease ref count.
- if task is traced, set exit_state to
EXIT_ZOMBIE
- set task flag to
PF_DEAD
- call
schedule()
We need zombie state cause the parent may need to use those file descriptors so we can not delete all the things in the first time. The parent task will need to use something like wait()
to check if child is dead. After wait()
, it is time for the zombie to release totally by release_task()
- decrease the owners' task number
- if the task is traced, delete from the
ptrace_children
list
- call
__exit_signal()
delete all pending signals and release signal_struct descriptor and exit_itimers()
delete all the timer
- call
__exit_sighand()
delete signal handler
- call
__unhash_process()
nr_threads
--
- call
detach_pid()
to delete task descriptor from PIDTYPE_PID
and PIDTYPE_TGID
- call
REMOVE_LINKS
to delete the task from list
- call
sched_exit()
to schedule parent's time pieces
- call
put_task-struct()
to decrease the counter, and release memory & task descriptor
- call delayed_put_task_struct()
So, we know that sched_process_exit
state will be make in the do_exit(), but we can not make sure if the process is released or not (may call release_task() or not, which will trigger sched_process_free
). That is why we need both of the two perf event point.