我看到一篇文章写道:“APC_LEVEL当一个asynchsonous procedure call产生时,processor进入到APC_LEVEL。在这个level上,会无视其他的APC,屏蔽APC LEVEL的中断,比如,一些I/O completion APC。可以访问pagable memory。系统在APC_LEVEL处理缺页中断,所以,执行在>=APC_LEVEL上的代码必须存放在NON-PGAE内存中。”
可是又在MSDN上看到,“The routine using the corresponding paged-pool virtual addresses must be running at IRQL <= APC_LEVEL,if a page fault occurs while running at IRQL > APC_LEVEL, it is a fatal error.”
照MSDN上推断,缺页中断应该在DISPATCH_LEVEL ,因为只要是DISPATCH_LEVEL以下都可以是可分页的(paged)
!!请问Windows中的缺页中断处理是在那个中断级别啊,是APC_LEVEL吗 ,还是DISPATCH_LEVEL得???
楼上的理解有误,MSDN上面说了IRQL <= APC_LEVEL是可以处理page fault的,只有IRQL >= DISPATCH_LEVEL才不能处理页错误。具体原因,看看这本书:
《Microsoft Windows Internals, Fourth Edition》
By Mark E. Russinovich, David A. Solomon
Publisher: Microsoft Press
书中有这样一段话,解释得比较明白:
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.