1. Interrupt
저번시간의 마지막 부분을 이어서 설명하겠다. 그전에 우선 IRQ 라인에 의해서 CPU가 인터럽트에 걸리는 3가지 경우가 존재한다는걸 알고가자. 이미 설명한 케이스이다.
- 만약 현재 요청들어온 IRQm 라인에 일을 해주고 있는 CPU가 없으면 그냥 CPU0 가 처리해준다.
- CPU0가 IRQm 라인을 처리하고 있는 도중에 동일한 IRQm라인의 요처이 들어와서 CPU1이 처리해주려고한다. IRQm라인의 status는 현재 IRQ_Inprogress 비트가 세팅되어있기 때문에 이를 확인하고 IRQ_pending bit을 추가로 세팅한다음 종료된다.
- CPU1이 IRQm 의
handle_IRQ_event()
함수를 수행하고 이는 do-while이다. 이게 끝나면 for문에서 다시한번 IRQ_pendding bit을 체크한다. 분명 그전에 끄고 왔지만 이게 세팅되었다는 뜻은, 동일한 라인에서 또 요청이 들어왔다는 놈이고, 다른 CPU가 나에게 처리부탁을 요청했다는 의미이다. 그럼 다시 for문으로 돌아가handle_IRQ_event()
를 수행한다.
이제 위 과정을 정리해보자.
- APIC의 IRQ lines에 여러 디바이스들이 물려있다. IRQm 라인을통해 특정 디바이스가 인터럽트 요청을 보낸다.
- APIC에서는 현재 CPI(i)와 CPI(k) 둘중 CPU(i) 를 선택한다. 따라서 CPU(i)의 counter는 0가 된다. (counter에 대한 설명은 이전 강의를 참고바람)
- CPUi는 irq_desc[m].status의 waiting 필드를 지우고 pennding으로 업데이트한다.
- 이제 어떤 CPU가 해당 인터럽트를 처리할지 선택한다. 이는 위에서 설명한 케이스에 따라서 달라진다.
- Case A : 어떠한 CPU도 IRQm을 처리하고 있지 않으면, CPU(i)가 바로 해줌. ⇒Let CPU(i) handle IRQm
- Case B : 다른 CPU(k)가 이미 IRQm을 처리하고 있으면, irq status에 Inprogress status를 추가하고, CPU(k)에게 요청을 넘긴다. ⇒ Let CPU(k) handle IRQm
2. Race Condition
이러한 do_iqr() 함수 로직은 많은 민폐를 끼치게 된다. 여기서 말하는 민폐는 요청에 대한 ACK가 오기 전까지 PIC는 block이되고, 또 IRQ 라인은 공유 메모리로 사용되기 때문에 lock이걸리면 다른 CPU는 사용하지 못하는 것들을 말한다.
이렇게 민폐를 끼치는 영역은 주로 Critical_section
에서 발생한다. 따라서 해당 영역은 매우 신속한 처리를 필요로한다. 이러한 신속한 처리를 필요로 하는 영역을 Top-Half 영역이라고 부른다. 이는 하드웨어에 시작되는 영역이다
이에 반해 Non-Critical_section
Top-Half 영역보다는 block되는 리소스같은게 적긴하다. 하지만 이 역시도 민폐를 키칠수 있는 상황이 존재한다.
만약 현재 handle_IRQ_event() 에서 처리해야하는 작업이 디스크에서 200TB를 가져와라! 라는 요청이면 어떨까?. 매우 사이즈가 큰 작업이므로 신속한 처리를 하지 못한다. 따라서 한번에 처리하지 못하는 작업을 후에 다시 처리할수 있도록 soft-iqr pending bit
를 세팅한다.
해당 비트가 설정되어 있으면 후에 do_softirq() 에 의해서 남은 작업을 다시 수행하도록 소프트웨어적으로 구현되어있다. 이러한 메커니즘은 Bottom Half
라고 부른다.
즉 Top Half는 하드웨어의해 실행되고, Bottom Half는 소프트웨어에 의해 실행되는 로직을 갖는다. Bottom Half의 실 예를 한번 봐보자.
현재 NIC 즉 네트워크 인터페이스 카드에서 인터럽트 요청이 들어왔다. 무선 랜카드 같은곳에서 현재 어떠한 패킷을 받고 해당 패킷을 처리하기 위한 인터럽트 요청일것이다.
그럼 PIC는 특정 CPU를 선택하고 CPU에서는 do_IRQ()를 호출한다. do_IRQ()에서는 초기에 ack를 PIC에 보내 다른 인터럽트를 처리할수 있도록 하고, irq_desc[IRQm] status를 업데이트한다. 메모리에 복사된 패킷을 확인하여 재조립후 하나의 스트림으로 하여 패킷 요청이 실행된다. 만약 ftp 관련 패킷이면 ftp 관련 작업을 할것이다.
위 과정은 하나의 Top-Half에서 다 수행되는게 아니다.
NIC로부터 요청이 오고, do_irq() 즉, 초기엔 Top-Half가 수행된다. Critical Top half가 수행되면서, ACK를 보내고, NIC의 패킷을 저장한 버퍼를 만들고, 거기에 패킷을 복사한다. 실제 패킷의 동작 처리는 bottom-half에서 진행되게끔 soft-iqr pending bit
를 세팅한다.
그 이후 정상적으로 다른 인터럽트들을 쭉 실행한다. 그러면서 중간중간 CPU가 처리할 작업을 우선순위를 보고 선택하게 되는데, 그때 soft-irq-pending-bit
가 세팅되어있는 놈을 보면, do_softiqr()를 실행시킨다. 여기서 실제 패킷에 대한 처리가 수행된다.
이러한 일련의 과정을 다음 그림으로 정리할수 있다
3. 정리
ISR 루틴이 수행될때 부하가 큰 작업은 신속한 처리를 위해 do_softirq() 함수를 이용해서 처리를 한다. 따라서 Top-half, Bottom-half 가 무엇인지 이제 구분할수 있다. 다음에는 Bottom-half 를 중점적으로 설명하겠다.
'컴퓨터 관련 과목 > 운영체제 & 커널' 카테고리의 다른 글
kernel of linux - File system of Unix(1) (0) | 2020.10.01 |
---|---|
kernel of linux - interrupt(3) (0) | 2020.09.30 |
kernel of linux - interrupt(1) (0) | 2020.09.29 |
kernel of linux - interrupt(0) (0) | 2020.09.28 |
kernel of linux - Process Mangement(2) (0) | 2020.09.26 |
Uploaded by Notion2Tistory v1.0.0