1) Memory types.
In snd_dma_alloc_pages(), ALSA does this:
case SNDRV_DMA_TYPE_PCI:
dmab->area = snd_malloc_pci_pages(dev->dev.pci, size, &dmab->addr);
which eventually comes down to this:
res = pci_alloc_consistent(pci, PAGE_SIZE * (1 << pg), dma_addr);
IOW:
dmab->area = pci_alloc_consistent(dev->dev.pci, size, &dmab->addr);
and in snd_pcm_lib_malloc_pages() we copy these into the runtime, thusly:
runtime->dma_area = dmab.area;
runtime->dma_addr = dmab.addr;
runtime->dma_private = dmab.private_data;
runtime->dma_bytes = size;
However, in snd_pcm_mmap_data_nopage(), ALSA does this:
vaddr = runtime->dma_area + offset;
page = virt_to_page(vaddr);
virt_to_page may _only_ be used on memory returned by get_free_page()
and kmalloc(), and certainly not on memory returned by
pci_alloc_consistent(). The only reason it works on x86 is because
x86 is a fully cache coherent architecture, so pci_alloc_consistent()
_just happens_ to be equivalent to get_free_pages() on that platform.
Note that the same applies to dma_alloc_coherent().
In other words, the above code will not work on non-cache coherent
architectures without modification.
I believe this needs discussing with the DMA API authors on LKML since
AFAIK the kernel currently doesn't have a clear API to translate memory
returned by either pci_alloc_consistent() or dma_alloc_coherent() back
to it's consituent struct page pointers.
Secondly the user space mapping will be marked as cacheable on some
architectures, which would be Real Bad(tm) on architectures which
are not DMA coherent.
The way architectures mark their mappings uncacheable and/or only
writecombining is architecture specific... see drivers/video/fbmem.c
as an example.
2) PCM mmap control/status mappings
These suffer from a similar cache coherency problem - you can not
assume that two different mappings of the same page will not alias
in the CPUs caches.
In my case on ARM, not only must the user space mappings of these
structures be marked uncacheable, but also the kernel space mappings
of the same to ensure that accesses via both mappings always return
up to date information.
I have hacks in my tree which work around this using ARM specific
functionality, but this is very much architecture specific at the
moment, and I suspect requires a new kernel API for creating memory
(it's similar to the DMA case above.)
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel