From: Xiang Chen <chenxiang66@hisilicon.com> mainline inclusion from mainline-v5.14-rc1 commit 7978724f399ae7eba5b6d36ae5a7224d5bf3859a category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID5X4C Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... ---------------------------------------- It is not necessary to put free_iova_mem() inside of spinlock/unlock iova_rbtree_lock which only leads to more completion for the spinlock. It has a small promote on the performance after the change. And also rename private_free_iova() as remove_iova() because the function will not free iova after that change. Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> Reviewed-by: John Garry <john.garry@huawei.com> Acked-by: Robin Murphy <robin.murphy@arm.com> Link: https://lore.kernel.org/r/1620647582-194621-1-git-send-email-chenxiang66@his... Signed-off-by: Joerg Roedel <jroedel@suse.de> Signed-off-by: Lin Yujun <linyujun809@h-partners.com> --- drivers/iommu/iova.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index 7e4a5cfe49ae..5e4d536c01a6 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -355,16 +355,15 @@ private_find_iova(struct iova_domain *iovad, unsigned long pfn) } return NULL; } -static void private_free_iova(struct iova_domain *iovad, struct iova *iova) +static void remove_iova(struct iova_domain *iovad, struct iova *iova) { assert_spin_locked(&iovad->iova_rbtree_lock); __cached_rbnode_delete_update(iovad, iova); rb_erase(&iova->node, &iovad->rbroot); - free_iova_mem(iova); } /** * find_iova - finds an iova for a given pfn * @iovad: - iova domain in question. @@ -395,12 +394,13 @@ void __free_iova(struct iova_domain *iovad, struct iova *iova) { unsigned long flags; spin_lock_irqsave(&iovad->iova_rbtree_lock, flags); - private_free_iova(iovad, iova); + remove_iova(iovad, iova); spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); + free_iova_mem(iova); } EXPORT_SYMBOL_GPL(__free_iova); /** * free_iova - finds and frees the iova for a given pfn @@ -415,14 +415,17 @@ free_iova(struct iova_domain *iovad, unsigned long pfn) unsigned long flags; struct iova *iova; spin_lock_irqsave(&iovad->iova_rbtree_lock, flags); iova = private_find_iova(iovad, pfn); - if (iova) - private_free_iova(iovad, iova); + if (!iova) { + spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); + return; + } + remove_iova(iovad, iova); spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); - + free_iova_mem(iova); } EXPORT_SYMBOL_GPL(free_iova); /** * alloc_iova_fast - allocates an iova from rcache @@ -856,11 +859,12 @@ iova_magazine_free_pfns(struct iova_magazine *mag, struct iova_domain *iovad) struct iova *iova = private_find_iova(iovad, mag->pfns[i]); if (WARN_ON(!iova)) continue; - private_free_iova(iovad, iova); + remove_iova(iovad, iova); + free_iova_mem(iova); } spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); mag->size = 0; -- 2.34.1