设备驱动程序 IRQL 和线程/上下文切换
我是 Windows 设备驱动程序编程的新手。我知道某些操作只能在 IRQL PASSIVE_LEVEL
下执行。例如,Microsoft 有以下示例代码,说明如何从内核驱动程序写入文件:
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
return STATUS_INVALID_DEVICE_STATE;
Status = ZwCreateFile(...);
我的问题是:在上面的 KeGetCurrentIrql()
检查之后,是什么阻止了 IRQL 被引发?假设发生了上下文或线程切换,当 IRQL 返回到我的驱动程序时,它不会突然变为 DISPATCH_LEVEL 吗?这会导致系统崩溃吗?
如果这是不可能的,那么为什么不直接检查 DriverEntry
函数中的 IRQL 并一次性完成呢?
I'm new to Windows device driver programming. I know that certain operations can only be performed at IRQL PASSIVE_LEVEL
. For example, Microsoft have this sample code of how to write to a file from a kernel driver:
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
return STATUS_INVALID_DEVICE_STATE;
Status = ZwCreateFile(...);
My question is this: What is preventing the IRQL from being raised after the KeGetCurrentIrql()
check above? Say a context or thread swithch occurs, couldn't the IRQL suddenly be DISPATCH_LEVEL
when it gets back to my driver which would then result in a system crash?
If this is NOT possible then why not just check the IRQL in the DriverEntry
function and be done with it once for all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
线程的irql只能由其自身引发。
因为你是从上层/下层驱动调用的,所以当前运行上下文的irql可能不同。还有几个函数可以提高/降低 irql。
几个例子:
IRP_MJ_READ
(Io-)Completion 例程可以在 DISPATCH_LEVEL 处调用,因此应该进行相应的操作。
The irql of a thread can only be raised by itself.
Because you are called from upper/lower drivers, the irql of the current running context may be different. And there are a couple of functions that raise/lower the irql.
A couple examples :
IRP_MJ_READ
(Io-)Completion routines may be called at
DISPATCH_LEVEL
and so should behave accordingly.IRQL 只能通过设置在您的控制下以任何有意义的方式进行更改。有两个“线程特定”IRQL - PASSIVE_LEVEL 和 APC_LEVEL。您可以使用快速互斥体等控制进出这些级别,并且线程的上下文切换将始终使您保持在之前所在的级别。上面是“处理器特定的”IRQL。即 DISPATCH_LEVEL 或以上。在这些级别中不能发生上下文切换。您可以使用自旋锁等进入这些级别。 ISR 将在您的线程上以更高的 IRQL 发生,但您看不到它们。当他们将控制权返回给您时,您的 IRQL 就会恢复。
The IRQL can only change in any meaningful way under your control by setting it. There are two "thread specific" IRQLs - PASSIVE_LEVEL and APC_LEVEL. You control going in and out of these levels with things like fast mutexes, and a context switch to your thread will always leave you at the level you were in before. Above that are "processor specific" IRQLs. That is DISPATCH_LEVEL or above. In these levels a context switch cannot occur. You get into these levels using spin locks and such. ISRs will occur at higher IRQLs on your thread, but you can't see them. When they return control to you your IRQL is restored.
DriverEntry 也在 PASSIVE_LEVEL 被调用。
如果您想在 PASSIVE_LEVEL 完成工作,请使用 IoQueueWorkItem
DriverEntry is also called at PASSIVE_LEVEL.
If you want to have a job done at PASSIVE_LEVEL then use functions like IoQueueWorkItem