<1> Interrupt handler와 bottom halves


커널에서 인터럽트 핸들러는 비동기적으로 시행되며, 선점될 수 없다.(=스케줄링될 수 없다.) 따라서 빠른 동작이 매우 중요한데, 이 때문에 반드시 처리해야 하는 일들만 처리하고 나머지 일들은 bottom halve로 미뤄서 실행하도록 한다. 여기에서 '어느 정도의' 일까지를 인터럽트 핸들러가 처리해야 하는지에 대한 명확한 규칙은 없다. 다만 가이드라인은 존재하는데 다음과 같다.


  • 시간에 민감한 일은 인터럽트 핸들러가 처리한다.

  • 하드웨어에 관련된 일은 인터럽트 핸들러가 처리한다.

  • 만약 해당하는 일이 다른 인터럽트 핸들러에 의해 인터럽트되지 않는 것이 보장되어야 할 경우, 인터럽트 핸들러가 처리한다.

  • 이외의 모든 일은 bottom half에서 처리한다. 



<2>Bottom halves는 언제 시행되나


bottom halves가 시행되는 특정한 시점은 정해져 있지 않다. "just not now", 커널이 덜 바쁘고 다른 모든 인터럽트에 대해 enable할 때 시행하도록 한다. 따라서 대개의 경우에는 인터럽트 핸들러가 수행을 마친 직후에 bottom halves로 수행된다.


<3>Bottom halves의 종류


가장 초기에 리누스가 구현한 것은 Bottom Halves이다. 보통 운영체제 전반의 용어로서의 bottom halves와 구별하기위해 리누스의 구현을 BH로 지칭한다. 이외에도 Task queues와 Softirq, Tasklet, Work queues 등이 있다. 커널 2.6을 기준으로, BH와 Task Queues는 사용되지 않으며, 나머지 3가지가 사용된다, 아래에서 각각의 구현에 대해 설명하도록 하겠다.


<4>Softirqs(Soft IRQ)


정적으로 컴파일 타임에 정의되며 최대 32개의 softirq가 선언될 수 있다. 2.6커널을 기준으로 현재 9개를 사용중이다. 병렬적으로 어떤 프로세서에서든 실행 가능하며 이 때문에 lock에 관해 까다로운 구현이 필요하다. 따라서 performance-critical한 인터럽트에 대해서만 사용하며 현재는 network와 block device만이 직접적으로 softirq를 사용한다. 인터럽트 핸들러가 해당 softirq를 mark하면(=raising the softirq) 이후 적당한 시간에 실행된다.


<5>Tasklets


Tasklet은 softirq의 위에서 구현되었다. 보다 간편한 인터페이스와 가벼운 locking rule을 제공하며, 특별히 performance-critical한 인터럽트가 아닌 경우에는 tasklet을 사용하도록 한다. 즉 대부분의 인터럽트는 softirq가 아닌 tasklet을 사용한다. Static하게도 선언 가능하며 softirq와 달리 dynamic하게도 선언가능하다. 또한 softirq와 다르게 같은 tasklet이 같은 프로세서에서 동시에 실행될 수 없다. 다른 프로세서에서는 가능하다. 이 덕분에 병렬 프로그래밍을 덜 고려해도 되는 장점을 지닌다.


<6> Work Queue


Softirq나 tasklet과 다르게, work queue는 프로세스 컨텍스트에서 실행된다. 따라서 work queue는 스케줄링이 가능하며 휴면 상태로 전환될 수 있다. 또한 프로세스 컨텍스트에서 실행되므로 disable을 할 필요가 존재하지 않는다.




<참고>

http://onecellboy.tistory.com/52



+ Recent posts