리눅스 팁·자료

차영호 2011. 1. 12. 17:42

<< 출처 : http://krunivs.tistory.com/7 >>


0. 목표 

 - 리눅스 커널의 시간 관리 기능에 이해

1. 타이머 역할
 - 시각의 카운트
 - 일정 시간이 지나면 지정한 처리 수행
    EX) 통신처리 -> 재발송 처리, 응답 없는 다비이스 재실행
          인터럽트 발생이 어려운 디바이스에 대한 주기적인 폴링 처리, SIGALARM 시그널 생성

2. 타이머 종류
 가. 글로벌 타이머
  - 시스템 전체와 관련된 처리
  - 주기적으로 인터럽트 발생, 시스템 상의 CPU 통지

 나. 로컬 타이머
  - 특정 CPU 관련된 처리(각 CPU 마다 발생)
  - 로컬타이머의 2단계 처리
     1. 응답성을 필요로 하는 하드웨어 인터럽트: smp_local_timer_interrupt(하드웨어 인터럽트 핸들러), x86
     2. 소프트 인터럽트 처리(지연 처리): rum_timer_softirq(소프트 인터럽트 핸들러)
 
3. 글로벌 타이머
 - do_timer(): 글로벌 타이머 인터럽트 핸들러
 - 4ms 간격으로 발생 (Intel x86, PC/AT 호환기종 기준)
 - 리눅스 내부타이머(xtime 변수) 처리
 - 타이머 인터럽트에 따른 오차 계산
 - 시스템 부하 계산
 - watch dog timer 가능으로 감시 수행

3. 로컬 타이머
 가. smp_local_timer_interrupt(하드웨어 인터럽트 핸들러), x86
  - 수행 절차
   Step 1. 커널과 프로세스의 정보 수집
   Step 2. 타이머 소프트 인터럽트 요청
   Step 3. RCU 배제 상태를 체크
   Step 4. 프로세스 스케쥴러에 재스케쥴링 처리
   Step 5. POSIX 타이머와 구간 타이머(Interval Timer)를 처리

  - 로컬 타이머는 CPU 들이 동시에 인터럽트를 발생하지 않게 하기 위해 지연시간을 갖음
     (특정 순간의 부하 집중을 막고, 타이머 핸들러간 경쟁 발생 기회를 줄임)

 나. run_timer_softirq(소프트 인터럽트 핸들러)
  - 소프트 인터럽트(TIMER_SOFTIRQ)에 따라 로컬 타이머 소프트 인터럽트 핸들러 호출
  - 소프트 인터럽트 핸들러는 타이머 리스트를 실행
  - 로컬 타이머 인터럽트 1회 당 로컬 타이머 소프트 인터럽트 핸들러 1회 동작
  - 인터럽트 지연처리에 영향을 받음

4. 리눅스 내부 타이머
 - 리눅스 커널은 세계 표준시(1970/1/1/0)부터 경과한 시간을 xtime 변수에 설정
 - 리눅스 커널이 부팅되었을 때 하드웨어 시간 값으로 초기화되고, 그 후 일정 주기에 동작하는 글로벌 타이머 
    인터럽트에 의해 시각 처리를 함

5. 하드웨어시간(Wall-clock)
 - 내부에 시간(wall-clock)이라고 하는 컨트롤러를 갖고 있음(하드웨어 시간을 리눅스 내부 타이머에 반영

6. jiffies
 - 커널의 부팅을 0으로 한 시각
 - 타이머 인터럽트 횟수를 카운트
 - 리눅스 내부의 제한 시간을 관리하는 처리 기준으로 이용됨
 - 머신의 부팅과 함께 리셋

7. 타임스탬프 카운터
 - CPU 내부나 외부 컨트롤러가 시간을 카운트 하는 구조
   예) CPU 내부 카운터 레지스터(TSC)- 동작 시작 후, CPU에 보낸 클록의 총 수를 저장함

8. 각종 타이머 관련 하드웨어
 가. APIC(Advanced Programmable Interrupt Controller): 인터럽트 콘트롤러
  - Local APIC
  - I/O APIC: 외부 하드웨어 인터럽트를 받아들임

 나. PIT(Programmable Interval Timer) 컨트롤러
  - I/O APIC에 접속 혹은 칩셋의 사우스 브리지 내에 통합
  - I/O APIC가 받아들인 글로벌 타이머 인터럽트 -> CPU 코어 내에 로컬 APIC에 전송
  - CPU 코어 내 로컬 APIC는 로컬 타이머 인터럽트 발생

9. 시각 관리의 과제
  - jiffies 오버플로우: 디바이스 드라이버 작성시 고려해야함
  - GMT 시삿을 카운트하는 xtime 변수: 2038년 오버플로우

10. 타이머 리스트
 가. 타이머 리스트: 콜백(call back) 핸들러 들록을 위한 범용적인 구조
  - 네트워크 프로토콜 처리, 디바이스 드라이버 타임아웃 처리, 재실행 처리에 이용
  - 실행시각을 지정하고 핸들러를 등록 -> 로컬타이머가 실행 시각을 감시하고 있다가, 
    지정한 시각에 핸들러 호출(jiffies 카운터를 이용해 시각 감시)

