Cyclic DMA - callback properties and tx_status residue

Russell King - ARM Linux linux at arm.linux.org.uk
Fri May 11 10:29:41 EDT 2012


On Fri, May 11, 2012 at 03:18:35PM +0100, Mark Brown wrote:
> On Fri, May 11, 2012 at 03:07:10PM +0100, Russell King - ARM Linux wrote:
> > On Thu, May 10, 2012 at 04:31:15PM +0530, Vinod Koul wrote:
> > > This should not be in ASoC library. The driver should be able to detect
> > > if a tasklet was called for many dma completions and notify the client
> > > (soc-lib) accordingly.
> 
> > No.  Think about the cyclic case.  How do you correctly record how many
> > 'periods' have completed so that when your tasklet eventually gets called,
> > you call its callback the correct number of times?
> 
> I do think that (separately to what ALSA does) if we're going to have a
> callback specified per request we really should make sure that they all
> get run as best as we can since the way the API is written people using
> non-cyclic transfers may run into the same surprise; for cyclic ones the
> issue you identify is very real though.

Please stop confusing non-cyclic with cyclic transfers.  We know what the
required semantics are for non-cyclic transfers and they really aren't
under discussion here.  I'm focusing 100% on the cyclic case here.

> > It is my opinion that having this emulation of the current position in
> > soc-dmaengine-pcm is not only causing a wrong direction to be taken here,
> > but is potentially causing inefficiency by forcing conditions into the API
> > which we really don't need.
> 
> I agree entirely, it's clearly just a bodge for not being able to read
> the position and we'd be better off fixing that.
> 
> > > One way to do this would be to ensure that the descriptor is marked in
> > > irq_handler and then all descriptor completed notified in tasklet.
> 
> > No.  You're assuming that for each IRQ you have the tasklet run exactly
> > once.  There is no such guarantee.
> 
> I think the intention here was that the framework keep a list of all
> pending transfers and then in the tasklet it runs through all the
> completions up to the most recent one rather than only completing the
> most recent one.  Easier said than done for cyclic of course...

That's my point.  And keeping count of N times to call the callback in
the DMA engine driver is racy at best.

Here's what I think.  I think the best solution for cyclic transfers
is as follows:

1. The callback will be guaranteed to be called at least _once_ when one
   or more periods have expired.

2. There may be fewer callbacks issued than periods have expired.

3. All DMA engine drivers supporting cyclic transfers *must* without
   exception implement the residue in their tx_status function.

4. The residue returned _must_ be the number of bytes between the next
   byte to be read or written by DMA to/from memory and the end of the
   buffer - more explicitly, according to this mathematics:
	buffer_dma_start_address + buffer_size - next_dma_address

5. Users of DMA engine cyclic transfers are expected to use the tx_status
   function to determine how many periods have completed on each callback
   if this information matters to their operation.



More information about the linux-arm-kernel mailing list