据我所知,如果IRQL级别是分派,那么您可以从非分页池访问内存。如果我们将尝试从分页池访问内存。只是想知道为什么?
答案 0 :(得分:5)
"为什么我们可以在DISPATCH LEVEL及以上的非分页池中访问内存"是一个声明,问题是为什么我们无法从分页池IRQL访问内存> = DISPATCH_LEVEL?
嗯...
"任何运行大于IRQL APC_LEVEL的例程都可以 既不从分页池分配内存也不在分页中访问内存 安全地游泳。如果IRQL运行的例程大于APC_LEVEL 导致页面错误,这是一个致命的错误。"
- http://msdn.microsoft.com/en-us/library/windows/hardware/ff554368(v=vs.85).aspx
为什么:
假设您的驱动程序正在处理中断,而在此处,它会保持旋转锁定。现在,您希望访问驻留在页面缓冲池中的某些数据结构,并且由于运气不佳,该数据位于已由内存管理器分页的页面上。
现在,您的驱动程序必须等到内存管理器页面输入您的数据。你正在阻止/等待/睡觉,实际上你的司机是。
现在,又发生了另一个中断,但由于您仍在等待数据被分页,您认为现在会发生什么?
知道这一点,
"持有不必要的长时间旋转锁可能会受到伤害 全系统的表现。"
当你的驱动程序等待更长时间发生某事时,你的内核将会冻结。
另外,
"请注意,在持有自旋锁时线程可能不会阻塞,因为 这可能会导致死锁。此外,在给定的情况下禁用抢占 处理螺旋锁时的处理器。"
无论如何,请进一步阅读:
"在IRQL上运行的驱动程序代码> PASSIVE_LEVEL应该执行为 尽快。例程运行的IRQL越高, 更重要的是调整该例程以获得良好的整体性能 尽快执行。例如,任何调用的驱动程序 KeRaiseIrql应该尽快对KeLowerIrql进行相互调用 它可以。"
- http://msdn.microsoft.com/en-us/library/windows/hardware/ff554368(v=vs.85).aspx
页面错误是需要由内存管理器快速处理的异常。当你的驱动程序持有螺旋锁并保持处理器人质时,该处理器就像现在一样好。
MSDN说:
"当驱动程序例程持有自旋锁时,它不会导致硬件 异常或引发软件异常而不降低 系统。换句话说,驱动程序的ISR和任何SynchCritSection 驱动程序在调用KeSynchronizeExecution时提供的例程 不得导致故障或陷阱,例如页面错误或算术 异常,并不能引发软件异常。一个调用的例程 KeAcquireSpinLock或KeAcquireInStackQueuedSpinLock也无法造成 硬件异常或引发软件异常,直到它有 发布了执行自旋锁,不再运行IRQL = DISPATCH_LEVEL"
- http://msdn.microsoft.com/en-us/library/windows/hardware/ff559854(v=vs.85).aspx
所有这些都回答将会发生什么,或者会发生什么。至于回答为什么我们不能使用上面的分页存储器或在DISPATCH_LEVEL:
我试图获取尽可能多的相关信息,如果你还没有出售,请尝试阅读自旋锁,重入函数,中断处理,分页。尝试阅读Linux,Windows和Apple的操作系统内核。他们都用不同的细节说同样的事情。