Hi BaoLu, On Tue, 11 Jul 2023 09:06:42 +0800, Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> wrote: > Remove the static iopf_param pointer from struct iommu_fault_param to > save memory. > > Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> > --- > include/linux/iommu.h | 2 -- > drivers/iommu/io-pgfault.c | 47 +++++++++++++++++++++++--------------- > 2 files changed, 29 insertions(+), 20 deletions(-) > > diff --git a/include/linux/iommu.h b/include/linux/iommu.h > index ffd6fe1317f4..5fe37a7c5a55 100644 > --- a/include/linux/iommu.h > +++ b/include/linux/iommu.h > @@ -551,7 +551,6 @@ struct iommu_fault_param { > * struct dev_iommu - Collection of per-device IOMMU data > * > * @fault_param: IOMMU detected device fault reporting data > - * @iopf_param: I/O Page Fault queue and data > * @fwspec: IOMMU fwspec data > * @iommu_dev: IOMMU device this device is linked to > * @priv: IOMMU Driver private data > @@ -564,7 +563,6 @@ struct iommu_fault_param { > struct dev_iommu { > struct mutex lock; > struct iommu_fault_param *fault_param; > - struct iopf_device_param *iopf_param; > struct iommu_fwspec *fwspec; > struct iommu_device *iommu_dev; > void *priv; > diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c > index 1749e0869f2e..6a3a4e08e67e 100644 > --- a/drivers/iommu/io-pgfault.c > +++ b/drivers/iommu/io-pgfault.c > @@ -158,7 +158,7 @@ int iommu_queue_iopf(struct iommu_fault *fault, > struct device *dev) > * As long as we're holding param->lock, the queue can't be > unlinked > * from the device and therefore cannot disappear. > */ > - iopf_param = param->iopf_param; > + iopf_param = iommu_get_device_fault_cookie(dev, 0); I am not sure I understand how does it know the cookie type is iopf_param for PASID 0? Between IOPF and IOMMUFD use of the cookie, cookie types are different, right? > if (!iopf_param) > return -ENODEV; > > @@ -235,7 +235,7 @@ int iopf_queue_flush_dev(struct device *dev) > return -ENODEV; > > mutex_lock(¶m->lock); > - iopf_param = param->iopf_param; > + iopf_param = iommu_get_device_fault_cookie(dev, 0); > if (iopf_param) > flush_workqueue(iopf_param->queue->wq); > else > @@ -286,9 +286,9 @@ EXPORT_SYMBOL_GPL(iopf_queue_discard_partial); > */ > int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev) > { > - int ret = -EBUSY; > - struct iopf_device_param *iopf_param; > + struct iopf_device_param *iopf_param, *curr; > struct dev_iommu *param = dev->iommu; > + int ret; > > if (!param) > return -ENODEV; > @@ -303,16 +303,27 @@ int iopf_queue_add_device(struct iopf_queue *queue, > struct device *dev) > mutex_lock(&queue->lock); > mutex_lock(¶m->lock); > - if (!param->iopf_param) { > - list_add(&iopf_param->queue_list, &queue->devices); > - param->iopf_param = iopf_param; > - ret = 0; > + curr = iommu_set_device_fault_cookie(dev, 0, iopf_param); > + if (IS_ERR(curr)) { > + ret = PTR_ERR(curr); > + goto err_free; > } > + > + if (curr) { > + ret = -EBUSY; > + goto err_restore; > + } > + list_add(&iopf_param->queue_list, &queue->devices); > mutex_unlock(¶m->lock); > mutex_unlock(&queue->lock); > > - if (ret) > - kfree(iopf_param); > + return 0; > +err_restore: > + iommu_set_device_fault_cookie(dev, 0, curr); > +err_free: > + mutex_unlock(¶m->lock); > + mutex_unlock(&queue->lock); > + kfree(iopf_param); > > return ret; > } > @@ -329,7 +340,6 @@ EXPORT_SYMBOL_GPL(iopf_queue_add_device); > */ > int iopf_queue_remove_device(struct iopf_queue *queue, struct device > *dev) { > - int ret = -EINVAL; > struct iopf_fault *iopf, *next; > struct iopf_device_param *iopf_param; > struct dev_iommu *param = dev->iommu; > @@ -339,16 +349,17 @@ int iopf_queue_remove_device(struct iopf_queue > *queue, struct device *dev) > mutex_lock(&queue->lock); > mutex_lock(¶m->lock); > - iopf_param = param->iopf_param; > - if (iopf_param && iopf_param->queue == queue) { > - list_del(&iopf_param->queue_list); > - param->iopf_param = NULL; > - ret = 0; > + iopf_param = iommu_get_device_fault_cookie(dev, 0); > + if (!iopf_param || iopf_param->queue != queue) { > + mutex_unlock(¶m->lock); > + mutex_unlock(&queue->lock); > + return -EINVAL; > } > + > + list_del(&iopf_param->queue_list); > + iommu_set_device_fault_cookie(dev, 0, NULL); > mutex_unlock(¶m->lock); > mutex_unlock(&queue->lock); > - if (ret) > - return ret; > > /* Just in case some faults are still stuck */ > list_for_each_entry_safe(iopf, next, &iopf_param->partial, list) Thanks, Jacob