]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
ARM: mm: dma-mapping: Separate gap-page from num-pf-page
authorSri Krishna chowdary <schowdary@nvidia.com>
Tue, 6 Jan 2015 17:23:13 +0000 (22:53 +0530)
committerSri Krishna Chowdary <schowdary@nvidia.com>
Fri, 16 Jan 2015 05:16:35 +0000 (21:16 -0800)
A mapping can have gap-page and num-pf-page mentioned separately.
However, the current code adds a prefetch page for iommu mapping
if gap-page is 1 even though num-pf-page is 0. This is wrong and
prefetch page should not be mapped. Fixing it with this change.

Bug 200070960

Change-Id: I76fccbf9feb34d1dfd284d4ac48565dd21257864
Signed-off-by: Sri Krishna chowdary <schowdary@nvidia.com>
Reviewed-on: http://git-master/r/669775
Reviewed-by: Hiroshi Doyu <hdoyu@nvidia.com>
GVS: Gerrit_Virtual_Submit

arch/arm/mm/dma-mapping.c
arch/arm64/mm/dma-mapping.c

index 010382f02233af86b221dd9c46169c4d7990019b..bb1294fd2b013839fb61e02e6989c6bc4e13e607 100644 (file)
@@ -1168,8 +1168,6 @@ static void iommu_mapping_list_del(struct dma_iommu_mapping *mapping)
 static inline int iommu_get_num_pf_pages(struct dma_iommu_mapping *mapping,
                                         struct dma_attrs *attrs)
 {
-       int count = 0;
-
        /* XXX: give priority to DMA_ATTR_SKIP_IOVA_GAP */
        if (dma_get_attr(DMA_ATTR_SKIP_IOVA_GAP, attrs))
                        return 0;
@@ -1177,9 +1175,16 @@ static inline int iommu_get_num_pf_pages(struct dma_iommu_mapping *mapping,
        /* XXX: currently we support only 1 prefetch page */
        WARN_ON(mapping->num_pf_page > prefetch_page_count);
 
-       count += mapping->num_pf_page;
-       count += mapping->gap_page ? gap_page_count : 0;
-       return count;
+       return mapping->num_pf_page;
+}
+
+static inline int iommu_gap_pg_count(struct dma_iommu_mapping *mapping,
+                                    struct dma_attrs *attrs)
+{
+       if (dma_get_attr(DMA_ATTR_SKIP_IOVA_GAP, attrs))
+               return 0;
+
+       return mapping->gap_page ? gap_page_count : 0;
 }
 
 static int pg_iommu_map(struct dma_iommu_mapping *mapping, unsigned long iova,
@@ -1311,6 +1316,7 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
                 (1 << mapping->order) - 1) >> mapping->order;
 
        count += iommu_get_num_pf_pages(mapping, attrs);
+       count += iommu_gap_pg_count(mapping, attrs);
 
        if (order > mapping->order)
                align = (1 << (order - mapping->order)) - 1;
@@ -1341,6 +1347,7 @@ static dma_addr_t __alloc_iova_at(struct dma_iommu_mapping *mapping,
                 (1 << mapping->order) - 1) >> mapping->order;
 
        count += iommu_get_num_pf_pages(mapping, attrs);
+       count += iommu_gap_pg_count(mapping, attrs);
 
        bytes = count << (mapping->order + PAGE_SHIFT);
 
@@ -1397,6 +1404,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
        unsigned long flags;
 
        count += iommu_get_num_pf_pages(mapping, attrs);
+       count += iommu_gap_pg_count(mapping, attrs);
 
        spin_lock_irqsave(&mapping->lock, flags);
        bitmap_clear(mapping->bitmap, start, count);
index 27a08567a70951289b34bede73d5e7e03d45db65..83658ae60f6384892b354488a4501316c5e0138a 100644 (file)
@@ -1221,8 +1221,6 @@ static void iommu_mapping_list_del(struct dma_iommu_mapping *mapping)
 static inline int iommu_get_num_pf_pages(struct dma_iommu_mapping *mapping,
                                         struct dma_attrs *attrs)
 {
-       int count = 0;
-
        /* XXX: give priority to DMA_ATTR_SKIP_IOVA_GAP */
        if (dma_get_attr(DMA_ATTR_SKIP_IOVA_GAP, attrs))
                return 0;
@@ -1230,9 +1228,16 @@ static inline int iommu_get_num_pf_pages(struct dma_iommu_mapping *mapping,
        /* XXX: currently we support only 1 prefetch page */
        WARN_ON(mapping->num_pf_page > prefetch_page_count);
 
-       count += mapping->num_pf_page;
-       count += mapping->gap_page ? gap_page_count : 0;
-       return count;
+       return mapping->num_pf_page;
+}
+
+static inline int iommu_gap_pg_count(struct dma_iommu_mapping *mapping,
+                                    struct dma_attrs *attrs)
+{
+       if (dma_get_attr(DMA_ATTR_SKIP_IOVA_GAP, attrs))
+               return 0;
+
+       return mapping->gap_page ? gap_page_count : 0;
 }
 
 static int pg_iommu_map(struct dma_iommu_mapping *mapping, unsigned long iova,
@@ -1360,6 +1365,7 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
                 (1 << mapping->order) - 1) >> mapping->order;
 
        count += iommu_get_num_pf_pages(mapping, attrs);
+       count += iommu_gap_pg_count(mapping, attrs);
 
        if (order > mapping->order)
                align = (1 << (order - mapping->order)) - 1;
@@ -1390,6 +1396,7 @@ static dma_addr_t __alloc_iova_at(struct dma_iommu_mapping *mapping,
                 (1 << mapping->order) - 1) >> mapping->order;
 
        count += iommu_get_num_pf_pages(mapping, attrs);
+       count += iommu_gap_pg_count(mapping, attrs);
 
        bytes = count << (mapping->order + PAGE_SHIFT);
 
@@ -1446,6 +1453,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
        unsigned long flags;
 
        count += iommu_get_num_pf_pages(mapping, attrs);
+       count += iommu_gap_pg_count(mapping, attrs);
 
        spin_lock_irqsave(&mapping->lock, flags);
        bitmap_clear(mapping->bitmap, start, count);