Re: [PATCH v9 13/14] iommu: Improve iopf_queue_remove_device()

From: Jason Gunthorpe
Date: Fri Jan 05 2024 - 11:25:52 EST


On Wed, Dec 20, 2023 at 09:23:31AM +0800, Lu Baolu wrote:
> -int iopf_queue_remove_device(struct iopf_queue *queue, struct device *dev)
> +void iopf_queue_remove_device(struct iopf_queue *queue, struct device *dev)
> {
> - int ret = 0;
> struct iopf_fault *iopf, *next;
> + struct iommu_page_response resp;
> struct dev_iommu *param = dev->iommu;
> struct iommu_fault_param *fault_param;
> + const struct iommu_ops *ops = dev_iommu_ops(dev);
>
> mutex_lock(&queue->lock);
> mutex_lock(&param->lock);
> fault_param = rcu_dereference_check(param->fault_param,
> lockdep_is_held(&param->lock));
> - if (!fault_param) {
> - ret = -ENODEV;
> - goto unlock;
> - }
> -
> - if (fault_param->queue != queue) {
> - ret = -EINVAL;
> - goto unlock;
> - }
>
> - if (!list_empty(&fault_param->faults)) {
> - ret = -EBUSY;
> + if (WARN_ON(!fault_param || fault_param->queue != queue))
> goto unlock;
> - }
> -
> - list_del(&fault_param->queue_list);
>
> - /* Just in case some faults are still stuck */
> + mutex_lock(&fault_param->lock);
> list_for_each_entry_safe(iopf, next, &fault_param->partial, list)
> kfree(iopf);
>
> + list_for_each_entry_safe(iopf, next, &fault_param->faults, list) {
> + memset(&resp, 0, sizeof(struct iommu_page_response));
> + resp.pasid = iopf->fault.prm.pasid;
> + resp.grpid = iopf->fault.prm.grpid;
> + resp.code = IOMMU_PAGE_RESP_INVALID;

I would probably move the resp and iopf variables into here:

struct iopf_fault *iopf = &group->last_fault;
struct iommu_page_response resp = {
.pasid = iopf->fault.prm.pasid,
.grpid = iopf->fault.prm.grpid,
.code = IOMMU_PAGE_RESP_INVALID
};

(and call the other one partial_iopf)

But this looks fine either way

Reviewed-by: Jason Gunthorpe <jgg@xxxxxxxxxx>

Jason