Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

76261
1501
219118


[리눅스커널] 시간관리: jiffies란 무엇인가 8. 커널 타이머 관리

많은 리눅스 커널 세부 함수에서 jiffies를 써서 실행 시간 기준으로 알고리즘을 제어합니다. 이번 시간에 jiffies의 개념을 소개하고 리눅스 커널에서 jiffies로 시간의 흐름을 제어하는 코드를 소개합니다.

jiffies 소개

jiffies는 커널 타이머를 실행하는 시간 단위입니다. 공학 용어로 Resolution와 비슷한 개념입니다. jiffies를 지피스라고도 부르기도 합니다. 하지만 이번 챕터에서 리눅스 커널에서 쓰는 jiffies란 용어를 그대로 쓰겠습니다.

HZ란 무엇일까 
jiffies 개념을 이해하려면 HZ가 무엇인지 알아야 합니다. HZ는 무엇일까요? 

    HZ는 진동수라고 부르며 1초에 지피스(jiffies)가 업데이트되는 횟수이다.

만약 HZ가 300이면 지피스는 1초에 300번 증감하고, HZ가 100이면 지피스는 1초에 100번 증감합니다.

HZ는 커널 타이머가 동적 타이머를 처리하는 단위입니다. 또한 1초당 커널 타이머가 동적 타이머를 처리하는 횟수를 의미합니다. 그래서 HZ 크기로 커널 타이머의 실행 빈도는 정해집니다.
 
    그러면 HZ가 크면 좋은 시스템일까? 

HZ가 너무 크면 시스템 오버해드가 걸릴 수 있습니다. HZ값이 늘어나면 타이머를 처리하는 횟수도 증가하기 때문입니다. 반대로 HZ가 너무 적으면 동적 타이머를 처리하는 횟수가 줄어듭니다. 타이머 만료 시각 처리에 오차가 생깁니다. 소프트웨어에서 자주 듣는 트레이드 오프가 HZ에도 적용되는 듯 합니다. HZ는 수 많은 테스트로 최적화된 값을 적용합니다.

HZ는 어떻게 확인할까
이미 수많은 커널과 CPU 개발자들이 여러 시행착오로 CPU 별로 HZ값을 이미 정해 놨습니다. 라즈베리파이에서 HZ는 얼마일까요? 라즈베리파이는 ARM CPU를 탑재하므로 HZ값이 100입니다. 참고로 대부분 ARM 계열 리눅스 커널은 HZ값이 100입니다. 이 값은 라즈비안 커널을 빌드하면 생성되는 .config 파일에서 다음과 같이 확인할 수 있습니다.
CONFIG_HZ=100


커널을 빌드를 하면 out 폴더에 .config 파일을 확인할 수 있습니다.
2.3.2 소절에서 라즈비안 커널 소스 빌드 방법을 설명하니 참고하세요.

HZ는 커널 빌드를 할 때 정해지며 커널이 실행하는 도중 바뀌지 않습니다. 만약 HZ이 100이면 리눅스 시스템은 부팅하고 나서 실행하는 동안 계속 100입니다.

대부분 ARMv7 프로세스를 탑재한 리눅스 시스템에서는 HZ를 100으로 설정하는 경우가 많습니다. 하지만 시스템 전반 설계 방향에 따라 HZ를 200 혹은 300으로 정할 수도 있습니다.

타이머 인터럽트 발생 빈도는 스케줄러나 시스템 리소스를 관리하는 드라이버 동작에 영향을 줄 수 있습니다.

라즈비안에서 HZ는 100이니 앞으로 이 기준으로 커널 타이머로 시간의 흐름을 어떻게 관리하는지 분석하겠습니다. 

jiffies는 실제 어떻게 바뀔까?
jiffies는 1초에 HZ(100) 만큼 증감하며 이 기준으로 시간의 흐름을 관리할 수 있습니다. 그렇다면 실제 jiffies는 어떤 값일까요? 만약 여러분에게 다음과 같은 시나리오가 주어졌다고 가정하겠습니다.

    어떤 함수 코드 블락이 2초에 실행되는지 점검하자.

현재 jiffies가 1000이면 jiffies는 초당 다음과 같이 바뀝니다.
1초 후: 1100
2초 후: 1200
3초 후: 1300

이렇게 jiffies란 용어는 2가지 개념으로 생각해 볼 있습니다.
현재 시각: “지금 jiffies가 304200입니다.”라는 문장은 jiffies 라는 변수가 현재 시각 정보를 나타낸다는 의미입니다.

상대 시각: “jiffie 단위로 200ms로 마감시각을 설정합니다.” 이 문장에서 jiffies는 어떤 의미일까요? jiffies 는 HZ 단위로 시간 정보를 표현하는 값입니다. 시간을 현재 시각 값인 jiffies HZ단위 기준으로 설정합니다.

이렇게 2가지 개념을 섞어서 jiffies라는 용어를 쓰니 헷갈릴 수 있습니다. 다음 절에서 소개할 ftrace 로그를 같이 분석하면 확실히 jiffies의 개념을 파악할 수 있습니다.

