小智 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和驱动程序在调用KeSynchronizeExecution时提供的任何SynchCritSection例程都不能导致一个错误或陷阱,例如页面错误或算术异常,并且不能引发软件异常.调用KeAcquireSpinLock或KeAcquireInStackQueuedSpinLock的例程也不会引发硬件异常或引发软件异常,直到它释放其执行自旋锁定为止不再以IRQL = DISPATCH_LEVEL运行."
- http://msdn.microsoft.com/en-us/library/windows/hardware/ff559854(v=vs.85).aspx
所有这些都回答了会发生什么,或者会发生什么.至于回答为什么我们不能使用上面的分页存储器或在DISPATCH_LEVEL:
我试图获取尽可能多的相关信息,如果你还没有出售,请尝试阅读自旋锁,重入函数,中断处理,分页.尝试阅读Linux,Windows和Apple的操作系统内核.他们都用不同的细节说同样的话.
| 归档时间: |
|
| 查看次数: |
1961 次 |
| 最近记录: |