diff mbox series

[2/2] iommu: Undo pasid attachment only for the devices that have succeeded

Message ID 20240327125433.248946-3-yi.l.liu@intel.com (mailing list archive)
State New, archived
Headers show
Series Two enhancements to iommu_at[de]tach_device_pasid() | expand

Commit Message

Yi Liu March 27, 2024, 12:54 p.m. UTC
There is no error handling now in __iommu_set_group_pasid(), it relies on
its caller to loop all the devices to undo the pasid attachment. This is
not self-contained and has unnecessary remove_dev_pasid() calls on the
devices that have not changed in the __iommu_set_group_pasid() call. this
results in unnecessary warnings by the underlying iommu drivers. Like the
Intel iommu driver, it would warn when there is no pasid attachment to
destroy in the remove_dev_pasid() callback.

The ideal way is to handle the error within __iommu_set_group_pasid(). This
not only makes __iommu_set_group_pasid() self-contained, but also avoids
unnecessary warnings.

Fixes: 16603704559c7a68 ("iommu: Add attach/detach_dev_pasid iommu interfaces")
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
---
 drivers/iommu/iommu.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

Comments

Jason Gunthorpe March 27, 2024, 1:05 p.m. UTC | #1
On Wed, Mar 27, 2024 at 05:54:33AM -0700, Yi Liu wrote:
> There is no error handling now in __iommu_set_group_pasid(), it relies on
> its caller to loop all the devices to undo the pasid attachment. This is
> not self-contained and has unnecessary remove_dev_pasid() calls on the
> devices that have not changed in the __iommu_set_group_pasid() call. this
> results in unnecessary warnings by the underlying iommu drivers. Like the
> Intel iommu driver, it would warn when there is no pasid attachment to
> destroy in the remove_dev_pasid() callback.
> 
> The ideal way is to handle the error within __iommu_set_group_pasid(). This
> not only makes __iommu_set_group_pasid() self-contained, but also avoids
> unnecessary warnings.
> 
> Fixes: 16603704559c7a68 ("iommu: Add attach/detach_dev_pasid iommu interfaces")
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Yi Liu <yi.l.liu@intel.com>
> ---
>  drivers/iommu/iommu.c | 20 ++++++++++++++------
>  1 file changed, 14 insertions(+), 6 deletions(-)

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>

This will need revising when we get to PASID replace, but good enough
for now

Thanks,
Jason
Yi Liu March 27, 2024, 1:12 p.m. UTC | #2
On 2024/3/27 21:05, Jason Gunthorpe wrote:
> On Wed, Mar 27, 2024 at 05:54:33AM -0700, Yi Liu wrote:
>> There is no error handling now in __iommu_set_group_pasid(), it relies on
>> its caller to loop all the devices to undo the pasid attachment. This is
>> not self-contained and has unnecessary remove_dev_pasid() calls on the
>> devices that have not changed in the __iommu_set_group_pasid() call. this
>> results in unnecessary warnings by the underlying iommu drivers. Like the
>> Intel iommu driver, it would warn when there is no pasid attachment to
>> destroy in the remove_dev_pasid() callback.
>>
>> The ideal way is to handle the error within __iommu_set_group_pasid(). This
>> not only makes __iommu_set_group_pasid() self-contained, but also avoids
>> unnecessary warnings.
>>
>> Fixes: 16603704559c7a68 ("iommu: Add attach/detach_dev_pasid iommu interfaces")
>> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
>> Signed-off-by: Yi Liu <yi.l.liu@intel.com>
>> ---
>>   drivers/iommu/iommu.c | 20 ++++++++++++++------
>>   1 file changed, 14 insertions(+), 6 deletions(-)
> 
> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> 
> This will need revising when we get to PASID replace, but good enough
> for now

yes, the rollback part would be revised a bit when coming to support
PASID domain replacement. Already in the pending list, will send it
out soon. :)
Tian, Kevin March 28, 2024, 3:15 a.m. UTC | #3
> From: Liu, Yi L <yi.l.liu@intel.com>
> Sent: Wednesday, March 27, 2024 8:55 PM
> +
> +err_revert:
> +	last_gdev = device;
> +	for_each_group_device(group, device) {
> +		if (device == last_gdev)
> +			break;
> +		dev_iommu_ops(device->dev)->remove_dev_pasid(device-
> >dev,
> +							     pasid, domain);
> +	}

break the long line into:
	ops = dev_iommu_ops(device->dev);
	ops->remove_dev_pasid();

otherwise it looks good to me:

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Yi Liu March 28, 2024, 6:29 a.m. UTC | #4
On 2024/3/28 11:15, Tian, Kevin wrote:
>> From: Liu, Yi L <yi.l.liu@intel.com>
>> Sent: Wednesday, March 27, 2024 8:55 PM
>> +
>> +err_revert:
>> +	last_gdev = device;
>> +	for_each_group_device(group, device) {
>> +		if (device == last_gdev)
>> +			break;
>> +		dev_iommu_ops(device->dev)->remove_dev_pasid(device-
>>> dev,
>> +							     pasid, domain);
>> +	}
> 
> break the long line into:
> 	ops = dev_iommu_ops(device->dev);
> 	ops->remove_dev_pasid();

got it.

> otherwise it looks good to me:
> 
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
diff mbox series

Patch

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 681e916d285b..2a12c9c9e045 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3317,15 +3317,25 @@  EXPORT_SYMBOL_GPL(iommu_group_dma_owner_claimed);
 static int __iommu_set_group_pasid(struct iommu_domain *domain,
 				   struct iommu_group *group, ioasid_t pasid)
 {
-	struct group_device *device;
-	int ret = 0;
+	struct group_device *device, *last_gdev;
+	int ret;
 
 	for_each_group_device(group, device) {
 		ret = domain->ops->set_dev_pasid(domain, device->dev, pasid);
 		if (ret)
-			break;
+			goto err_revert;
 	}
 
+	return 0;
+
+err_revert:
+	last_gdev = device;
+	for_each_group_device(group, device) {
+		if (device == last_gdev)
+			break;
+		dev_iommu_ops(device->dev)->remove_dev_pasid(device->dev,
+							     pasid, domain);
+	}
 	return ret;
 }
 
@@ -3375,10 +3385,8 @@  int iommu_attach_device_pasid(struct iommu_domain *domain,
 	}
 
 	ret = __iommu_set_group_pasid(domain, group, pasid);
-	if (ret) {
-		__iommu_remove_group_pasid(group, pasid, domain);
+	if (ret)
 		xa_erase(&group->pasid_array, pasid);
-	}
 out_unlock:
 	mutex_unlock(&group->mutex);
 	return ret;