From 8693c2d4c408745630ff6566c06e1f5da29d6380 Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Tue, 21 May 2019 15:17:42 -0700 Subject: [PATCH] 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 Signed-off-by: Patrick Daly Signed-off-by: Isaac J. Manjarres --- drivers/iommu/iova.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index 41c605b0058f..bf1db5f2f428 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -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);