[wdmaudiodev] Unjustified Starvation in IDmaChannel::CopyFrom() @ High CPU Load

  • From: "Don Bell" <0dbell@xxxxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Mon, 24 Mar 2008 10:38:12 -0500

In a driver that I have written based on the MSVAD (simple) sample, I
use the inherited IMiniportWaveCyclicStream::SetNotificationFreq() to
set the interval to 20ms.

For render, this indeed sets correctly the interval in which the
inherited IDmaChannel::CopyTo(), supplying exactly FrameSize bytes to
read every such call.

For capture, on the other hand, IDmaChannel::CopyFrom() arrives at a
higher "rate" (sometimes over 30 times every 20ms, microseconds
apart!), with the ByteCount parameter being anywhere between 16 and
FrameSize (15 < ByteCount < FrameSize + 1).

After inquiring about this, I learned that there are several factors
that can contribute to getting multiple CopyTo or CopyFrom calls in a
single DPC cycle and for the variable transfer sizes:

    *) If the desired transfer wraps around the end of the cyclic DMA
buffer the transfer will be broken into two transfers, one at the end
of the buffer and one at the beginning

    *) If the desired transfer spans an IRP boundary the transfer will
be broken up into two transfers (or more depending on IRP packet
sizes)

    *) The DPC is scheduled to run each time the miniport notifies the
port driver.  So, if you set the notification frequency to 20ms and
notify the port at that rate, the DPC will run at least every 20ms.
However, the DPC is also scheduled to run each time a new streaming
IRP arrives (this reduces the chance of starvation and glitches).  As
a result, you may see variable DPC scheduling impacting DMA transfer
sizes.

All of that is now clear and understood. However, I am struggling with
a very difficult problem in which my driver behaves very nicely at
low-to-moderate CPU loads (<50%), but in high CPU loads (>80%)
IDmaChannel::CopyFrom() simply doesn't request enough bytes to
transfer!

That is, the ByteCount is not high enough to keep up with the rate of
bytes arriving from the microphone... As a result, my microphone FIFO
buffer overflows and the driver's capture start loosing samples.

What could be the explanation for such behavior?

At first, I thought that perhaps the DPC (that calls
IDmaChannel::CopyFrom) doesn't have high enough priority, comparing to
other threads and interrupts in the system. But using WPP and
TraceView I was able to see that IDmaChannel::CopyFrom is called
frequently enough, even microseconds apart. The only problem is that
it is called with ridiculously low ByteCount such as 16, when it is
clear that it needs at least 256 (which *are* available in the
buffer).

What is the right approach to solving this problem?

Remember, at low-to-moderate CPU loads (<50%) this problem does not exist.

I would appreciate any tip or hint that can get me closer to solving
this mystery.

Thanks,
Dave
******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.com/

Other related posts:

  • » [wdmaudiodev] Unjustified Starvation in IDmaChannel::CopyFrom() @ High CPU Load