iommu/arm-smmu-v3: Remove io-pgtable spinlock
As for SMMUv2, take advantage of io-pgtable's newfound tolerance for concurrency. Unfortunately in this case the command queue lock remains a point of serialisation for the unmap path, but there may be a little more we can do to ameliorate that in future. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
Родитель
523d7423e2
Коммит
58188afeb7
|
@ -646,7 +646,6 @@ struct arm_smmu_domain {
|
||||||
struct mutex init_mutex; /* Protects smmu pointer */
|
struct mutex init_mutex; /* Protects smmu pointer */
|
||||||
|
|
||||||
struct io_pgtable_ops *pgtbl_ops;
|
struct io_pgtable_ops *pgtbl_ops;
|
||||||
spinlock_t pgtbl_lock;
|
|
||||||
|
|
||||||
enum arm_smmu_domain_stage stage;
|
enum arm_smmu_domain_stage stage;
|
||||||
union {
|
union {
|
||||||
|
@ -1414,7 +1413,6 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&smmu_domain->init_mutex);
|
mutex_init(&smmu_domain->init_mutex);
|
||||||
spin_lock_init(&smmu_domain->pgtbl_lock);
|
|
||||||
return &smmu_domain->domain;
|
return &smmu_domain->domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1686,44 +1684,29 @@ out_unlock:
|
||||||
static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
|
static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
|
||||||
phys_addr_t paddr, size_t size, int prot)
|
phys_addr_t paddr, size_t size, int prot)
|
||||||
{
|
{
|
||||||
int ret;
|
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
|
||||||
unsigned long flags;
|
|
||||||
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
|
|
||||||
struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
|
|
||||||
|
|
||||||
if (!ops)
|
if (!ops)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
|
return ops->map(ops, iova, paddr, size, prot);
|
||||||
ret = ops->map(ops, iova, paddr, size, prot);
|
|
||||||
spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
|
arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
|
||||||
{
|
{
|
||||||
size_t ret;
|
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
|
||||||
unsigned long flags;
|
|
||||||
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
|
|
||||||
struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
|
|
||||||
|
|
||||||
if (!ops)
|
if (!ops)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
|
return ops->unmap(ops, iova, size);
|
||||||
ret = ops->unmap(ops, iova, size);
|
|
||||||
spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static phys_addr_t
|
static phys_addr_t
|
||||||
arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
|
arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
|
||||||
{
|
{
|
||||||
phys_addr_t ret;
|
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
|
||||||
unsigned long flags;
|
|
||||||
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
|
|
||||||
struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
|
|
||||||
|
|
||||||
if (domain->type == IOMMU_DOMAIN_IDENTITY)
|
if (domain->type == IOMMU_DOMAIN_IDENTITY)
|
||||||
return iova;
|
return iova;
|
||||||
|
@ -1731,11 +1714,7 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
|
||||||
if (!ops)
|
if (!ops)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
|
return ops->iova_to_phys(ops, iova);
|
||||||
ret = ops->iova_to_phys(ops, iova);
|
|
||||||
spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver arm_smmu_driver;
|
static struct platform_driver arm_smmu_driver;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче