iommu/iova: Limit IOVA alignment using CONFIG_ARM64_DMA_IOMMU_ALIGNMENT

Currently IOVAs are aligned to the next power of two of the size of the
allocation. This can result in unnecessary fragmentation of the IOVA
space.

If defined use CONFIG_ARM64_DMA_IOMMU_ALIGNMENT to limit the maximum IOVA
alignment.

Change-Id: Ica7f6382237e37acac2d35972a564ca1e1f5e84f
Signed-off-by: Liam Mark <lmark@codeaurora.org>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
This commit is contained in:
Patrick Daly 2019-05-21 15:17:42 -07:00 • committed by Isaac J. Manjarres
commit 8693c2d4c4

View file

@ -177,6 +177,24 @@ iova_insert_rbtree(struct rb_root *root, struct iova *iova,
rb_insert_color(&iova->node, root);
}
#ifdef CONFIG_ARM64_DMA_IOMMU_ALIGNMENT
static unsigned long limit_align(struct iova_domain *iovad,
unsigned long shift)
{
unsigned long max;
max = CONFIG_ARM64_DMA_IOMMU_ALIGNMENT + PAGE_SHIFT
- iova_shift(iovad);
return min(shift, max);
}
#else
static unsigned long limit_align(struct iova_domain *iovad,
unsigned long shift)
{
return shift;
}
#endif
static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
unsigned long size, unsigned long limit_pfn,
struct iova *new, bool size_aligned)
@ -188,7 +206,7 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
unsigned long align_mask = ~0UL;
if (size_aligned)
align_mask <<= fls_long(size - 1);
align_mask <<= limit_align(iovad, fls_long(size - 1));
/* Walk the tree backwards */
spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);