At Thu, 08 May 2008 07:53:11 +1000, Benjamin Herrenschmidt wrote:
On Wed, 2008-05-07 at 09:22 -0500, Timur Tabi wrote:
Takashi Iwai wrote:
This is a mmap of the data record to be shared in realtime with apps. The app updates its data pointer (appl_ptr) on the mmapped buffer while the driver updates the data (e.g. DMA position, called hwptr) on the fly on the mmapped record. Due to its real-time nature, it has to be coherent -- at least, it was a problem on ARM.
This doesn't sound like a coherency problem to me, and least not one you'd find on PowerPC. Both the driver and the application run on the host CPU, so there shouldn't be any coherency problem. My understanding is that a "non coherent" platform is one where the host CPU isn't aware when a *hardware device* writes directly to memory, e.g. via DMA.
Yes, precisely. I was about to make a reply here. There is some confusion at least in terminology, in Alsa. This is not DMA coherency, though it is a problem with virtually tagged data caches that some archs such as ARM have.
Right. The words should be corrected. Since the only way to get a certain non-cached map was the (ab-)use of dma_mmap_coherent(), such a confusing wording was chosen.
So this is ok for all PowerPC since they all have a physically tagged data cache.
OK, so that part should work as is for PPC.
The real problem -is- still the DMA coherency issue and as I see it, is two fold:
- mmap'ing of the result of dma_alloc_coherent() doesn't work. There
are two issues at play here, one is the pgprot that -must- be set to uncached for such a mapping on non coherent architectures (and non coherent architectures only), and the other is our virt_to_page() that will puke on virtual addresses coming from dma_alloc_coherent().
And dma_mmap_coherent() would be a solution for it, I suppose.
- mmap'ing of SG lists for non coherent DMA. There the problem is a
mixture of how Alsa allocate the SG buffers mixes with the previous problem.
Yes.
I think it's never valid to create an SG list with the output of dma_alloc_coherent though. We would need a dma_alloc_sg() for that...
sglists are made of pages, thus allocated with GFP, and later DMA mapped with dma_map_*, however this brings a whole other set of issues/constra ints such as bouce bufferring on some MMU less platforms if the memory happens to come out of the wrong place. Also, such mapped buffers are -not- coherent as they must not be modified via their virtual address while mapped, -unless- they are also mapped in kernel and/or user space (vmap & mmap) using some kind of "coherent" attributes such as pgprot_noncached. (and provided that is possible at all in kernel place for archs like MIPS).
I don't have an easy answer there, it seems the bogosity roots deep in alsa, at least for the SG bits. For the non-SG bits, we can probably work around with an accessor to get the right pgprot and maybe some variant of virt_to_page() (dma_virt_to_page() ?) that would walk the kernel page tables to obtain the pfn.
The vmap() in sound/core/sgbuf.c can be omitted by adding proper PCM callbacks (copy and silent) to handle SG-buffers. These are only guys that access the linear buffer runtime->area.
Then we'll just need a proepr mmap PCM callback just calling dma_mmap_coherent() for each SG page. Also, the default PCM mmap should be fixed to use dma_mmap_coherent() appropriately. That's all.
So, what we really need is dma_mmap_coherent() implementations...
thanks,
Takashi