static void ttm_release_base(struct ttm_base_object *base) { struct ttm_object_device *tdev = base->tfile->tdev; mtx_enter(&tdev->object_lock); (void)drm_ht_remove_item_rcu(&tdev->object_hash, &base->hash); mtx_leave(&tdev->object_lock); /* * Note: We don't use synchronize_rcu() here because it's far * too slow. It's up to the user to free the object using * call_rcu() or ttm_base_object_free(). */ if (base->refcount_release) { ttm_object_file_unref(&base->tfile); base->refcount_release(&base); } }
static void ttm_release_base(struct kref *kref) { struct ttm_base_object *base = container_of(kref, struct ttm_base_object, refcount); struct ttm_object_device *tdev = base->tfile->tdev; spin_lock(&tdev->object_lock); (void)drm_ht_remove_item_rcu(&tdev->object_hash, &base->hash); spin_unlock(&tdev->object_lock); /* * Note: We don't use synchronize_rcu() here because it's far * too slow. It's up to the user to free the object using * call_rcu() or ttm_base_object_kfree(). */ ttm_object_file_unref(&base->tfile); if (base->refcount_release) base->refcount_release(&base); }
int ttm_base_object_init(struct ttm_object_file *tfile, struct ttm_base_object *base, bool shareable, enum ttm_object_type object_type, void (*refcount_release) (struct ttm_base_object **), void (*ref_obj_release) (struct ttm_base_object *, enum ttm_ref_type ref_type)) { struct ttm_object_device *tdev = tfile->tdev; int ret; base->shareable = shareable; base->tfile = ttm_object_file_ref(tfile); base->refcount_release = refcount_release; base->ref_obj_release = ref_obj_release; base->object_type = object_type; kref_init(&base->refcount); spin_lock(&tdev->object_lock); ret = drm_ht_just_insert_please_rcu(&tdev->object_hash, &base->hash, (unsigned long)base, 31, 0, 0); spin_unlock(&tdev->object_lock); if (unlikely(ret != 0)) goto out_err0; ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); if (unlikely(ret != 0)) goto out_err1; ttm_base_object_unref(&base); return 0; out_err1: spin_lock(&tdev->object_lock); (void)drm_ht_remove_item_rcu(&tdev->object_hash, &base->hash); spin_unlock(&tdev->object_lock); out_err0: return ret; }