Soft IRQ 관점으로 HZ의 의미 알아보기
커널 타이머는 Soft IRQ로 1초에 HZ만큼 TIMER_SOFTIRQ 아이디로 Soft IRQ 서비스를 요청합니다. Soft IRQ 서비스를 실행하는 __do_softirq() 함수에서 동적 타이머를 실행합니다. 커널 타이머를 실행하는 단위가 HZ입니다. 라즈베리파이는 HZ가 100이니 1초에 100번 커널 시스템 타이머가 실행합니다.

jiffies로 시간 흐름을 제어하는 코드 분석하기
HZ 단위 값은 mod_timer(), add_timer() 함수 및 timer_after()와 timer_before()에 전달하는 인자입니다. 관련 예제 코드를 보면서 HZ단위로 시각값을 어떻게 전달하는지 알아봅시다.

우선 mod_timer() 함수를 보겠습니다.
1       static timer_list dynamic_timer
2 int timeout = 0;
3 timeout = jiffies;
4 timeout += 2 * HZ;
5
6 mod_timer(&dynamic_timer, timeout);

먼저 3번째 줄 코드를 봅시다.
timeout 지역변수에 현재 시각을 표현하는 jiffies 값을 저장합니다. 

4번째 줄 코드는 timeout 지역변수에 (2 * HZ)를 더합니다. HZ는 1초 동안 jiffies가 증감하는 횟수를 표현하니 (2 * HZ) 값은 2초를 나타내는 HZ 단위 시간 정보입니다. 

6번째 줄 코드는 mod_timer() 함수 두 번째 인자로 timeout을 전달합니다. 이렇게 동적 타이머가 2초 후에 만료하려면 위와 같이 (jiffies + 2 * HZ) 인자를 mod_timer() 함수에 채워서 호출해야 합니다.

다음 mod_timer() 함수 선언부를 봅시다.
[https://github.com/raspberrypi/linux/blob/rpi-4.19.y/include/linux/timer.h]
extern int mod_timer(struct timer_list *timer, unsigned long expires);

두 번째 인자가 expires입니다. 이 인자에 HZ 단위 시간 정보를 전달해야 합니다.

이번에 timer_after() 함수를 호출해 실행 시간을 관리하는 예시 코드를 보겠습니다. 
01   int elapsed_time = jiffies + ( 3 * HZ )
02
03 //
04 // 특정 함수 실행 구간
05 //
06   if (timer_after(jiffies, elapsed_time) {
07 panic(“Current function should have been executed within elapsed_timen”);
08   }

01번째 줄 코드를 먼저 보겠습니다. 현재 시간 정보를 담고 있는 jiffies에 ( 3 * HZ )를 더해서 elapsed_time 지역 변수에 저장합니다. 여기서 elapsed_time 지역 변수를 다음과 같은 시간 정보를 저장하게 됩니다.

    3초 후 시간 정보

이 후 03~05번째 줄 코드에서 특정 루틴을 실행합니다. 이 구간에 for 문이나 while 문이 올 수 있습니다.

다음 06번째 줄 코드를 보겠습니다. timer_after() 함수 첫 번째 인자로 jiffies 변수와 elapsed_time 변수가 보입니다. 당연한 이야기지만 06번째 줄에서 보이는 jiffies는 06번째 줄 코드를 실행할 때 시간 정보를 담고 있습니다. 달리 설명을 드리면 01번째 줄 코드에서 보이는 jiffies와 다른 값을 저장하고 있을 것입니다. 그 이유는 다음과 같습니다.

    01번째 줄 코드의 jiffies는 01번째 줄 코드를 실행할 때 시간 정보를 담고 있다.

그런데 06번째 줄 코드에서 timer_after() 함수를 사용해 현재 시각인 jiffies와 elapsed_time를 비교합니다. 현재 시각인 jiffies가 elapsed_time보다 크면 panic() 함수를 호출해서 커널 크래시를 유발하게 됩니다. 즉, 03~05번째 코드 구간 실행 시간이 3초를 지나면 커널 크래시가 발생하는 목적의 코드인 것입니다.

이렇게 timer_after() 함수에 전달하는 두 인자도 HZ 기준 시간 값들입니다.

커널 타이머에서 HZ는 상대 시간을 표현하는 매우 중요한 단위입니다. 이 개념을 정확히 이해해야 실행 시간 흐름을 기준로 제어하는 코드를 제대로 읽을 수 있습니다.

다음 소절에서는 소스 코드에서 jiffies와 jiffies_64 변수의 의미를 알아보겠습니다.

* 강의 동영상도 있으니 같이 들으시면 좋습니다.






#커널 시간관리 목차
커널 타이머 관리 주요 개념 소개
jiffies란
커널 타이머 제어
동적 타이머 초기화
동적 타이머 등록하기
동적 타이머는 누가 언제 실행하나?
라즈베리파이 커널 타이머 실습 및 로그 분석

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



# Reference: For more information on 'Linux Kernel';

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2



 


핑백

덧글

댓글 입력 영역