summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vmwgfx/ttm_object.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2018-09-26 15:55:16 +0200
committerThomas Hellstrom <thellstrom@vmware.com>2018-09-27 16:14:48 +0200
commite14c02e6b6990e9f6ee18a214a22ac26bae1b25e (patch)
tree42258a937b40f01e9dcd935b089f68f6f824a0c3 /drivers/gpu/drm/vmwgfx/ttm_object.c
parentc7eae62666ade1c8c9960085911e420227144d5a (diff)
drm/vmwgfx: Look up objects without taking a reference
Typically when we look up objects under the rcu lock, we take a reference to make sure the returned object pointer is valid. Now provide a function to look up an object and instead of taking a reference to it, keep the rcu lock held when returning the object pointer. This means that the object pointer is valid as long as the rcu lock is held, but the object may be doomed (its refcount may be zero). Any persistent usage of the object pointer outside of the rcu lock requires a reference to be taken using kref_get_unless_zero(). Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/ttm_object.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/ttm_object.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c
index c5df2d7828e6..36990b80e790 100644
--- a/drivers/gpu/drm/vmwgfx/ttm_object.c
+++ b/drivers/gpu/drm/vmwgfx/ttm_object.c
@@ -225,6 +225,41 @@ void ttm_base_object_unref(struct ttm_base_object **p_base)
kref_put(&base->refcount, ttm_release_base);
}
+/**
+ * ttm_base_object_noref_lookup - look up a base object without reference
+ * @tfile: The struct ttm_object_file the object is registered with.
+ * @key: The object handle.
+ *
+ * This function looks up a ttm base object and returns a pointer to it
+ * without refcounting the pointer. The returned pointer is only valid
+ * until ttm_base_object_noref_release() is called, and the object
+ * pointed to by the returned pointer may be doomed. Any persistent usage
+ * of the object requires a refcount to be taken using kref_get_unless_zero().
+ * Iff this function returns successfully it needs to be paired with
+ * ttm_base_object_noref_release() and no sleeping- or scheduling functions
+ * may be called inbetween these function callse.
+ *
+ * Return: A pointer to the object if successful or NULL otherwise.
+ */
+struct ttm_base_object *
+ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key)
+{
+ struct drm_hash_item *hash;
+ struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];
+ int ret;
+
+ rcu_read_lock();
+ ret = drm_ht_find_item_rcu(ht, key, &hash);
+ if (ret) {
+ rcu_read_unlock();
+ return NULL;
+ }
+
+ __release(RCU);
+ return drm_hash_entry(hash, struct ttm_ref_object, hash)->obj;
+}
+EXPORT_SYMBOL(ttm_base_object_noref_lookup);
+
struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
uint32_t key)
{