diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2014-03-19 08:23:20 -0400 |
---|---|---|
committer | Thomas Hellstrom <thellstrom@vmware.com> | 2014-03-28 09:19:03 -0400 |
commit | 0d3215e3857ab679f74c9b26b7e711955c9d0438 (patch) | |
tree | 65f7255ca8ef0700b754a71a07bada5c5a89c0a2 | |
parent | 6d10aab8f0658d624e5aafcd52b70afa23a75e5e (diff) |
drm/ttm: Add a ttm_ref_object_exists function
A function to be used to check whether a caller has put a ref object
(opened) a struct ttm_base_object
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_object.c | 46 | ||||
-rw-r--r-- | include/drm/ttm/ttm_object.h | 4 |
2 files changed, 50 insertions, 0 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c index 53b51c4e671a..d2a053352789 100644 --- a/drivers/gpu/drm/ttm/ttm_object.c +++ b/drivers/gpu/drm/ttm/ttm_object.c | |||
@@ -270,6 +270,52 @@ ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key) | |||
270 | } | 270 | } |
271 | EXPORT_SYMBOL(ttm_base_object_lookup_for_ref); | 271 | EXPORT_SYMBOL(ttm_base_object_lookup_for_ref); |
272 | 272 | ||
273 | /** | ||
274 | * ttm_ref_object_exists - Check whether a caller has a valid ref object | ||
275 | * (has opened) a base object. | ||
276 | * | ||
277 | * @tfile: Pointer to a struct ttm_object_file identifying the caller. | ||
278 | * @base: Pointer to a struct base object. | ||
279 | * | ||
280 | * Checks wether the caller identified by @tfile has put a valid USAGE | ||
281 | * reference object on the base object identified by @base. | ||
282 | */ | ||
283 | bool ttm_ref_object_exists(struct ttm_object_file *tfile, | ||
284 | struct ttm_base_object *base) | ||
285 | { | ||
286 | struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE]; | ||
287 | struct drm_hash_item *hash; | ||
288 | struct ttm_ref_object *ref; | ||
289 | |||
290 | rcu_read_lock(); | ||
291 | if (unlikely(drm_ht_find_item_rcu(ht, base->hash.key, &hash) != 0)) | ||
292 | goto out_false; | ||
293 | |||
294 | /* | ||
295 | * Verify that the ref object is really pointing to our base object. | ||
296 | * Our base object could actually be dead, and the ref object pointing | ||
297 | * to another base object with the same handle. | ||
298 | */ | ||
299 | ref = drm_hash_entry(hash, struct ttm_ref_object, hash); | ||
300 | if (unlikely(base != ref->obj)) | ||
301 | goto out_false; | ||
302 | |||
303 | /* | ||
304 | * Verify that the ref->obj pointer was actually valid! | ||
305 | */ | ||
306 | rmb(); | ||
307 | if (unlikely(atomic_read(&ref->kref.refcount) == 0)) | ||
308 | goto out_false; | ||
309 | |||
310 | rcu_read_unlock(); | ||
311 | return true; | ||
312 | |||
313 | out_false: | ||
314 | rcu_read_unlock(); | ||
315 | return false; | ||
316 | } | ||
317 | EXPORT_SYMBOL(ttm_ref_object_exists); | ||
318 | |||
273 | int ttm_ref_object_add(struct ttm_object_file *tfile, | 319 | int ttm_ref_object_add(struct ttm_object_file *tfile, |
274 | struct ttm_base_object *base, | 320 | struct ttm_base_object *base, |
275 | enum ttm_ref_type ref_type, bool *existed) | 321 | enum ttm_ref_type ref_type, bool *existed) |
diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h index 0097cc03034e..ed953f98f0e1 100644 --- a/include/drm/ttm/ttm_object.h +++ b/include/drm/ttm/ttm_object.h | |||
@@ -244,6 +244,10 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base); | |||
244 | extern int ttm_ref_object_add(struct ttm_object_file *tfile, | 244 | extern int ttm_ref_object_add(struct ttm_object_file *tfile, |
245 | struct ttm_base_object *base, | 245 | struct ttm_base_object *base, |
246 | enum ttm_ref_type ref_type, bool *existed); | 246 | enum ttm_ref_type ref_type, bool *existed); |
247 | |||
248 | extern bool ttm_ref_object_exists(struct ttm_object_file *tfile, | ||
249 | struct ttm_base_object *base); | ||
250 | |||
247 | /** | 251 | /** |
248 | * ttm_ref_object_base_unref | 252 | * ttm_ref_object_base_unref |
249 | * | 253 | * |