Skip to contentSkip to conversation

gpu: host1x: Acquire a reference to the IOVA cache

PATCH In review Thierry Reding 2 participants 3 messages May 14, 2018

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 gpu: host1x: Acquire a reference to the IOVA cache

From: Thierry Reding <[email protected]>

The IOVA API uses a memory cache to allocate IOVA nodes from. To make sure that this cache is available, obtain a reference to it and release the reference when the cache is no longer needed.

On 64-bit ARM this is hidden by the fact that the DMA mapping API gets that reference and never releases it. On 32-bit ARM, this is papered over by the Tegra DRM driver (the sole user of the host1x API requiring the cache) acquiring a reference to the IOVA cache for its own purposes. However, there may be additional users of this API in the future, so fix this upfront to avoid surprises.

Fixes 404bfb78daf3 ("gpu: host1x: Add IOMMU support")
---
 drivers/gpu/host1x/dev.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/gpu/host1x/dev.c +10 -1
index 03db71173f5d..f1d5f76e9c33 100644
@@ -223,10 +223,14 @@ static int host1x_probe(struct platform_device *pdev)
 		struct iommu_domain_geometry *geometry;
 		unsigned long order;
 
+		err = iova_cache_get();
+		if (err < 0)
+			goto put_group;
+
 		host->domain = iommu_domain_alloc(&platform_bus_type);
 		if (!host->domain) {
 			err = -ENOMEM;
-			goto put_group;
+			goto put_cache;
 		}
 
 		err = iommu_attach_group(host->domain, host->group);
@@ -234,6 +238,7 @@ static int host1x_probe(struct platform_device *pdev)
 			if (err == -ENODEV) {
 				iommu_domain_free(host->domain);
 				host->domain = NULL;
+				iova_cache_put();
 				iommu_group_put(host->group);
 				host->group = NULL;
 				goto skip_iommu;
@@ -308,6 +313,9 @@ static int host1x_probe(struct platform_device *pdev)
 fail_free_domain:
 	if (host->domain)
 		iommu_domain_free(host->domain);
+put_cache:
+	if (host->group)
+		iova_cache_put();
 put_group:
 	iommu_group_put(host->group);
 
@@ -328,6 +336,7 @@ static int host1x_remove(struct platform_device *pdev)
 		put_iova_domain(&host->iova);
 		iommu_detach_group(host->domain, host->group);
 		iommu_domain_free(host->domain);
+		iova_cache_put();
 		iommu_group_put(host->group);
 	}
 
Signature · 6 lines
2.17.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Reviewed-by on v1 1/1
#1 lore raw
Quoted 59 lines · Thierry Reding

From: Thierry Reding <[email protected]>

The IOVA API uses a memory cache to allocate IOVA nodes from. To make sure that this cache is available, obtain a reference to it and release the reference when the cache is no longer needed.

On 64-bit ARM this is hidden by the fact that the DMA mapping API gets that reference and never releases it. On 32-bit ARM, this is papered over by the Tegra DRM driver (the sole user of the host1x API requiring the cache) acquiring a reference to the IOVA cache for its own purposes. However, there may be additional users of this API in the future, so fix this upfront to avoid surprises.

Fixes 404bfb78daf3 ("gpu: host1x: Add IOMMU support")
---
 drivers/gpu/host1x/dev.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/gpu/host1x/dev.c +9 -1
index 03db71173f5d..f1d5f76e9c33 100644
@@ -223,10 +223,14 @@ static int host1x_probe(struct platform_device *pdev)
 		struct iommu_domain_geometry *geometry;
 		unsigned long order;
 
+		err = iova_cache_get();
+		if (err < 0)
+			goto put_group;
+
 		host->domain = iommu_domain_alloc(&platform_bus_type);
 		if (!host->domain) {
 			err = -ENOMEM;
-			goto put_group;
+			goto put_cache;
 		}
 
 		err = iommu_attach_group(host->domain, host->group);
@@ -234,6 +238,7 @@ static int host1x_probe(struct platform_device *pdev)
 			if (err == -ENODEV) {
 				iommu_domain_free(host->domain);
 				host->domain = NULL;
+				iova_cache_put();
 				iommu_group_put(host->group);
 				host->group = NULL;
 				goto skip_iommu;
@@ -308,6 +313,9 @@ static int host1x_probe(struct platform_device *pdev)
 fail_free_domain:
 	if (host->domain)
 		iommu_domain_free(host->domain);
+put_cache:
+	if (host->group)
+		iova_cache_put();
 put_group:
 	iommu_group_put(host->group);
 

drivers/gpu/host1x/dev.c static int host1x_remove(struct platform_device *pdev) · line 342

Quoted 7 lines
drivers/gpu/host1x/dev.c +1 -0
@@ -328,6 +336,7 @@ static int host1x_remove(struct platform_device *pdev)
 		put_iova_domain(&host->iova);
 		iommu_detach_group(host->domain, host->group);
 		iommu_domain_free(host->domain);
+		iova_cache_put();
 		iommu_group_put(host->group);
 	}
 

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

author Applied
#2 lore raw
Quoted 14 lines · Dmitry Osipenko
Quoted 13 lines · Thierry Reding

From: Thierry Reding <[email protected]>

The IOVA API uses a memory cache to allocate IOVA nodes from. To make sure that this cache is available, obtain a reference to it and release the reference when the cache is no longer needed.

On 64-bit ARM this is hidden by the fact that the DMA mapping API gets that reference and never releases it. On 32-bit ARM, this is papered over by the Tegra DRM driver (the sole user of the host1x API requiring the cache) acquiring a reference to the IOVA cache for its own purposes. However, there may be additional users of this API in the future, so fix this upfront to avoid surprises.

Quoted 5 lines
Quoted 5 lines
Fixes 404bfb78daf3 ("gpu: host1x: Add IOMMU support")
---
 drivers/gpu/host1x/dev.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

Applied, thanks.

Thierry

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel