使用内核堆栈

内核模式堆栈的大小限制为大约三页。 因此,将数据传递给内部例程时,驱动程序不能在内核堆栈上传递大量数据。

若要避免内核模式堆栈空间不足,请使用以下设计准则:

  • 如果每个例程在内核堆栈上传递数据,请避免从一个内部驱动程序例程向另一个内部驱动程序例程进行深度嵌套调用。

  • 如果设计的驱动程序具有递归例程,请确保限制可能发生的递归调用数。

换句话说,驱动程序的调用树结构应该是相对平坦的。 可以调用 IoGetStackLimitsIoGetRemainingStackSize 例程来确定可用的内核堆栈空间,或 调用 KeExpandKernelStackAndCallout 将其展开。 请注意,内核模式堆栈的大小可能因不同的硬件平台和操作系统的不同版本而异。

内核堆栈空间不足会导致严重的系统错误。 因此,驱动程序 分配系统空间内存 比耗尽内核堆栈空间更好。 但是,非分页池也是有限的系统资源。

通常,内核模式堆栈驻留在内存中,但如果线程进入指定用户模式的等待状态,它偶尔会被分页。 有关如何暂时禁用当前线程的内核堆栈分页的信息,请参阅 KeSetKernelStackSwapEnable 。 出于性能原因,不建议全局禁用内核堆栈分页,但如果要在调试会话期间禁用内核 堆栈分页,请参阅禁用内核堆栈的分页

由于内核堆栈可能已分页,因此请谨慎将基于堆栈的缓冲区 (即) 局部变量传递给 DMA 或在 DISPATCH_LEVEL 或更高版本上运行的任何例程。