summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMikko Perttunen <mperttunen@nvidia.com>2026-05-15 05:34:51 +0300
committerThierry Reding <treding@nvidia.com>2026-05-28 18:19:28 +0300
commit3cbf5e3c46e66d9b3b6b91099bb720c6cb1be3bc (patch)
tree19c326421f743da2cf77ad858f579cf6a90708ea /include
parentace01e2af3871343d700fb60c6f64d8f8e3180e1 (diff)
downloadlinux-3cbf5e3c46e66d9b3b6b91099bb720c6cb1be3bc.tar.xz
gpu: host1x: Allow entries in BO caches to be freed
When a buffer object is pinned via host1x_bo_pin() with a cache, the resulting mapping is kept in the cache so it can be reused on subsequent pins. Each mapping held a reference to the underlying host1x_bo (taken in tegra_bo_pin / gather_bo_pin), so as long as a mapping was cached, the bo itself could not be freed. However, the only way to remove the cached mapping was through the free path of the buffer object. This meant that if a bo got cached, it could never get freed again. Resolve the circularity by holding a weak reference to the bo from the cache side. This is done by having the .pin callbacks not bump the bo's refcount -- instead the common Host1x bo code does so, except for the cache reference. Also move the remove-cache-mapping-on-free code into a common function inside Host1x code. This is only called from the TegraDRM GEM buffers since those are the only ones that can be cached at the moment. Reported-by: Aaron Kling <webgeek1234@gmail.com> Fixes: 1f39b1dfa53c ("drm/tegra: Implement buffer object cache") Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Tested-by: Aaron Kling <webgeek1234@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patch.msgid.link/20260515-host1x-bocache-leak-v1-1-a0375f68aeab@nvidia.com
Diffstat (limited to 'include')
-rw-r--r--include/linux/host1x.h7
1 files changed, 7 insertions, 0 deletions
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index 1f5f55917d1c..a7a675783136 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -143,6 +143,12 @@ static inline struct host1x_bo_mapping *to_host1x_bo_mapping(struct kref *ref)
return container_of(ref, struct host1x_bo_mapping, ref);
}
+/**
+ * struct host1x_bo_ops - operations implemented by a host1x_bo provider
+ *
+ * @pin: create a DMA mapping. Implementation must not touch the bo's refcount.
+ * @unpin: destroy a DMA mapping. Implementation must not touch the bo's refcount.
+ */
struct host1x_bo_ops {
struct host1x_bo *(*get)(struct host1x_bo *bo);
void (*put)(struct host1x_bo *bo);
@@ -181,6 +187,7 @@ struct host1x_bo_mapping *host1x_bo_pin(struct device *dev, struct host1x_bo *bo
enum dma_data_direction dir,
struct host1x_bo_cache *cache);
void host1x_bo_unpin(struct host1x_bo_mapping *map);
+void host1x_bo_clear_cached_mappings(struct host1x_bo *bo);
static inline void *host1x_bo_mmap(struct host1x_bo *bo)
{