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); 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) -- 2.34.1