I have verified that if I push a request created by WdfRequestCreate and completed by WdfObjectDelete a reference to the request will be stuck in the last queue the request was in. I did that by pushing just 1 allocated request through our system. No threading issues were involved. The requests we get from the IOCTL are completed by calling WdfRequestComplete and in that case
the reference is removed from the last queue it was in.
Normal flow of Request through driver:
! IOCTL Request → FrameBuf_New → FrameBuf_Active → QueueDMA → DpcDelayRequestComplete → WdfRequestComplete
When I allocate the request in the driver, new quad mode:
! Request Create → FrameBuf_New → FrameBuf_Active → QueueDMA → DpcDelayRequestComplete → WdfObjectDelete
To fix my big issued with memory leaking, I created a circular ring buffer with preallocated requests and just cycled through them. To get the driver to shut down on power down I added a EvtIoStop() callback to my DMA queues. The callback is never called, but with it there, the driver shuts down on power down.
But when we are releasing the hardware ( EvtDeviceReleaseHardware ) when the driver is going to be updated / change, the queues with the hidden references in them, cause the driver to hang with the inflight buffers message. Since I have pulled all the request from the queue, I do not know what to do to clear the queues. The hanging comes after returning from release hardware.
! Thread 0xFFFFB00F5063C040 is waiting for all inflight requests to be acknowledged on WDFQUEUE 0x00004FF0B0494BC8
This is the queue with the 1 reference in it:
0: kd> !wdfkd.wdfqueue 0x04FF0B0494BC8
Treating handle as a KMDF handle!Dumping WDFQUEUE 0x00004ff0b0494bc8
Manual, Power-managed, PowerPurgeDriverNotified, Shut down, Cannot accept, Cannot dispatch, ExecutionLevelDispatch, SynchronizationScopeNone
Number of driver owned requests: 1
Power transition in progress
Number of waiting requests: 0Number of requests notified about power change: 1 !wdfrequest 0x00004ff0b0775e98 !irp 0xffffb00f4eefa010 (Request is marked cancelled, EvtIoStop may not have been called for this request) EvtIoIdleComplete: (0xfffff8005152db90) NewTekHD EvtIoPurgeComplete: (0xfffff80051524010) NewTekHD EvtIoCanceledOnQueue: (0xfffff80051529770) NewTekHD EvtIoStop: (0xfffff80051529650) NewTekHD
I tried to clear the queues using the follow calls:
! WdfIoQueueDrain()
! WdfIoQueueStop()
! WdfIoQuueStopAndPurgeSychronously()
! WdfIoQueuePurge()
I allocated the requests by calling:
WDFIOTARGET Target_ = WdfDeviceGetIoTarget( devContext->WdfDevice );
ntStatus_ = WdfRequestCreate( WDF_NO_OBJECT_ATTRIBUTES, Target_, &devContext->RequestQueue[ i ] );
What I need to know is there a way to remove or to complete the request to remove it from the last queue it was in. Or is there a way to shutdown the queue threads to stop the inflight messages. We need to be able to shut down the driver to replace the driver.