This time it’s about hibernation. This is a non-virtual, full-duplex miniport.
- On Windows 2003, Storport calls ScsiRestartAdapter at DIRQL when coming back from hibernation.
Moreover, the interrupt lock is held. This is against MS docs at http://msdn.microsoft.com/en-us/library/ff567025(VS.85).aspx which say
HwAdapterControlRoutine
Spin lock held by port driver: None
Note: In Windows Server 2003, the StartIo spin lock was held when control type is ScsiStopAdapter.
This is not in the hibernation stack, so it’s way within the boundaries of the documented interfaces. If the docs correctly documented the locking policy of ScsiRestartAdapter, the IRQL could also be guessed by us poor souls…
- Worse, on hibernate Diskdump’s storport implementation calls HwStorInitialize at DISPATCH_LEVEL and never goes below DISPATCH_LEVEL. The normal stack calls the function at DIRQL and you can obviously expect to go down to PASSIVE_LEVEL sooner or later. So, if it wants to do anything at low IRQL, HwStorInitialize must queue a DPC, and kernel DPCs will never be executed during hibernation.
To be fair, DPCs will never be executed during crash dump either. In my case I didn’t have this problem with crash dump because, unlike hibernation, it doesn’t tear down the primary copy of the device. So crash dump happened to find everything already initialized and didn’t queue that DPC.
Also, I haven’t tested what happens with Storport DPCs, it’s possible that Diskdump special-cases those.
> 1) On Windows 2003, Storport calls ScsiRestartAdapter at DIRQL when coming back from hibernation.
Moreover, the interrupt lock is held. This is against MS docs at http://msdn.microsoft.com/en-us/library/ff567025(VS.85).aspx
which say
HwAdapterControlRoutine
Spin lock held by port driver: None
Note: In Windows Server 2003, the StartIo spin lock was held when control type is ScsiStopAdapter.
This is not in the hibernation stack, so it’s way within the boundaries of the documented interfaces. If the docs correctly
documented the locking policy of ScsiRestartAdapter, the IRQL could also be guessed by us poor souls…
Yes, I agree that the documentation is unclear/incorrect around the IRQLs at which the various interfaces are invoked and the locks
the miniport can attempt to acquire.
- Worse, on hibernate Diskdump’s storport implementation calls HwStorInitialize at DISPATCH_LEVEL and never goes below
DISPATCH_LEVEL. The normal stack calls the function at DIRQL and you can obviously expect to go down to PASSIVE_LEVEL sooner or
later. So, if it wants to do anything at low IRQL, HwStorInitialize must queue a DPC, and kernel DPCs will never be executed
during hibernation.
This is documented in the section http://msdn.microsoft.com/en-us/library/ff564084(v=VS.85).aspx. I believe the restrictions apply
to both the crash dump and hibernate cases.
To be fair, DPCs will never be executed during crash dump either. In my case I didn’t have this problem with crash dump because,
unlike hibernation, it doesn’t tear down the primary copy of the device. So crash dump happened to find everything already
initialized and didn’t queue that DPC.
I didn’t quite get the statement “it doesn’t tear down the primary copy of the device”. Do you mean the miniport’s hardware
extension? Doesn’t the run-time miniport be unloaded and re-loaded in the dump/hibernate context (including the call to
DriverEntry)?
Regards,
Girish.
IMHO the storport documentation should be re-written instead of asking the
user to refer scsiport documentation. Here is one of the contradictions at
its best!
HwScsiAdapterControl Routine:
http://msdn.microsoft.com/en-us/library/ff557274(VS.85).aspx
Section - *ScsiStopAdapter:
The document says, “*The miniport driver disables interrupts on its HBA,
halts all processing …*” and in next couple of paragraphs the doc says
the following ,
“*Note that the port driver might call *HwScsiAdapterControl* to stop the
adapter after the HBA has already been physically removed from the system,
so the miniport driver’s *HwScsiAdapterControl* routine *must not perform
any operations that require the HBA to be physically present while it is
stopping the HBA*.*”
* I do-not find a storport API or other best way to
check is my HBA present during ScsiStorAdapter to disable the interrupts!
Regards,
Gokul T V
On Thu, Feb 24, 2011 at 9:26 PM, wrote:
> This time it’s about hibernation. This is a non-virtual, full-duplex
> miniport.
>
> 1) On Windows 2003, Storport calls ScsiRestartAdapter at DIRQL when coming
> back from hibernation.
>
> Moreover, the interrupt lock is held. This is against MS docs at
> http://msdn.microsoft.com/en-us/library/ff567025(VS.85).aspx which say
>
> HwAdapterControlRoutine
> Spin lock held by port driver: None
> Note: In Windows Server 2003, the StartIo spin lock was held when control
> type is ScsiStopAdapter.
>
> This is not in the hibernation stack, so it’s way within the boundaries of
> the documented interfaces. If the docs correctly documented the locking
> policy of ScsiRestartAdapter, the IRQL could also be guessed by us poor
> souls…
>
> 2) Worse, on hibernate Diskdump’s storport implementation calls
> HwStorInitialize at DISPATCH_LEVEL and never goes below DISPATCH_LEVEL. The
> normal stack calls the function at DIRQL and you can obviously expect to go
> down to PASSIVE_LEVEL sooner or later. So, if it wants to do anything at
> low IRQL, HwStorInitialize must queue a DPC, and kernel DPCs will never be
> executed during hibernation.
>
> To be fair, DPCs will never be executed during crash dump either. In my
> case I didn’t have this problem with crash dump because, unlike hibernation,
> it doesn’t tear down the primary copy of the device. So crash dump happened
> to find everything already initialized and didn’t queue that DPC.
>
> Also, I haven’t tested what happens with Storport DPCs, it’s possible that
> Diskdump special-cases those.
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
> I didn’t quite get the statement "it doesn’t tear down the primary
copy of the device". Do you mean the miniport’s hardware
extension? Doesn’t the run-time miniport be unloaded and
re-loaded in the dump/hibernate context (including the call
to DriverEntry)?
Both dump and hibernate have two copies of the drivers. However,
hibernate does a SRB_FUNCTION_POWER/ScsiStopAdapter
of the primary copy before initializing the secondary copy. Dump
instead initializes the secondary copy without first tearing down
the primary copy. This made a big difference in my case.
Thanks for pointing out the docs about DPCs. I was aware of
all the other limitations, I had missed that one.