[RFC PATCH] Avoid aliasing mappings in DMA coherent allocator
Janusz Krzysztofik
jkrzyszt at tis.icnet.pl
Mon Jan 3 13:28:36 EST 2011
Monday 03 January 2011 10:57:52 Russell King - ARM Linux wrote:
> On Tue, Dec 28, 2010 at 09:29:58PM +0000, Janusz Krzysztofik wrote:
> > Works fine on OMAP1 based Amstrad Delta, both default 2MB/2MB and
> > shrinked to 1MB/1MB configurations. No need to preallocate dma
> > coherent memory for camera video buffers on boot.
>
> That's good news.
>
> > However, in 1MB/1MB configuration it failed to allocate 600kB of
> > writecombined omapfb vram, required for double-buffering, and
> > reserving up to 4MB of machine's total 32MB seems too expensive.
>
> Do you have other users of the writecombined memory? If so, what
> size are they?
Apparently ASoC omap-pcm, 2 x 128kB.
> As the 600k allocation can only be satisfied at the beginning of the
> region, we could do top-down rather than bottom-up allocation
> (untested):
Yes, this solves the issue for me. Both omap-pcm and omapfb/lcdc are now
able to get their requested DMA writecombined buffers (2 x 128kB +
600kB) from the reserved 1MB area.
Tested-by: Janusz Krzysztofik <jkrzyszt at tis.icnet.pl>
I'll try to prepare for review a followup patch that updates those
<{mach,plat}/memory.h> and similiar include files which provided their
own non-default CONSISTENT_DMA_SIZE values. Since I'm not familiar with
machines other that OMAP1, I'll take a 50/50 approach as a starting
point if no other indications can be found.
Thanks,
Janusz
> diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
> index 935993e..036fdbf 100644
> --- a/arch/arm/mm/vmregion.c
> +++ b/arch/arm/mm/vmregion.c
> @@ -38,7 +38,7 @@ struct arm_vmregion *
> arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
> size_t size, gfp_t gfp)
> {
> - unsigned long addr = head->vm_start, end = head->vm_end - size;
> + unsigned long start = head->vm_start, addr = head->vm_end;
> unsigned long flags;
> struct arm_vmregion *c, *new;
>
> @@ -54,21 +54,20 @@ arm_vmregion_alloc(struct arm_vmregion_head
> *head, size_t align,
>
> spin_lock_irqsave(&head->vm_lock, flags);
>
> - list_for_each_entry(c, &head->vm_list, vm_list) {
> - if ((addr + size) < addr)
> - goto nospc;
> - if ((addr + size) <= c->vm_start)
> + addr = rounddown(addr - size, align);
> + list_for_each_entry_reverse(c, &head->vm_list, vm_list) {
> + if (addr >= c->vm_end)
> goto found;
> - addr = ALIGN(c->vm_end, align);
> - if (addr > end)
> + addr = rounddown(c->vm_start - size, align);
> + if (addr < start)
> goto nospc;
> }
>
> found:
> /*
> - * Insert this entry _before_ the one we found.
> + * Insert this entry after the one we found.
> */
> - list_add_tail(&new->vm_list, &c->vm_list);
> + list_add(&new->vm_list, &c->vm_list);
> new->vm_start = addr;
> new->vm_end = addr + size;
> new->vm_active = 1;
More information about the linux-arm-kernel
mailing list