mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 12:25:00 -04:00
iommu/iova: Support disabling domain iova alignment
Currently the IOVA framework automatically applies IOVA alignment to provided IOVAs based on the requested IOVA size and the alignment configs which are enabled. Some clients who don't require any IOVA alignment would benefit from the reduced fragmentation that would result from disabling IOVA alignment. Add support to allow clients to disable IOVA alignment on an IOMMU domain. Change-Id: Ifa6a75576e7a084c443abf38726d790b883f00b3 Signed-off-by: Patrick Daly <pdaly@codeaurora.org> [lmark@codeaurora.org: cleanup change] Signed-off-by: Liam Mark <lmark@codeaurora.org>
This commit is contained in:
parent
ed0190d5df
commit
2281bbc545
5 changed files with 64 additions and 0 deletions
|
|
@ -35,6 +35,22 @@ config IOMMU_IOVA_ALIGNMENT
|
|||
The order is expressed a power of two multiplied by the PAGE_SIZE.
|
||||
|
||||
If unsure, leave the default value "9".
|
||||
|
||||
config DMA_CONFIGURE_ALIGNMENT
|
||||
bool "Configure IOVA alignment"
|
||||
help
|
||||
Currently the IOVA framework automatically applies IOVA
|
||||
alignment to provided IOVAs based on the requested IOVA size and
|
||||
the alignment configs which are enabled.
|
||||
|
||||
Some clients who don't require any IOVA alignment would
|
||||
benefit from the reduced fragmentation that would result from
|
||||
disabling IOVA alignment.
|
||||
|
||||
Enable this option to allow clients to disable IOVA alignment on
|
||||
an IOMMU domain.
|
||||
|
||||
If unsure, say N.
|
||||
endif
|
||||
|
||||
menuconfig IOMMU_SUPPORT
|
||||
|
|
|
|||
|
|
@ -400,6 +400,27 @@ int iommu_dma_enable_best_fit_algo(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(iommu_dma_enable_best_fit_algo);
|
||||
|
||||
#ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT
|
||||
/*
|
||||
* Should be called prior to using dma-apis.
|
||||
*/
|
||||
int iommu_dma_configure_alignment(struct device *dev, bool force_no_align)
|
||||
{
|
||||
struct iommu_domain *domain;
|
||||
struct iova_domain *iovad;
|
||||
|
||||
domain = iommu_get_domain_for_dev(dev);
|
||||
if (!domain || !domain->iova_cookie)
|
||||
return -EINVAL;
|
||||
|
||||
iovad = &((struct iommu_dma_cookie *)domain->iova_cookie)->iovad;
|
||||
|
||||
iovad->force_no_align = force_no_align;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(iommu_dma_configure_alignment);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dma_info_to_prot - Translate DMA API directions and attributes to IOMMU API
|
||||
* page flags.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule,
|
|||
rb_link_node(&iovad->anchor.node, NULL, &iovad->rbroot.rb_node);
|
||||
rb_insert_color(&iovad->anchor.node, &iovad->rbroot);
|
||||
iovad->best_fit = false;
|
||||
#ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT
|
||||
iovad->force_no_align = false;
|
||||
#endif
|
||||
init_iova_rcaches(iovad);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(init_iova_domain);
|
||||
|
|
@ -385,6 +388,11 @@ alloc_iova(struct iova_domain *iovad, unsigned long size,
|
|||
if (!new_iova)
|
||||
return NULL;
|
||||
|
||||
#ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT
|
||||
if (iovad->force_no_align)
|
||||
size_aligned = false;
|
||||
#endif
|
||||
|
||||
if (iovad->best_fit) {
|
||||
ret = __alloc_and_insert_iova_best_fit(iovad, size,
|
||||
limit_pfn + 1, new_iova, size_aligned);
|
||||
|
|
|
|||
|
|
@ -58,6 +58,16 @@ int iommu_dma_reserve_iova(struct device *dev, dma_addr_t base,
|
|||
|
||||
int iommu_dma_enable_best_fit_algo(struct device *dev);
|
||||
|
||||
#ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT
|
||||
int iommu_dma_configure_alignment(struct device *dev, bool force_no_align);
|
||||
#else /* CONFIG_DMA_CONFIGURE_ALIGNMENT */
|
||||
static inline int iommu_dma_configure_alignment(struct device *dev,
|
||||
bool force_no_align)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_IOMMU_DMA */
|
||||
|
||||
struct iommu_domain;
|
||||
|
|
@ -110,5 +120,11 @@ static inline int iommu_dma_enable_best_fit_algo(struct device *dev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int iommu_dma_configure_alignment(struct device *dev,
|
||||
bool force_no_align)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IOMMU_DMA */
|
||||
#endif /* __DMA_IOMMU_H */
|
||||
|
|
|
|||
|
|
@ -96,6 +96,9 @@ struct iova_domain {
|
|||
atomic_t fq_timer_on; /* 1 when timer is active, 0
|
||||
when not */
|
||||
bool best_fit;
|
||||
#ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT
|
||||
bool force_no_align;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline unsigned long iova_size(struct iova *iova)
|
||||
|
|
|
|||
Loading…
Reference in a new issue