On Mon, May 19 2014, Joonsoo Kim wrote: > On Tue, May 20, 2014 at 02:57:47PM +0900, Gioh Kim wrote: >> >> Thanks for your advise, Michal Nazarewicz. >> >> Having discuss with Joonsoo, I'm adding fallback allocation after __alloc_from_contiguous(). >> The fallback allocation works if CMA kernel options is turned on but CMA size is zero. > > Hello, Gioh. > > I also mentioned the case where devices have their specific cma_area. > It means that this device needs memory with some contraint. > Although I'm not familiar with DMA infrastructure, I think that > we should handle this case. > > How about below patch? > > ------------>8---------------- > diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c > index 6b00be1..4023434 100644 > --- a/arch/arm/mm/dma-mapping.c > +++ b/arch/arm/mm/dma-mapping.c > @@ -379,7 +379,7 @@ static int __init atomic_pool_init(void) > unsigned long *bitmap; > struct page *page; > struct page **pages; > - void *ptr; > + void *ptr = NULL; > int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long); > > bitmap = kzalloc(bitmap_size, GFP_KERNEL); > @@ -393,7 +393,8 @@ static int __init atomic_pool_init(void) > if (IS_ENABLED(CONFIG_DMA_CMA)) > ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page, > atomic_pool_init); > - else > + > + if (!ptr) > ptr = __alloc_remap_buffer(NULL, pool->size, gfp, prot, &page, > atomic_pool_init); > if (ptr) { > @@ -701,10 +702,22 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, > addr = __alloc_simple_buffer(dev, size, gfp, &page); > else if (!(gfp & __GFP_WAIT)) > addr = __alloc_from_pool(size, &page); > - else if (!IS_ENABLED(CONFIG_DMA_CMA)) > - addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); > - else > - addr = __alloc_from_contiguous(dev, size, prot, &page, caller); > + else { > + if (IS_ENABLED(CONFIG_DMA_CMA)) { > + addr = __alloc_from_contiguous(dev, size, prot, > + &page, caller); > + /* > + * Device specific cma_area means that > + * this device needs memory with some contraint. > + * So, we can't fall through general remap allocation. > + */ > + if (!addr && dev && dev->cma_area) > + return NULL; > + } > + > + addr = __alloc_remap_buffer(dev, size, gfp, prot, > + &page, caller); > + } __arm_dma_free will have to be changed to handle the fallback as well. But perhaps Marek is right and there should be no fallback for regular allocations? Than again, non-CMA allocation should be performed at least in the case of cma=0. > > if (addr) > *handle = pfn_to_dma(dev, page_to_pfn(page)); -- Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michał “mina86” Nazarewicz (o o) ooo +--<mpn@xxxxxxxxxx>--<xmpp:mina86@xxxxxxxxxx>--ooO--(_)--Ooo--
Attachment:
signature.asc
Description: PGP signature