[alsa-devel] Audio buffer mmap-ing on sh arch vs. cache aliasing problem
Paul Mundt
lethal at linux-sh.org
Sun Sep 21 03:13:10 CEST 2008
On Tue, Sep 16, 2008 at 08:18:06PM +0200, Takashi Iwai wrote:
> At Thu, 04 Sep 2008 12:23:54 +0100,
> Pawel MOLL wrote:
> > As a quick-and-dirty work-around I have modified
> > snd_pcm_alloc_vmalloc_buffer() to allocate always 12kB more and then use
> > 16k-aligned pointer:
> >
> > static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
> > {
> > struct snd_pcm_runtime *runtime = subs->runtime;
> > if (runtime->dma_addr) {
> > if (runtime->dma_bytes >= size)
> > return 0; /* already large enough */
> > vfree((void *)runtime->dma_addr);
> > }
> > runtime->dma_addr = (unsigned long)vmalloc(size + 12 * 1024);
> > if (!runtime->dma_addr)
> > return -ENOMEM;
> > runtime->dma_area = (void *)ALIGN(runtime->dma_addr, 16 * 1024);
> > runtime->dma_bytes = size;
> > return 0;
> > }
> >
> > Of course it cannot be regarded as anything more as a hack. And
> > definitely not as a solution... So my question is:
> >
> > Any idea how the "proper solution" should look like? I see no obvious
> > method to get an arch-independent "mmap-compliant" buffer. This problem
> > was found on a sh arch, using an USB Audio Class device, however out
> > there some other architectures are suffering from this MMU "feature" as
> > well (ie. see http://docs.hp.com/en/B3906-90006/ch07s09.html) and
> > possibly other drivers could behave "wrongly" (quoted as the driver is
> > actually innocent...)
>
> Currently, it's PITA on Linux to get a non-cached mmap properly in a
> generic way. Especially together with coherent memory allocations,
> there is no API for that. But, in the case of usb-audio, the problem
> is the vmaloc'ed intermediate buffer, and this could be a bit easier.
>
> One thing we can try is a patch like below. But, I'm not sure whether
> this is correct over all architectures, too. At best, a generic API
> would be helpful for such a thing...
>
pgprot_noncached() is the closest you will get to a generic API, but it's
true that not every architecture implements it. Given that, you will have
to toss up an #ifdef pgprot_noncached() around it, as seems to already be
the case for snd_pcm_lib_mmap_iomem(). Any sane platform that has
problems in this regard will have to define pgprot_noncached(), and
that's already true for things like /dev/mem today.
More information about the Alsa-devel
mailing list