Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

80258
1323
114582


[리눅스커널] 스케줄링: 프로세스는 스케줄러 클래스로 스케줄러 세부 함수를 어떻게 호출할까? 10. Process Scheduling

스케줄러 클래스 자료구조는 스케줄러 세부 함수 동작을 모듈화한 함수 포인터를 저장하는 필드로 구성돼 있습니다. 이번 소절에는 스케줄러 클래스 메소드들 중 enqueue_task()와 dequeue_task() 함수를 호출하면 어떤 방식으로 스케줄러 클래스 세부 함수를 호출하는지 분석합니다.

enqueue_task() 함수 분석하기

먼저 살펴볼 함수는 enqueue_task() 함수입니다.
[https://elixir.bootlin.com/linux/v4.19.30/source/kernel/sched/core.c]
1 static inline void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
2 {
3 if (!(flags & ENQUEUE_NOCLOCK))
4 update_rq_clock(rq);
5
6 if (!(flags & ENQUEUE_RESTORE))
7 sched_info_queued(rq, p);
8
9 p->sched_class->enqueue_task(rq, p, flags);
10 }

위 코드는 스케줄러 클래스를 배워야 하는 이유를 알려주는 좋은 예시입니다. 어떤 분이 여러분에게 묻습니다. 

    9번째 줄 코드에서 어느 함수를 호출할까?

스케줄러 클래스를 모른다면 대답하기 어려운 질문입니다. 여러분은 스케줄러 클래스를 배웠으니 다음과 같이 대답할 수 있는 역량이 쌓였습니다. 

    프로세스 태스크 디스크립터에 등록된 enqueue 스케줄러 클래스 메소드를 호출한다.

enqueue_task() 함수는 프로세스를 런큐에 큐잉하는 동작을 수행합니다.

먼저 함수에 전달하는 인자부터 점검합시다. 
첫 번째 인자: struct rq *rq는 런큐 주소
두 번째 인자: struct task_struct *p는 런큐에 큐잉하려는 프로세스 태스크 디스크립터 주소 

다음 9 번째 줄 코드를 보겠습니다.
9 p->sched_class->enqueue_task(rq, p, flags);

두 번째 인자인 p(struct task_struct) 필드인 sched_class에 접근해 enqueue_task 필드가 저장한 함수를 호출합니다. 여기서 어떤 함수를 호출할까요?

만약 이 코드를 실행하는 프로세스의 스케줄러 클래스가 CFS 스케줄러로 지정돼 있으면 CFS 스케줄러 클래스로 지정된 enqueue_task_fair() 함수를 호출합니다. RT 클래스 스케줄러를 등록했을 경우 enqueue_task_rt() 함수를 호출합니다.

dequeue_task() 함수 분석하기

프로세스를 런큐에 Enqueue하는 동작을 알아봤으니 이번에는 프로세스를 런큐에서 Dequeue하는 함수 코드를 보겠습니다.
[https://elixir.bootlin.com/linux/v4.19.30/source/kernel/sched/core.c]
1 static inline void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
2 {
3 if (!(flags & DEQUEUE_NOCLOCK))
4 update_rq_clock(rq);
5
6 if (!(flags & DEQUEUE_SAVE))
7 sched_info_dequeued(rq, p);
8
9 p->sched_class->dequeue_task(rq, p, flags);
10 }

dequeue_task() 함수 9 번째 줄 코드를 보면 프로세스의 스케줄러 클래스 필드에서 dequeue_task() 메소드를 호출합니다.  

    여기서 어떤 함수를 호출할까요?

만약 이 코드를 실행하는 프로세스의 스케줄러 클래스가 CFS 스케줄러로 지정돼 있으면 CFS 스케줄러 클래스로 지정된 dequeue_task_fair() 함수를 호출합니다. RT 클래스 스케줄러인 경우 dequeue_task_rt() 함수를 호출합니다.

여기까지 배운 내용을 정리하면 다음과 같습니다.
프로세스는 생성되면서 스케줄러 클래스를 부모 프로세스로부터 물려 받거나 우선순위에 따라 스케줄러 클래스를 바꿉니다. 모든 프로세스는 스케줄러 클래스에 등록한 상태로 실행합니다.


필자가 진행한 세미나 시간에 받았던 질문을 공개합니다. 

    리눅스 시스템에서 전체 프로세스 중에 RT 클래스 프로세스와 CFS 클래스 프로세스 
   비율은 어떻게 될까?

수 많은 리눅스 코어 덤프를 관찰한 결과 대부분 99% 정도 프로세스들은 CFS 스케줄러 클래스로 등록되서 실행하고 나머지 1% 프로세스들이 RT 스케줄러 클래스로 등록해 실행합니다. 리눅스 커널 기본 스케줄러 정책은 일반 프로세스는 CFS 스케줄러 클래스로 실행하고 우선순위가 높은 프로세스들은 RT 클래스 스케줄러로 빠른 시간 내 실행하는 것입니다.

대부분 일반 프로세스들이 CFS 스케줄러 클래스로 실행하므로 입출력 중심으로 처리하는 프로세스들의 실행 속도가 빠릅니다.

"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)

Reference(프로세스 스케줄링)

스케줄링 소개
프로세스 상태 관리
   어떤 함수가 프로세스 상태를 바꿀까?
스케줄러 클래스
런큐
CFS 스케줄러
   CFS 관련 세부 함수 분석  
선점 스케줄링(Preemptive Scheduling)   
프로세스는 어떻게 깨울까?
스케줄링 핵심 schedule() 함수 분석
컨택스트 스위칭
스케줄링 디버깅
   스케줄링 프로파일링
     CPU에 부하를 주는 테스트   
     CPU에 부하를 주지 않는 테스트




핑백

덧글

댓글 입력 영역