Maystyle :
Admin : New post
Guestbook
Local
media
Catergories
Recent Articles
Recent Comments
Recent Trackbacks
Calendar
Tag
Archive
Link
Search
 
  지루한 인터럽트 한방에 알아보자 
작성일시 : 2007. 11. 12. 21:03 | 분류 : Windows Server/Kernel

 

인터럽트나 Exception이 발생하면 커널은 기존 처리 중 이던 Thread를 커널 스텍에 Trap Frame을 만들어 상태를 처리하고, Trap Handler를 호출하여 해당 Trap을 처리한다. ( 알수 없거나 처리 할 수 없을 경우 KeBugCheckEx를 호출 하고 정지 )

덤프 미 생성시 블러스터 웜/ Disk Array Controller / CPU / Memory / 메인 보드 를 확인 해야 한다.

하드웨어 인터럽트 처리

이전 포스트들을 잘 읽어 봤다면, 용어에 대하여 별도로 설명할 필요는 없을꺼 같다.하드웨어 인터럽트가 발생하면 위와 같은 순서로 처리된다. 또한 CPU는 여러 ISR에 대하여, 개별 적으로 처리가 가능하다.

PIC
http://maystyle.tistory.com/entry/Programmable-Interrupt-Controller
IDT
http://maystyle.tistory.com/entry/IDT-살펴-보기

Windows 에서 인터럽트의 처리 (IRQL)

IRQL에 대해서는 이전 포스트(http://maystyle.tistory.com/entry/IRQL)에서 다뤘다 시피 인터럽트에 대한 처리 우선 순이라 할 수 있다. 즉 더 높은 순위의 인터럽트는 낮은 순위의 인터럽트를 마스크(블럭 시키고 자기가 실행 된다.) 한다. 높은 인터럽트가 발생하면 기 실행 Thread는 저장되고 해당 인터럽트와 연결된 Dispatcher들을 실행 한다.

인터럽트가 발생 > CPU의 IRQL을 높힘 > CPU에서 인터럽트 처리 > CPU의 IRQL을 원상 복귀 시킴
(현재 IRQL 확인 : http://maystyle.tistory.com/entry/현재-CPU의-IRQL을-살펴보자)

중요한건 IRQL을 통해서 PIC와 통신 비용을 줄일 수 있다는 거다. (이 부분은 나만의 유추다) 일단 PIC는 3개의 레지스터를 가지고 인터럽트 프로세스를 진행한다.
IRR - Interrupt Request Register
ISR - Interrupt Service Register
IMR - Interrupt Mase Register
로직은 IRR에서 인터럽트를 요구 할때 IMR와 IRR 값을 비교하여 처리되어야 한다면 ISR 단계로 넘어가게 된다. 그런데, 문제는 HAL에서 IMR을 설정하는 작업이 굉장이 느리다는 것다. (H/W의 인터럽트는 HAL이 IRQL에 Mapping 한다.)그래서 굳이 PIC까지 가서 IMR을 설정하지 않고, IRQL을 만들어 놓고, HAL 단에서 IRQL만 건들여서 우선 순위를 설정하게 된다.

커널 모드 스레드는 자신이 실행하려는 작업에 따라 IRQL을 높히게 된다. 그래서 장치 인터럽트시  커널 및 장치 드라이버는 왠만하면 Passive 수준을 유지하여, 인터럽트를 빠르게 처리하려 한다.

방금 언급한 것 처럼 PIC에서 정의된 IRQ와 IRQL은 다르다. 솔직히 Windows는 IRQ와 별계로 IRQL을 통해 서비스 우선 순위를 결정한다. 그렇다면 어떻게 누가 결정할까? 바로 HAL에서 HalpGetSystemInterruptVector를 호출하여 매핑한다. 이전 포스트를 참고 하자. http://maystyle.tistory.com/entry/인터럽트를-IRQL에-매핑하기

DPC 계층 이상에서 코드가 실행 중일 경우 CPU는 다른 스케줄러를 실행 할 수 없다. 없는데 그런 경우가 생기니깐 장애가 생기는 것이다. DPC는 이전 포스트를 참고 하자. (http://maystyle.tistory.com/entry/DPC-Deferred-Procedure-call)

원문을 참고 하자.
One important restriction  on code running at DPC/dispatch level or above is that it can't wait for an object  if doing so would necessitate the scheduler to select another thread to execute , which is an illegal operation / because the scheduler synchronizes its data structures at DPC/ dispatch level and cannot therefore be invoked to perform a reschedule. Another restriction is that only nonpaged memory can be accessed at IRQL DPC/dispatch level or higher. / This rule is actually a side-effect of the first restriction because attempting to access memory that isn't resident results in a page fault. When a page fault occurs, the memory manager initiates a disk I/O and then needs to wait for the file system driver to read the page in from disk. This wait would in turn require the scheduler to perform a context switch (perhaps to the idle thread if no user thread is waiting to run), thus violating the rule that the scheduler can't be invoked (because the IRQL is still DPC/dispatch level or higher at the time of the disk read). If either of these two restrictions is violated, the system crashes with an IRQL_NOT_LESS_OR_EQUAL crash code. (See Chapter 4 for a thorough discussion of system crashes.) Violating these restrictions is a common bug in device drivers. The Windows Driver Verifier, explained in the section "Driver Verifier" in Chapter 7, has an option you can set to assist in finding this particular type of bug.

본문의 예를 들자면 DPC/디스패치 수준은 무조건 Nonpaged Memory에서 수행되는 것이다.  즉 DPC의 오브젝트들은 메모리에 저장이 되는데, 만약 Page Fault가 발생하게 되면 어떻게 될까? 그렇게 되면 분명 Disk에서 해당 object를 읽어 와야 하고, 또 다시 인터럽트들이 발생하게 된다. 그러면 다시 컨텍스트 전환이 일어나게 되며, 이는 on code running at DPC/dispatch level or above is that it can't wait for an object  를 어기게 된다. 이때 충돌 코드가 IRQL_NOT_LESS_OR_EQUAL이다. 순환 큐가 아닌 이상... 큐에 들어간 DPC는 수행되야 하며, 이에 컨텍스트 스위칭이 일어날 수 없다.

자 마지막으로 인터럽트 개체는 무엇일까?
다음 포스트를 참고하자 (http://maystyle.tistory.com/entry/인터럽트-개체)

|