Linux(Centos or RHEL)/RHEL 기초

인터럽트에서의 전반부 처리(Top Half)와 후반부 처리(Bottom Half)?

최소양 2020. 4. 27. 16:39

아래의 블로그 및 리눅스 커널 심층 분석 3(로버트 러브)를 참고하여 글을 작성하였습니다.

https://poplinux.tistory.com/126

 

[kernel] Top Half? Bottom Half? context?

Top Half? Bottom Half? 이게 뭐하는 녀석이지? 용어만 보면 정확히 어떤 개념인지 와닿지가 않습니다. HW 인터럽트가 발생하였다고 가정하고, 인터럽트가 발생하면 보통 아래와 같이 처리를 하게 됩니다. step 1...

poplinux.tistory.com

 

 

HW 인터럽트가 발생하였다고 가정하고, 인터럽트가 발생하면 리눅스에서는 보통 아래와 같은 처리를 하게 됩니다.

 

step. 1 인터럽트 disable

step. 2 해당 인터럽트에 관련된 기능 동작

step. 3 인터럽트 enable

 

인터럽트가 발생하게 되면 우선 인터럽트 기능 자체를 disable 하게 됩니다.

지금 발생한 인터럽트에 관련된 기능을 모두 처리하기 전까지는 다른 인터럽트들은 무시하기 위해서입니다.

인터럽트에 대한 처리가 모두 완료되면 인터럽트 기능을 enable하고 기능을 종료하게 됩니다.

 

하지만, 인터럽트를 처리하는 동안 커널은 인터럽트 컨텍스트에 있는 상태이므로, 인터럽트 처리를 선점한다든가, 잠시 멈추는 것은 불가능하다. 따라서 인터럽트를 처리하는 시간이 길면 길수록 시스템이 멈춘 것처럼 보일 수 있습니다.

예를 들면, 네트워크 장치의 인터럽트를 처리하기 위해 커널이 실행하는 함수(인터럽트 핸들러)를 생각해 보면 될 것 같습니다. 하드웨어에 응답을 보낸 다음, 인터럽트 핸들러는 네트워크 패킷을 하드웨어에서 메모리로 복사하고, 처리 작업을 수행한 다음 애플리케이션이나 프로토콜 스택으로 패킷을 옮겨야 합니다. 이 모든 작업은 상당한 시간이 걸릴 것이며, 요즘처럼 이더넷 기기의 속도가 빠른 환경이라면 더 오랜 시간이 걸릴 것입니다.

 

이러한 상황을 개선하고자 전반부 처리(Top half)와 후반부 처리(Bottom half)라는 개념이 생기게 되었습니다.

전반부 처리(Top half)는 인터럽트 핸들러가 담당하고, 인터럽트를 받은 즉시 실행되며, 인터럽트 수신 확인이나 하드웨어 재설정처럼 처리시한이 중요한 작업만을 처리합니다.

나중에 할 수 있는 일은 후반부 처리(Bottom half)로 지연시킵니다. 리눅스에서는 후반부처리를 아래와 같이 다양한 방법으로 구현해 놓았습니다.

http://jake.dothome.co.kr/two-part-interrupt-handler/

 

Bottom halves

Task queues

Softirq

Tasklet

Work queues

 

 

앞에서 이야기했던 네트워크 장치의 경우를 통해 전반부 처리와 후반부 처리의 예를 살펴보겠습니다.

 

네트워크 카드가 패킷을 수신하면 커널에 이 사실을 알려야 합니다. 네트워크 전송량과 지연시간을 최적화하고, 타임아웃을 막으려면 즉시 이 작업을 처리해야 합니다. 그러므로 즉시 인터럽트를 발생시켜서 커널에게 새로운 패킷이 왔다는 것을 알립니다. 커널은 이에 반응해 네트워크 장치에 등록된 인터럽트를 실행합니다.

 

인터럽트가 실행되면 하드웨어에 확인 신호를 보내고, 새로 수신한 네트워크 패킷을 주 메모리에 복사한 다음, 네트워크 카드를 다시 패킷을 수신할 수 있는 상태로 조정합니다. 이 작은업 시간에 민감하고 하드웨어에 의존적인 중요한 작업입니다. 왜냐하면, 네트워크 카드의 데이터 버퍼는 고정되어 있고, 주 메모리에 비해 크기가 작기 때문에, 커널은 네트워크 패킷을 주 메모리로 빨리 복사해야 하기 때문입니다. , 패킷 복사 작업이 지연되면 버퍼가 모자라 수신 패킷이 네트워크 카드의 버퍼를 넘쳐서 버려지는 일이 발생하기 때문입니다.

 

네트워크 데이터를 안전하게 주 메모리로 복사하면 인터럽트가 처리할 일은 끝나고 시스템 제어권을 인터럽트 발생으로 실행이 중단된 코드로 다시 돌려줍니다. 그리고 나머지 패킷 처리는 나중에 후반부 처리에서 진행됩니다.