···270270}271271EXPORT_SYMBOL(ttm_base_object_lookup_for_ref);272272273273+/**274274+ * ttm_ref_object_exists - Check whether a caller has a valid ref object275275+ * (has opened) a base object.276276+ *277277+ * @tfile: Pointer to a struct ttm_object_file identifying the caller.278278+ * @base: Pointer to a struct base object.279279+ *280280+ * Checks wether the caller identified by @tfile has put a valid USAGE281281+ * reference object on the base object identified by @base.282282+ */283283+bool ttm_ref_object_exists(struct ttm_object_file *tfile,284284+ struct ttm_base_object *base)285285+{286286+ struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE];287287+ struct drm_hash_item *hash;288288+ struct ttm_ref_object *ref;289289+290290+ rcu_read_lock();291291+ if (unlikely(drm_ht_find_item_rcu(ht, base->hash.key, &hash) != 0))292292+ goto out_false;293293+294294+ /*295295+ * Verify that the ref object is really pointing to our base object.296296+ * Our base object could actually be dead, and the ref object pointing297297+ * to another base object with the same handle.298298+ */299299+ ref = drm_hash_entry(hash, struct ttm_ref_object, hash);300300+ if (unlikely(base != ref->obj))301301+ goto out_false;302302+303303+ /*304304+ * Verify that the ref->obj pointer was actually valid!305305+ */306306+ rmb();307307+ if (unlikely(atomic_read(&ref->kref.refcount) == 0))308308+ goto out_false;309309+310310+ rcu_read_unlock();311311+ return true;312312+313313+ out_false:314314+ rcu_read_unlock();315315+ return false;316316+}317317+EXPORT_SYMBOL(ttm_ref_object_exists);318318+273319int ttm_ref_object_add(struct ttm_object_file *tfile,274320 struct ttm_base_object *base,275321 enum ttm_ref_type ref_type, bool *existed)