Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

80258
1323
114582


[리눅스커널] 스케줄링: 런큐 runqueues 변수에 대해서 - p 10. Process Scheduling

런큐는 per-cpu 타입 전역 변수인 runqueues로 각각 CPU 갯수 별로 프로세스 스케줄링 정보를 저장합니다.

runqueues 변수 선언부 확인하기

먼저 per-cpu 타입 런큐 전역 변수를 소개합니다.
[https://elixir.bootlin.com/linux/v4.19.30/source/kernel/sched/sched.h]
1 DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);

런큐는 runqueues 이란 per-cpu 타입 전역 변수로 관리합니다. 따라서 per-cpu 별 런큐 주소를 얻기 위해서 다음과 같은 cpu_rq() 함수와 this_irq() 함수를 호출해야 합니다.
[https://elixir.bootlin.com/linux/v4.19.30/source/kernel/sched/sched.h]
#define cpu_rq(cpu)  (&per_cpu(runqueues, (cpu)))
#define this_rq()  this_cpu_ptr(&runqueues)

runqueues 변수 percpu 구조 확인하기

라즈베리파이에서 확인한 런큐 디버깅 정보와 함께 percpu 타입 변수인 runqueues 변수에 대해서 조금 더 짚어 보겠습니다.
 
  [그림 10.24] 런큐 runqueues 변수 구조

먼저 runqueues 란 전역 변수 주소는 0x80B8CD40입니다.
  (struct rq *) &runqueues = 0x80B8CD40 

다음 계산식으로 per-cpu 별 런큐 위치를 확인할 수 있습니다.
CPU0: runqueues
0xB0E69D40 = 0x80B8CD40 + 0x302DD000 = &runqueues + __per_cpu_offset[0]

CPU1: runqueues
0xB0E75D40 = 0x80B8CD40 + 0x302E9000 = &runqueues + __per_cpu_offset[1]

CPU2: runqueues
0xB0E81D40 = 0x80B8CD40 + 0x302F5000 = &runqueues + __per_cpu_offset[2]

CPU3: runqueues
0xB0E8DD40 = 0x80B8CD40 + 0x30301000 = &runqueues + __per_cpu_offset[3]

per-cpu 타입 변수인 runqueues 전역 변수 주소에 __per_cpu_offset[4] 에 저장된 percpu 오프셋을 더하면 각 CPU별로 관리하는 런큐 주소를 알 수 있습니다.

__per_cpu_offset 배열 값은 CPU 갯수 만큼 설정하며 각 배열에 저장된 값은 다음과 같습니다.
  (static long unsigned int [4]) __per_cpu_offset = (
    [0x0] = 0x302DD000,
    [0x1] = 0x302E9000,
    [0x2] = 0x302F5000,
    [0x3] = 0x30301000,


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

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

Reference(프로세스 스케줄링)

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



핑백

덧글

댓글 입력 영역