ARM: dma-mapping: Use iommu_map_sg() in dma_map_sg()
Hiroshi Doyu [Tue, 11 Jun 2013 12:25:10 +0000 (15:25 +0300)]
Use iommu_map_sg() in dma_map_sg() for perf instead of calling
iommu_map() repeatedly.

Bug 1304956
Bug 1327616

Change-Id: Ib5941f719fdf822a166fbbb0dc3fad22e2767e21
Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
Reviewed-on: http://git-master/r/253307
(cherry picked from commit 1765eb73dd6f668e8f9fde99230af8fcba0bd906)
Signed-off-by: Ajay Nandakumar <anandakumarm@nvidia.com>
Reviewed-on: http://git-master/r/264779

arch/arm/mm/dma-mapping.c

index d2e40f0..975cc94 100644 (file)
@@ -1561,20 +1561,24 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
        if (iova == DMA_ERROR_CODE)
                return -ENOMEM;
 
+       if (is_coherent || dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+               goto skip_cmaint;
+
        for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
-               phys_addr_t phys = page_to_phys(sg_page(s));
                unsigned int len = PAGE_ALIGN(s->offset + s->length);
 
-               if (!is_coherent &&
-                       !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
-                       __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
+               __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
 
-               ret = iommu_map(mapping->domain, iova, phys, len, 0);
-               if (ret < 0)
-                       goto fail;
                count += len >> PAGE_SHIFT;
                iova += len;
        }
+
+skip_cmaint:
+       count = size >> PAGE_SHIFT;
+       ret = iommu_map_sg(mapping->domain, iova_base, sg, count, 0);
+       if (WARN_ON(ret < 0))
+               goto fail;
+
        *handle = iova_base;
 
        return 0;