Power IRPs处理注意点

  <Programming the Microsoft Windows Driver Model>第8章8.1节提到处理Power Irp的注意点:

"Power IRPs come to you in the context of a system thread that you must not block. There are several reasons why you can’t
block the thread
. If your device has the INRUSH characteristic, or if you’ve cleared the DO_POWER_PAGABLE flag in your
device object, the Power Manager will send you IRPs at DISPATCH_LEVEL. You remember, of course, that you can’t block a
thread while executing at DISPATCH_LEVEL. Even if you’ve set DO_POWER_PAGABLE, however, so that you get power
IRPs at PASSIVE_LEVEL, you can cause a deadlock by requesting a device power IRP while servicing a system IRP and then
blocking: the Power Manager might not send you the device IRP until your system IRP dispatch routine returns
, so you’ll wait forever."

这个注意点的背后涉及到System Power Irp处理的一个特点:Power Manager向设备栈发出(Query/Set) S-IRP后,设备驱动在Power Dispatcher函数中设置完成函数,调用PoCallDriver发送S-IRP并返回STATUS_PENDING。当Power Policy Owner Driver收到S-IRP后,会暂时挂起S-IRP,创建并向自己设备栈发送(Query/Set) D-IRP,当D-IRP处理完后,S-IRP才会完成。而S-IRP和D-IRP都由驱动程序的Power Dispatcher处理。

假设一个具有3层驱动的设备栈,从上往下依次为A->B(Power policy owner)->C(Bus)。当B收到S-IRP时,它会挂起S-IRP,然后调用PoRequestPowerIrp创建D-IRP,并将D-IRP发给A,将电源将要改变的状态通知A。一种不正确的处理方式是:A调用PoCallDriver下发S-IRP后,调用KeWaitForSingleObject等待S-IRP完成,即Power Dispatcher没有返回到Power Manager。这又导致Power Manger卡在PoCallDriver没有返回。当B收到从A传来的S-IRP后,又将调用Power Manager的PoRequestPowerIrp发出D-IRP。由于此时Power Manger在等待S-IRP完成,S-IRP等待驱动处理D-IRP;而新创建的D-Irp又等待Power Manger发送,最终形成死锁。

另外,MSDN设定PoRequestPowerIrp的返回值为STATUS_PENDING,多少也暗示驱动开发者:Power Dispatcher必须以异步方式处理Power IRP(设置完成函数/IoMarkIrpPending/return STATUS_PENDING)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值