Merge "defconfig: lahaina: Enable DMA_CONFIGURE_ALIGNMENT"

This commit is contained in:
qctecmdr 2020-04-28 13:12:17 -07:00 • committed by Gerrit - the friendly Code Review server
commit 4bb5eb96b4
6 changed files with 65 additions and 0 deletions

View file

@ -44,6 +44,7 @@ CONFIG_CMA_DIRECT_UTILIZATION=y
CONFIG_CMA_PCP_LISTS=y
CONFIG_DMA_COHERENT_HINT_CACHED=y
CONFIG_PRIORITIZE_OOM_TASKS=y
CONFIG_DMA_CONFIGURE_ALIGNMENT=y
# CONFIG_ZONE_DEVICE is not set
# CONFIG_BUG_ON_HW_MEM_ONLINE_FAIL is not set
CONFIG_MSM_BT_POWER=m

View file

@ -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

View file

@ -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.

View file

@ -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);

View file

@ -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 */

View file

@ -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)