[alsa-devel] Audio buffer mmap-ing on sh arch vs. cache aliasing problem

Takashi Iwai tiwai at suse.de
Fri Sep 26 12:04:23 CEST 2008


At Thu, 25 Sep 2008 15:55:53 +0100,
Pawel MOLL wrote:
> 
> > 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...
> > +	area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
> 
> Well, it's not enough, because the kernel mapping of buffer is still
> cached... A hack below does the job, but it is not nice as well...

Yeah, that's not sexy, but maybe the only working case right now
(better with arch-specific ifdefs).

IIRC, a similar buffer handling (via vmalloc) is used in video
drivers.  I suppose they don't work as well, right?
DRM driver uses __vmalloc() with PAGE_KERNEL_NOCACHE, but it's only
for PPC32 non-coherent.


Takashi


> 
> Cheers
> 
> Paweł
> 
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index 59b29cd..304f9e5 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -3159,6 +3159,9 @@ static struct vm_operations_struct snd_pcm_vm_ops_data =
>  static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
>                                 struct vm_area_struct *area)
>  {
> +#ifdef pgprot_noncached
> +       area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
> +#endif
>         area->vm_ops = &snd_pcm_vm_ops_data;
>         area->vm_private_data = substream;
>         area->vm_flags |= VM_RESERVED;
> diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
> index 7bd5852..c98a4ec 100644
> --- a/sound/usb/usbaudio.c
> +++ b/sound/usb/usbaudio.c
> @@ -714,7 +714,8 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
>                         return 0; /* already large enough */
>                 vfree(runtime->dma_area);
>         }
> -       runtime->dma_area = vmalloc(size);
> +       runtime->dma_area = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM,
> +                       PAGE_KERNEL_NOCACHE);
>         if (! runtime->dma_area)
>                 return -ENOMEM;
>         runtime->dma_bytes = size;
> 


More information about the Alsa-devel mailing list