On Sat, Aug 26, 2023 at 09:46:53AM +0800, Tong Tiangen wrote: > " the ``task_struct`` object is freed only after one or more > grace periods elapse, with the help of call_rcu(), which is invoked via > put_task_struct_rcu_user(). " > > Combined with the code,when the task exits: > > release_task() > __exit_signal() > __unhash_process() > list_del_rcu(&p->tasks) > > put_task_struct_rcu_user() > call_rcu(&task->rcu, delayed_put_task_struct); > > delayed_put_task_struct() > put_task_struct() > if (refcount_sub_and_test(nr, &t->usage)) > __put_task_struct() > free_task() > > The code is consistent with the description in the document. > > According to this understanding, i think for_each_process() under the > protection of rcu locl is safe, that is, task_struct in the list will not be > destroyed, and get_task_struct() is also safe. Aha! This is different from the usual pattern. What I'm used to seeing is: if (refcount_sub_and_test()) { list_del_rcu(); rcu_free(); } and then on the read side you need a refcount_inc_not_zero(), which we didn't have here. Given this new information you've found, I withdraw my objection. It'd be nice to include some of this analysis in an updated changelog (and maybe improved documentation for tasklist?).