Пример #1
0
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
	struct task_struct *tsk;
	struct thread_info *ti;

	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;
	}

	*tsk = *orig;
	tsk->thread_info = ti;
	setup_thread_stack(tsk, orig);

	/* One for us, one for whoever does the "release_task()" (usually parent) */
	atomic_set(&tsk->usage,2);
	atomic_set(&tsk->fs_excl, 0);
	tsk->btrace_seq = 0;
	tsk->splice_pipe = NULL;
	return tsk;
}
Пример #2
0
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
	struct task_struct *tsk;
	struct thread_info *ti;

	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;
	}

	*ti = *orig->thread_info;
	*tsk = *orig;
	tsk->thread_info = ti;
	ti->task = tsk;

	/* One for us, one for whoever does the "release_task()" (usually parent) */
	atomic_set(&tsk->usage,2);
	return tsk;
}
Пример #3
0
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
	struct task_struct *tsk;
	struct thread_info *ti;

	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;
	}

	*tsk = *orig;
	tsk->stack = ti;
	setup_thread_stack(tsk, orig);

#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;
	return tsk;
}
Пример #4
0
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);
	if (err)
		goto out;

	tsk->stack = ti;

	err = prop_local_init_single(&tsk->dirties);
	if (err)
		goto out;

	setup_thread_stack(tsk, orig);
	clear_user_return_notifier(tsk);
	clear_tsk_need_resched(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;
}
Пример #5
0
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
	struct task_struct *tsk;
	struct thread_info *ti;

	prepare_to_copy(orig);

	/*
	 * 为新进程获取进程描述符
	 */
	tsk = alloc_task_struct();
	if (!tsk)
		return NULL;

	/*
	 * 获取一片空闲区域4k或者8k, 用来存放新进程的thread_info结构和内核栈
	 */
	ti = alloc_thread_info(tsk);
	if (!ti) {
		free_task_struct(tsk);
		return NULL;
	}

	/*
	 * 将current进程描述符的内容复制到tsk所指向的task_struct结构中
	 */
	*ti = *orig->thread_info;
	/*
	 * 把current进程的thread_info描述符的内容复制到ti中
	 */
	*tsk = *orig;
	/*
	 * 下面两行将新进程的task_struct与thread_info绑定
	 */
	tsk->thread_info = ti;
	ti->task = tsk;

	/* One for us, one for whoever does the "release_task()" (usually parent) */
	atomic_set(&tsk->usage,2);
	return tsk;
}
Пример #6
0
int import_thread_info(struct epm_action *action,
		       ghost_t *ghost, struct task_struct *task)
{
	struct thread_info *p;
	int r;

	p = alloc_thread_info(task);
	if (!p) {
		r = -ENOMEM;
		goto exit;
	}

	r = ghost_read(ghost, p, sizeof(struct thread_info));
	/* Required by [__]free_thread_info() */
	p->task = task;
	if (r)
		goto exit_free_thread_info;

	p->exec_domain = import_exec_domain(action, ghost);

	p->preempt_count = 0;
	p->addr_limit = USER_DS;

	r = import_restart_block(action, ghost, &p->restart_block);
	if (r)
		goto exit_free_thread_info;

	task->stack = p;

exit:
	return r;

exit_free_thread_info:
	__free_thread_info(p);
	goto exit;
}
Пример #7
0
/*
 * 由do_fork()调用,为新的子进程创建task_struct, thread_info, 内核栈等信息
 * 创建完成之后和父进程状态完全相同
 */
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);
	/* 申请task_struct内存空间 */
	tsk = alloc_task_struct();
	if (!tsk)
		return NULL;

	/* 申请thread_info内存空间 */
	ti = alloc_thread_info(tsk);
	if (!ti) {
		/* 失败需要释放前面已经成功申请的task_struct内存空间,防止内存泄漏 */
		free_task_struct(tsk);
		return NULL;
	}
	/* 复制orig进程的信息到tsk进程中,复制完成后地址空间地址相同 */
 	err = arch_dup_task_struct(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);
	/* 清除进程栈的部分信息 */
	clear_user_return_notifier(tsk);
	clear_tsk_need_resched(tsk);
	stackend = end_of_stack(tsk);
	*stackend = STACK_END_MAGIC;	/* 用作内存越界检测 */

#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;
}