sched_entity의 초기화

새로운 태스크가 생성될 때 task_struct를 slab cache에서 새롭게 가져온다. 태스크의 sched_entity는 task_struct 구조체에 embedded되어 있으므로 sched_entity도 0으로 초기화되어 있다.

do_fork
-> _do_fork
->-> copy_process()
->->-> dup_task_struct()
->->->-> alloc_task_struct_node() <------ allocate new task_struct

task_struct의 sched_entity의 주요변수들은 __sched_fork()에서 다시한번 0으로 초기화된다.

do_fork
-> _do_fork
->-> copy_process()
->->-> sched_fork()
->->->-> __sched_fork()

kernel/sched/core.c

static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
{
        p->on_rq                        = 0;
        p->se.on_rq                     = 0;
        p->se.exec_start                = 0;
        p->se.sum_exec_runtime          = 0;
        p->se.prev_sum_exec_runtime     = 0;
        p->se.nr_migrations             = 0;
        p->se.vruntime                  = 0;
        INIT_LIST_HEAD(&p->se.group_node);

#ifdef CONFIG_FAIR_GROUP_SCHED
        p->se.cfs_rq                    = NULL;
#endif
        ...
}

다만 sched_entity의 cfs_rq, parent 멤버변수는 set_task_rq()에서 의미있는 값으로 설정된다

kernel/sched/sched.h

static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
{
#if defined(CONFIG_FAIR_GROUP_SCHED) || defined(CONFIG_RT_GROUP_SCHED)
        struct task_group *tg = task_group(p);
#endif

#ifdef CONFIG_FAIR_GROUP_SCHED
        set_task_rq_fair(&p->se, p->se.cfs_rq, tg->cfs_rq[cpu]);
        p->se.cfs_rq = tg->cfs_rq[cpu];
        p->se.parent = tg->se[cpu];
#endif
}

task_group()은 태스크 @p->sched_task_group이 가리키는 태스크그룹을 리턴해준다. 별도의 태스크그룹을 생성하지 않으면 root_task_group으로 설정되어 있다.

새로 생성되는 태스크의 sched_task_group 멤버변수는 dup_task_struct()에서 부모의 것으로 복사된다. sched_task_group은 태스크가 다른 태스크그룹으로 이동할 때(sched_move_task()) 변경된다.

root_task_group으로 설정되어 있다고 가정하면, 새로 생성된 태스크 p의 sched_entity는 아래와 같이 설정된다.

  • @cpu의 rq->cfs_rq가 태스크가 enqueue될 cfs_rq로 설정됨
  • 태스크의 부모 sched_entity로 NULL이 설정됨.

위 설정되는 값이 잘 이해가 가지 않을 경우 태스크그룹 계층도의 root - root_task_group 글의 그림을 참고한다.

새로 생성된 태스크의 sched_entity가 초기화된 모습을 그림으로 표현하면 아래와 같다.

results matching ""

    No results matching ""