1.dup_task_struct函数调用位置及其作用
调用位置: do_fork -> copy_process -> dup_task_struct
作用:复制一份task_struct结构体
2.函数主体流程
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
struct task_struct *tsk;
struct thread_info *ti;
unsigned long *stackend;
int err;
prepare_to_copy(orig);
tsk = alloc_task_struct(); //创建新的子进程结构体
if (!tsk)
return NULL;
ti = alloc_thread_info(tsk);
if (!ti) {
free_task_struct(tsk);
return NULL;
}
err = arch_dup_task_struct(tsk, orig); //把orig中的内容完全复制给tsk,相当于*tsk = *orig
if (err)
goto out;
tsk->stack = ti;
err = prop_local_init_single(&tsk->dirties);
if (err)
goto out;
setup_thread_stack(tsk, orig);
/*为整个thread_info结构复制,并设置指针指向
thread_info里面有一个指向task_struct的指针 ,子进程指向子进程的,父进程指向父进程的,而现在,
这两个thread_info中的某个指针,都指向了父进程的task_struct,所以还要使得子进程thread_info的指针指向tsk的task_struct,
而不是 父进程的task_struct:task_thread_info(p)->task = p;*/
clear_user_return_notifier(tsk);
stackend = end_of_stack(tsk);
*stackend = STACK_END_MAGIC; /* for overflow detection */
#ifdef CONFIG_CC_STACKPROTECTOR
tsk->stack_canary = get_random_int();
#endif
/* One for us, one for whoever does the "release_task()" (usually parent) */
atomic_set(&tsk->usage,2);
atomic_set(&tsk->fs_excl, 0);
#ifdef CONFIG_BLK_DEV_IO_TRACE
tsk->btrace_seq = 0;
#endif
tsk->splice_pipe = NULL;
account_kernel_stack(ti, 1);
return tsk;
out:
free_thread_info(ti);
free_task_struct(tsk);
return NULL;
}
在专业高速缓冲内存上 分配task_struct,并完成初始化
在普通内存中 分配thread_info及连续的两个页面,完成初始化
将task_struct和thread_info联系起来