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 서비스란

  • Soft IRQ를 처리하는 단위

  • 부팅 과정에서 open_softirq() 함수를 호출해 Soft IRQ 서비스를 등록

  • 핵심 : 핸들러 => 벡터안에 설정

  • 소프트 IRQ 서비스가 실행이 된다 : 이 함수가 호출이 되어 내부의 코드가 실행이 된다.

  • 후반부 기법의 관점
    1. 인터럽트 유발 => 소프트 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
  • 시간의 차이 : 워크 핸들러의 실행 시간

0개의 댓글