11. 타이머 리스트의 구조
  - CPU 별로 기본 타이머 벡터(boot_tvec_bases) 등록
  - CPU에 등록된 기본타이머 벡터는 타이머 벡터(tvec_t) 다섯 개(tv1, tv2, tv3, tv4, tv5)로 분할
  - 타이머에 등록된 핸들러는 타이머 간격에 따라 시간별로 분류 다섯 개의 타이머 벡터에 분할 등록
    (핸들러의 효율적 관리를 위해서) 
  - tv1(tvec_root_s 구조체 타입)에는 256개 핸들러 등록 
  - tv2-5(tvec_s 구조체 타입)에는 64개의 핸들러 등록

12. 타이머 리스트의 실행
  - 타이머 리스트는 로컬 타이머 소프트 인터럽트 핸들러(run_timer_softirq)에 의해 실행
  - 인터럽트 핸들러 호출시마다 tv1에 등록되어있는 핸들러를 실행
  - 1개의 항목에 여러개의 핸들러가 등록되어 있을 경우, 모든 핸들러를 호출
  - 인터럽트 핸들러가 256회 호출되어 tv1의 모든 항목을 순회한 후, 다시 첫번째 항목으로 돌아옴
  - tv1의 첫번쨰 항목으로 돌아올때 tv2의 첫번째 항목에 있는 타이머리스트(timer_list)를 tv1에 등록시킨후 수행
  - 이와 같은 식으로 tv5까지 순회를 함
  - 로컬타이머 소프트 인터럽트 핸들러의 지연때문에, jiffies 값을 저장해 두었다가 이전 jiffies - 현재 jiffies의
     값만큼 타이머리스트를 실행시킴

13. 프로세스로부터의 이용
  - 프로세스 스케쥴링과 타이머 리스트 기능의 조합 기능 제공
  - select/poll 시스템의 타임아웃, nanosleep 시스템 콜 구현, 소켓에 대한 시스템 콜 처리 등이 있음

프로세스 스케쥴링과 조합한 타이머 리스트
schedule_timeout: 프로세스가 지정한 시각까지 CPU 무시
process_timeout: 타임아웃 지정으로 기다리는 프로세스 실행
sleep_on_timeout, interruptible_sleep_on_timeout: 타임아웃 지정으로 대기 상태를 만듬

14. 구간 타이머
  - 사용자 프로세스가 제한 시간을 등록하고 싶을 경우, 
    리눅스 커널 내의 기능인 타이머 리스트를 직접 이용할 수 없음
    따라서, 시그널을 이용하여 제한 시간을 등록함

  - 사용자 프로세스는 시그널 핸들러 내에 제한시간을 등록
  - 절대 시간, 요청 프로세스의 실행(running) 시간을 지정함으로써 시그널 생성 요청을 등록할 수 있음
  - 지정한 시그널(SIGALARM, SIGTVLALRM, SIGPROF)이 생성되어 요청 프로세스에 전송

15. 절대 시간 지정타이머
  - 시스템에 설정된 절대 시간이 되면 시그널 발생(타이머 리스트로 구현됨)
  - alarm, setitimer 시스템 콜로 타이머를 등록
  Step 1. 시스템 콜 발생시 프로세스의 task_struct 구조체의 real_timer 멤버를 타이머 리스트에 등록
  Step 2. 지정한 시간이 경과하면 타이머 리스트에 등록한 it_real_fn 함수가 호출되고, SIGALARM 시그널을 생성
  Step 3.  시그널 발생 후, 핸들러를 타이머 리스트에 재등록

16. 실행 시간 지정 타이머
  - 프로세스가 실행한 시간(CPU 이용 시간)의 합계가 지정한 시간을 넘으면 시그널을 발생
  - 로컬 타이머 인터럽트 핸들러는 해달 CPU 상에서 동작하고 있는 프로세스의 실행시간을 측정해서 지정한 
    시간이 지나면 시그널을 발생함(check_process_timers 함수)
  - 파라미터
    ITIMER_VIRTUAL: setitimer 시스템 콜 호출시 현재 작업 프로세스의 사용자 모드에서의 실행 
    시간 만을 합산 지정된 시간마다 주기적으로 SIGVTALARM 시그널을 발생 
    ITIMER_PROF: setitimer 시스템 콜 호출 시 실행시간(사용자/커널모드 양쪽의 실행시간)을 합산해 지정된 
   시간마다 주기적으로 SIGPROF 시그널을 발생하고, SIGPROF 시그널은 주로 정보 수집(Profiling)에 이용됨  

17. POSIX 타이머
  - POSIX 타이머 시각 제어 함수
   clock_getres: 시간 정밀도 구함
   clock_gettime: 시간 구함
   clock_settime: 시간 설정

 - POSIX 구간 파이머(Interval Timer)
  timer_create: 지정한 프로세스용의 구간 타이머 생성
  timer_delete: 구간 타이머 삭제
  timer_settime: 구간 타이머 등록
  timer_gettime: 구간 타이머 상태 구함
  clock_nanosleep: 나노초 단위로 지정할 수 있는 nanosleep 시스템 콜