Top Half
- 인터럽트가 발생한 후 빨리 처리해야 하는 루틴
- 인터럽트 핸들러에서는 간결한 연산 수행 권장
- 인터럽트 핸들러의 실행 시각 측정 요망
Bottom Half
- 지연해도 되는 인터럽트의 인터럽트 처리
- Top Half 부분의 인터럽트 핸들러는 최소한의 일을 수행하고 약간 지연되
어 처리되어도 상관 없는 부분은 Bottom Half에서 처리
디바이스 드라이버에서는 다음과 같은 요구 사항이 생김
- 인터럽트가 발생한 후 처리해야 할 동작이 많을 때가 있다.
- 인터럽트 핸들러는 빨리 실행돼야 한다.
대안으로 인터럽트가 발생했을 때 인터럽트를 처리할 코드를 다음
과 같은 2단계로 분리
- 빨리 실행할 코드: 인터럽트 핸들러 및 인터럽트 컨텍스트에서 실행
- 실시간으로 빨리 실행되지 않아도 되는 코드: 인터럽트 후반부 기법 적용
터치 인터럽트 핸들러 (Top Half)
- 터치 페리퍼럴에게 인터럽트의 처리에 대한 ACK 동작
후반부로 처리(Bottom Half)
- 터치 좌표를 계산해 유저 공간에 uevent로 전달
- 터치 디바이스 드라이버 관련 도메인(멀티 터치 프로토콜, I2C)
인터럽트 후반부 처리 기법
- 대부분 RTOS 및 임베디드 시스템에서 지원 (드라이버의 요구 사
항)
- 리눅스 커널에서도 다양한 인터럽트 후반부 기법 지원
인터럽트 핸들러에서 실행 시간이 오래 걸리면?
실행 시간이 오래 걸리는 코드 예시
- I/O을 시작하는 코드
- 과도한 while 반복문
- 유저 공간으로 uevent를 전달해서 인터럽트 발생을 알림
- 스케줄링을 지원하는 커널 함수를 호출
커널 패닉 예시 부분 필기
- 아래에서 위 방향
- 32비트 기반의 리눅스 커널에서 인터럽트 실행
- 스케줄 함수 => 스케쥴 버그에서 패닉이 발생
- 1039 : pid, 이후, 00010001 : 인터럽트 컨텍스트에서 스케쥴 함수를 호출해서 패닉이 유발했다.
- "scheduling while atomic" 메시지의 의미
- 아토믹 도중에 스케줄링을 수행 중임
- 아토믹은 어떤 코드나 루틴이 실행 도중 스케줄링을 수행하면 안
되는 컨텍스트
threaded IRQ
- 인터럽트를 처리하는 전용 IRQ 커널 스레드에서 Bottom-Half 처리
- "mmc0"라는 88번 인터럽트가 있으면 "irq/88-mmc0"란 IRQ 스레드가
88번 인터럽트 후반부를 전담해 처리
Soft IRQ
- 인터럽트 핸들러 실행이 끝나면 바로 실행 시작
- 인터럽트 핸들러에서 바로 처리해야 할 일을 마무리한 후 후반부를 Soft
IRQ 컨텍스트에서 처리
- Soft IRQ 서비스 핸들러의 실행 도중 시간이 오래 걸리면 ksoftirqd 프로
세스를 깨우고(Soft IRQ 서비스를 종료), ksoftirqd라는 프로세스에서 나
머지 인터럽트 후반부 처리
태스크릿
- Soft IRQ 서비스를 동적으로 쓸 수 있는 인터페이스이자 자료구조
워크큐
- 인터럽트 핸들러가 실행될 때 워크를 워크큐에 큐잉하고 프로세스 콘텍스
트에서 실행되는 워커 스레드에서 인터럽트 후반부 처리
인터럽트 후반부 처리
- IRQ가 인터럽트 핸들러의 실행을 마무리하고 인터럽트를 실행하는 코드로 복귀
- IRQ스레드는 우선순위가 높은 프로세스
주요 인터럽트 후반부 기법
IRQ란
- Interrupt Request의 약자로 페리퍼럴에서 발생한 인터럽트를 처리한다
는 의미
- 인터럽트가 발생한 후 인터럽트 핸들러까지 처리되는 흐름과 루틴
IRQ 스레드란?
- 인터럽트 후반부 처리를 위한 인터럽트 처리 전용 프로세스
- IRQ 스레드 기법은 인터럽트 후반부 처리를 IRQ 스레드에서 수행하는 방식
- 리눅스 커널 커뮤니티에서는 irq_thread 혹은 threaded IRQ 방식으로 부
름
IRQ 스레드 방식의 특징
- 실전 프로젝트에서 많이 사용됨
- IRQ 스레드는 RT 스레드로 우선 순위가 높음
- 라즈비안 커널에서는 IRQ 스레드가 많지 않음
IRQ 스레드는 언제 생성할까?
- 디바이스 드라이버의 초기화 코드(부팅 과정)에서
request_threaded_irq() 함수를 호출해 IRQ 스레드를 생성
- IRQ 스레드는 생성된 후 시스템 전원이 공급돼 동작하는 동안 해
당 인터럽트 후반부를 처리하는 기능을 수행
- irq_handler_t : top half
)
Soft IRQ 소개
- Soft IRQ는 리눅스 커널을 이루는 핵심 기능 중 하나임
- Soft IRQ 서비스의 형태로 커널을 구성하는 주요 서브 시스템(타이머, 스케
줄러, 네트워크, UFS 드라이버) 시스템이 동작
- Soft IRQ는 인터럽트 후반부 기법(태스크릿)으로 사용됨
Soft IRQ 서비스란
- 후반부 기법의 관점
- 인터럽트 유발 => 소프트 IRQ 서비스에 대한 실행 요청 => 인터럽트 핸들러의 실행흐름을 마무리 한 후 => IRQ EXIT함수 (소프트 IRQ서비스에 대한 요청 체크) => 요청이 있으면 소프트 IRQ 서비스 핸들러를 실행해서 인터럽트의 후반부를 처리, 실행시간이 오래 걸리면 소프트 IRQ 서비스를 처리하기 위한 용도로 생성된 데몬 프로세스를 깨우고 돌아간다. => ksoft 데몬 프로세서가 소프트 IRQ 서비스를 처리한다.
디버깅
- irq exit rcu에서 soft IRQ 서비스 요청을 확인한다.
- TIMER의 요청이 있었기 때문에 실행이 된다.
- run timer soft irq 서비스 함수가 호출됨
워크큐란
-인터럽트 후반부 기법으로 사용됐으나 전반적인 후반부 기법으로 사용되는
기법
- 실행 시각에 민감한 후반부를 처리하는 용도로 워크큐의 워크를 사용하는
것은 적합하지 않음
드라이버 레벨에서 워크는 쓰기 용이
- 워크는 work_struct 구조체 변수만 설정하고 워크를 실행할 코드에
queue_work() 혹은 schedule_work() 함수만 추가
- 워크큐를 쓰면 드라이버를 조금 더 유연하게 설계할 수 있음
- 지연해서 후반부로 처리할 코드를 워크를 통해 처리
인터럽트 후반부 코드의 설계 원칙
- 인터럽트 핸들러로 빨리 처리해야 할 코드를 수행한 후 워크를 워크큐에 큐잉
- 인터럽트 후반부로 처리해야 할 코드를 워크 핸들러에서 처리
[인터럽트 핸들러]
- ① 인터럽트를 발생한 하드웨어에 인터럽트를 잘 받았다고 알림
- ② 인터럽트를 처리했다는 플래그 정보를 업데이트함
- ③ 워크를 큐잉
[워크 핸들러]
§ ④ 유저 공간에 인터럽트로 하드웨어가 변경된 사실을 알림
§ ⑤ 인터럽트를 처리했다는 사실을 디버깅 자료구조에 남김
워커 스레드
워커 스레드란?
- 워커 스레드는 워크를 실행하고 워크큐 관련 자료구조를 업데이트하는 커널
스레드
- 워커 스레드의 세부 동작 방식은 worker_thread() 함수에 구현돼 있음
- 워커 스레드의 이름은 "kworker/"로 시작하며 워커풀의 종류에 따라
"kworker/" 다음에 번호를 부여
워크큐 디버깅
- sched wakeup : 워커스레드를 깨우는 이벤트
- kworker/u8:1이 깨어남
- 깨어나고 flush ... 워크 핸들러 함수를 호출
- 호출 직전에 워크큐 execute start, 마무리시 end
- 시간의 차이 : 워크 핸들러의 실행 시간