Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

106258
1323
114608


[리눅스커널] 스케줄링: 스케줄러 클래스 소개 - p 10. Process Scheduling

스케줄러 클래스는 다양한 스케줄러가 공존하면서 유연하게 실행하게 스케줄링 동작을 모듈화한 자료구조입니다. 또한 스케줄러 클래스는 스케줄러 별 세부 함수 연산을 할 수 있는 함수 포인터 형식의 메소드를 제공합니다. 즉, 스케줄러 클래스 메소드를 통해 리눅스 커널에서 제공하는 5가지 스케줄러 세부 함수에 접근합니다.
 
[그림 10.19] 스케줄러 클래스 종류 

위 그림을 보면서 스케줄러 클래스 개념에 대해서 조금 더 알아봅시다.

프로세스는 생성됨과 동시에 스케줄러 클래스를 등록합니다. 이후 리눅스 커널에서 지원하는 5개 스케줄러 세부 함수를 호출하기 위해서는 current->sched_class에 등록된 함수 메소드를 호출합니다.


리눅스 커널에서는 기본으로 5개의 스케줄러를 지원합니다. 5개 스케줄러에 대한 소개는 다음 테이블에서 확인할 수 있습니다.
 
[그림 10.20] 스케줄러 클래스 별 소스 위치 

이번 절에서는 자주 사용하는 RT 스케줄러, CFS 스케줄러, Idle 스케줄러에 초점을 맞추겠습니다. 


각각 5개의 스케줄러 동작을 모듈화해서 struct sched_class 이란 구조체로 선언하고 프로세스 태스크 디스크립터 sched_class 필드에 등록하는 것입니다.

스케줄러 클래스를 도입한 이유는 무엇일까?
커널에서 스케줄러 클래스를 도입한 이유는 무엇일까요? 

    프로세스가 스케줄러 클래스를 통해 유연하게 스케줄러를 바꿀 수 있다. 

이해를 돕기 위해 한 가지 예를 들겠습니다. 
대부분 일반 프로세스는 CFS 스케줄러에 의해 실행 흐름이 관리됩니다. 그런데 프로세스 실행 중 중요한 데이터나 코드가 선점되지 않고 CPU를 점유하면서 지속적으로 처리해야 하는 상황이 생길 수 있습니다. 이때 CFS 스케줄러보다 RT 스케줄러를 쓰면 계속 CPU를 점유하면서 실행할 수 있습니다. 이 상황에서 다음과 같이 처리하면 됩니다. 

    리눅스 커널에서 지원하는 5가지 스케줄러 클래스 중 RT 클래스를 스케줄러 클래스로 
      등록하면 된다.

스케줄러 클래스는 왜 알아야 할까?
이번에 커널에서 스케줄러 클래스는 왜 알아야 하는지 생각해 봅니다. 

    스케줄러 클래스가 어떤 자료구조로 구현돼 있는지 모르면 스케줄러 관련 코드를 읽을 수
    없다. 

스케줄러 세부 함수들은 모두 스케줄러 클래스를 통해 접근하는 구조로 설계 됐습니다. 따라서 스케줄링 코드 전체 흐름을 이해하기 위해 스케줄러 클래스를 이해해야 합니다. 커널 스케줄러 세부 알고리즘만큼 코드 전체 흐름도를 파악하는 것이 중요합니다.
스케줄러 클래스 자료구조 소개

스케줄러 클래스는 리눅스 커널이 기본으로 지원하는 5가지 스케줄러 세부 동작을 모듈화한 자료 구조입니다.

struct sched_class 구조체 알아보기
먼저 struct sched_class 구조체를 소개하겠습니다.
[https://elixir.bootlin.com/linux/v4.19.30/source/kernel/sched/sched.h]
1 struct sched_class {
2 const struct sched_class *next;
3
4 void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
5 void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
6 void (*yield_task) (struct rq *rq);
7 bool (*yield_to_task) (struct rq *rq, struct task_struct *p, bool preempt);
8
9 void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int flags);
10
11 struct task_struct * (*pick_next_task) (struct rq *rq,
12 struct task_struct *prev,
13 struct rq_flags *rf);
14 void (*put_prev_task) (struct rq *rq, struct task_struct *p);
15 int  (*select_task_rq)(struct task_struct *p, int task_cpu, int sd_flag, int flags);
16 void (*migrate_task_rq)(struct task_struct *p);
17 void (*task_woken) (struct rq *this_rq, struct task_struct *task);
18 void (*set_cpus_allowed)(struct task_struct *p,
const struct cpumask *newmask);

2 번째 줄 *next 필드를 제외하고 모든 필드가 포인터 형식 메소드입니다.
다음 테이블에서 스케줄러 클래스 필드 중 중요한 항목을 확인할 수 있습니다.
필드 설명
enqueue_task 프로세스가 실행 가능한 상태로 진입
dequeue_task 프로세스가 더 이상 실행 가능한 상태가 아닐때
yield_task 프로세스가 스스로 yield() 시스템콜을 실행했을 때
check_preempt_curr 현재 실행 중인 프로세스를 선점(preempt)할 수 있는지 검사
pick_next_task 실행할 다음 프로세스를 선택
put_prev_task 실행중인 태스크를 다시 내부 자료구조에 큐잉
load_balance 코어 스케줄러가 태스크 부하를 분산하고자 할때
set_curr_task 태스크의 스케줄러 클래스나 태스크 그룹을 바꿀때
task_tick 타이머 틱 함수가 호출

struct sched_class 자료구조에 대해 소개를 했으니 이어서 5가지 스케줄러 클래스에 대해서 살펴보겠습니다.


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

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

Reference(프로세스 스케줄링)

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


핑백

덧글

댓글 입력 영역