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(¶m->lock); > fault_param = rcu_dereference_check(param->fault_param, > lockdep_is_held(¶m->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