리눅스 커널 인터럽트 흐름 (Interrupt Flow)


  1. Process 수행 중 device에서 인터럽트 발생
  2. 돌고 있던 process의 context가 저장됨
  3. 인터럽트 핸들러 진입. 이때부터 인터럽트 context 이다. 인터럽트 context에서는 context switch가 불가한데, 이는 현재 수행중인 작업을 그만두고 CPU를 놔버리면 안 된다("블로킹 함수를 부르면 안 된다"라고도 함)는 뜻. 인터럽트 핸들러 동작을 모두 끝내고 IRET를 통해서만 CPU를 그만 독점해야한다.
  4. IRQ disable하여 다른 인터럽트 핸들러가 수행되지 않도록 함. 
  5. 해당 인터럽트에 맞는 디바이스들의 핸들러 들이 동작함
  6. IRQ enable하여 다른 인터럽트 핸들러 동작을 허용. 여기까지가 인터럽트 전반부 작업이다 (Top half).
  7. 수행할 softirq나 tasklet이 있다면 후반부 작업을 바로 수행 (이때 IRQ는 enable 상태이므로 다른 인터럽트 핸들러가 끼어들 수 있다.)
  8. 일을 모두 마쳤다면 IRET instruction이 수행되어 저장된 context를 불러와서 기존에 돌던 process를 재시작(resume). 이때 인터럽트 context에서 process context로 전환된다.
  9. 만약 돌아야 하는 workqueue나 지연된 softirq가 있다면 스케줄링 되었을 때 수행됨. 이때 softirq는 단시간 내에 끝나지 않아서, IRET 전에 중지되었던 softirq 이다. 이런 지연된 softirq는 ksoftirqd 커널 스레드에 의해 실행되며 프로세스 컨텍스트에서 수행된다. workqueue 또한 프로세스 컨텍스트에서 수행된다.


용어

maskable: 대부분의 인터럽트, 인터럽트가 disable 되어있으면 일시적으로 interrupt handler가 도는 것을 연기할 수 있음.

non-maskable: 몇 몇 critical interrupts는 disabled 되거나 연기될 수 없다.


Nested interrups and exceptions 조건

  • exception (e.g. page fault, system call) 이 interrupt 도중 끼어들면 (preempt) 안된다.
  • interrupt 는 exception 도중 끼어들 수 있다.
  • interrupt 는 다른 interrupt 도중 끼어들면 안된다.

댓글