Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

83258
1323
114585


[리눅스커널] 스케줄링: 프로세스 상태를 ftrace로 확인하기 10. Process Scheduling

필자가 처음 리눅스 커널을 공부할 때 '프로세스 상태 변화도'를 읽고 다음과 같은 궁금증이 생겼습니다. 

   * 커널이 실행하는 동안 커널 소스에서 프로세스 상태를 어떻게 확인할 수 있을까?

며칠 동안 고민을 했으나 끝내 알아내지 못했습니다. 결국 리눅스 커널 공부를 포기하고 말았습니다. 이번 소절에서는 리눅스 시스템에서 프로세스 상태를 직접 확인하는 방법을 공개하려 합니다. 프로세스 상태 변화에 대해 알아봤으니 이번에는 리눅스 시스템에서 실제 프로세스 상태가 어떻게 바뀌는지 알아보는 것입니다.

패치 코드 소개

먼저 컨텍스트 스위칭을 수행하는 다음 코드에 ftrace 로그를 하나 추가합시다.
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index aedd9bf..4fbd5e5 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3457,7 +3457,7 @@ static void __sched notrace __schedule(bool preempt)
                ++*switch_count;

                trace_sched_switch(preempt, prev, next);
-
+               trace_printk("[+] prev->state:%d, next->state: %d \n", prev->state, next->state);
                /* Also unlocks the rq: */
                rq = context_switch(rq, prev, next, &rf);
        } else {

패치 코드 입력하는 방법에 대한 이해를 돕기 위해 다음 코드를 소개합니다. 
원래 __schedule() 함수 코드에서 박스로 된 부분 코드를 입력하면 됩니다.
 

prev와 next는 프로세스 태스크 디스크립터를 의미합니다.
prev 컨텍스트 스위칭될 프로세스이고 next는 새롭게 실행을 시작하는 프로세스인 것입니다.

위에서 소개한 패치 코드를 입력한 후 커널 빌드를 한 후 커널 이미지를 설치합시다.

ftrace 로그로 프로세스 상태 확인하기
이후 ftrace 를 키고 sched_switch 이벤트를 킨 다음 ftrace 로그를 받습니다. 추출한 ftrace 로그를 열어 보면 다음과 같은 메시지를 확인할 수 있습니다.
1 <idle>-0     [002] d..2   148.079678: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=rcu_preempt next_pid=8 next_prio=120
2 <idle>-0     [002] d..2   148.079686: __schedule+0x468/0x938: [+] prev->state:0, next->state: 0 


ftrace 실행 방법은 3.4 ftrace 절에서 상세히 다루고 있습니다.


2 번째 줄 로그에서 prev->state 는 0입니다. 이 정보는 prev 프로세스의 태스크 디스크립터인 struct task_struct 구조체 state 필드에 저장된 값입니다. state 필드가 0이면 프로세스 상태는 무엇일까요?

다음 해더 파일을 열어보면 정답을 확인할 수 있습니다.
[https://elixir.bootlin.com/linux/v4.19.30/source/include/linux/sched.h]
#define TASK_RUNNING 0x0000

위 코드로 다음 사실을 알 수 있습니다.

    0x0000은 TASK_RUNNING 상태를 의미합니다.

prev 프로세스의 상태 값은 0인데, ftrace 메시지에서는 R(prev_state=R)로 표시합니다.
1 <idle>-0     [002] d..2   148.079678: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=rcu_preempt next_pid=8 next_prio=120

이번에는 다른 ftrace 로그를 보겠습니다.
1 watchdog/1-15    [001] d..2   148.095672: sched_switch: prev_comm=watchdog/1 prev_pid=15 prev_prio=0 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
2 watchdog/1-15    [001] d..2   148.095677: __schedule+0x468/0x938: [+] prev->state:1, next->state: 0 

2 번째 줄 로그를 보면 prev->state 는 1입니다. 이번에는 state 필드가 1이면 어떤 프로세스 상태를 의미할까요? 다음 해더 파일을 보면 정답을 확인할 수 있습니다.
[https://elixir.bootlin.com/linux/v4.19.30/source/include/linux/sched.h]
#define TASK_INTERRUPTIBLE 0x0001 

sched_switch 스케줄러 이벤트 메시지로 프로세스 상태를 알 수 있습니다. 이 메시지를 자주 활용해서 프로세스 상태 변화를 체크합시다. 

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

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

Reference(프로세스 스케줄링)

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



핑백

덧글

댓글 입력 영역