Hi.<br><br>vzalloc() call in __iommu_alloc_buffer() also causes BUG() in atomic context.<br><br><br>On Wed, Aug 22, 2012 at 7:20 PM, Hiroshi Doyu <<a href="mailto:hdoyu@nvidia.com">hdoyu@nvidia.com</a>> wrote:<br>> Makes use of the same atomic pool from DMA, and skips kernel page<br>
> mapping which can involves sleep'able operation at allocating a kernel<br>> page table.<br>><br>> Signed-off-by: Hiroshi Doyu <<a href="mailto:hdoyu@nvidia.com">hdoyu@nvidia.com</a>><br>> ---<br>
>  arch/arm/mm/dma-mapping.c |   22 ++++++++++++++++++----<br>>  1 files changed, 18 insertions(+), 4 deletions(-)<br>><br>> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c<br>> index aec0c06..9260107 100644<br>
> --- a/arch/arm/mm/dma-mapping.c<br>> +++ b/arch/arm/mm/dma-mapping.c<br>> @@ -1028,7 +1028,6 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,<br>>         struct page **pages;<br>
>         int count = size >> PAGE_SHIFT;<br>>         int array_size = count * sizeof(struct page *);<br>> -       int err;<br>><br>>         if (array_size <= PAGE_SIZE)<br>>                 pages = kzalloc(array_size, gfp);<br>
> @@ -1037,9 +1036,20 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,<br>>         if (!pages)<br>>                 return NULL;<br>><br>> -       err = __alloc_fill_pages(&pages, count, gfp);<br>
> -       if (err)<br>> -               goto error<br>> +       if (gfp & GFP_ATOMIC) {<br>> +               struct page *page;<br>> +               int i;<br>> +               void *addr = __alloc_from_pool(size, &page);<br>
> +               if (!addr)<br>> +                       goto err_out;<br>> +<br>> +               for (i = 0; i < count; i++)<br>> +                       pages[i] = page + i;<br>> +       } else {<br>
> +               int err = __alloc_fill_pages(&pages, count, gfp);<br>> +               if (err)<br>> +                       goto error;<br>> +       }<br>><br>>         return pages;<br>>  error:<br>
> @@ -1055,6 +1065,10 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t s<br>>         int count = size >> PAGE_SHIFT;<br>>         int array_size = count * sizeof(struct page *);<br>
>         int i;<br>> +<br>> +       if (__free_from_pool(page_address(pages[0]), size))<br>> +               return 0;<br>> +<br>>         for (i = 0; i < count; i++)<br>>                 if (pages[i])<br>
>                         __free_pages(pages[i], 0);<br>> --<br>> 1.7.5.4<br>><br>> --<br>> To unsubscribe, send a message with 'unsubscribe linux-mm' in<br>> the body to <a href="mailto:majordomo@kvack.org">majordomo@kvack.org</a>.  For more info on Linux MM,<br>
> see: <a href="http://www.linux-mm.org/">http://www.linux-mm.org/</a> .<br>> Don't email: <a href=mailto:"<a href="mailto:dont@kvack.org">dont@kvack.org</a>"> <a href="mailto:email@kvack.org">email@kvack.org</a> </a><br>
<br>