为什么我们可以在DISPATCH LEVEL或以上的非分页池中访问内存

MM *_*WDD 1 windows kernel ndis driver wdm

据我所知,如果IRQL级别是调度,那么您可以从非分页池访问内存.如果我们将尝试从分页池访问内存.只是想知道为什么?

小智 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

为什么是这样:

假设您的驱动程序正在处理中断,而在此处,它会保持旋转锁定.现在,您希望访问驻留在页面缓冲池中的某些数据结构,并且由于运气不好,该数据位于已由内存管理器分页的页面上.

现在,您的驱动程序必须等到内存管理器页面输入您的数据.你正在阻止/等待/睡觉,实际上你的司机是.

现在,发生了另一个中断,但由于您仍在等待数据被分页,您认为现在会发生什么?

知道这个,

"持续不必要的长时间旋转锁定会损害整个系统的性能."

当你的驱动程序等待更长时间发生某事时,你的内核将会冻结.

也,

"请注意,线程可能不会在持有自旋锁时阻塞,因为这可能会导致死锁.此外,在保持自旋锁的情况下,在给定处理器上禁用抢占."

- https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/KernelProgramming/synchronization/synchronization.html

无论如何,请进一步阅读:

"在IRQL> PASSIVE_LEVEL上运行的驱动程序代码应该尽快执行.例程运行的IRQL越高,调整该例程以尽快执行的整体性能就越重要.例如,任何调用KeRaiseIrql的驱动程序应尽快对KeLowerIrql进行相互调用."

- http://msdn.microsoft.com/en-us/library/windows/hardware/ff554368(v=vs.85).aspx

页面错误是需要由内存管理器快速处理的异常.当你的驱动程序持有螺旋锁并保持处理器人质时,该处理器就像现在一样好.

MSDN说:

"虽然驱动程序例程持有自旋锁,但它不会导致硬件异常或引发软件异常而不关闭系统.换句话说,驱动程序的ISR和驱动程序在调用KeSynchronizeExecution时提供的任何SynchCritSection例程都不能导致一个错误或陷阱,例如页面错误或算术异常,并且不能引发软件异常.调用KeAcquireSpinLock或KeAcquireInStackQueuedSpinLock的例程也不会引发硬件异常或引发软件异常,直到它释放其执行自旋锁定为止不再以IRQL = DISPATCH_LEVEL运行."

- http://msdn.microsoft.com/en-us/library/windows/hardware/ff559854(v=vs.85).aspx

所有这些都回答了会发生什么,或者会发生什么.至于回答为什么我们不能使用上面的分页存储器或在DISPATCH_LEVEL:

  1. 它在大多数情况下导致死锁,这在内核世界中是内核崩溃.
  2. 它会在内核中引发延迟,这很糟糕.
  3. 参见1,这很重要.

我试图获取尽可能多的相关信息,如果你还没有出售,请尝试阅读自旋锁,重入函数,中断处理,分页.尝试阅读Linux,Windows和Apple的操作系统内核.他们都用不同的细节说同样的话.