/** * drm_gem_free_mmap_offset - release a fake mmap offset for an object * @obj: obj in question * * This routine frees fake offsets allocated by drm_gem_create_mmap_offset(). */ void drm_gem_free_mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_gem_mm *mm = dev->mm_private; struct drm_map_list *list = &obj->map_list; drm_ht_remove_item(&mm->offset_hash, &list->hash); drm_mm_put_block(list->file_offset_node); kfree(list->map); list->map = NULL; }
void drm_gem_object_release_wrap(struct drm_gem_object *obj) { /* Remove the list map if one is present */ if (obj->map_list.map) { struct drm_gem_mm *mm = obj->dev->mm_private; struct drm_map_list *list = &obj->map_list; drm_ht_remove_item(&mm->offset_hash, &list->hash); drm_mm_put_block(list->file_offset_node); kfree(list->map); list->map = NULL; } drm_gem_object_release(obj); }
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; (void)drm_ht_remove_item(&tdev->object_hash, &base->hash); write_unlock(&tdev->object_lock); if (base->refcount_release) { ttm_object_file_unref(&base->tfile); base->refcount_release(&base); } write_lock(&tdev->object_lock); }
void drm_gem_free_mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_gem_mm *mm = dev->mm_private; struct drm_hash_item *list = &obj->map_list; if (!obj->on_map) return; drm_ht_remove_item(&mm->offset_hash, list); free_unr(mm->idxunr, list->key); obj->on_map = false; }
static void ttm_release_base(struct ttm_base_object *base) { struct ttm_object_device *tdev = base->tfile->tdev; (void)drm_ht_remove_item(&tdev->object_hash, &base->hash); rw_wunlock(&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(). */ if (base->refcount_release) { ttm_object_file_unref(&base->tfile); base->refcount_release(&base); } rw_wlock(&tdev->object_lock); }
/** * Removes the given magic number from the hash table of used magic number * lists. */ static int drm_remove_magic(struct drm_device *dev, drm_magic_t magic) { drm_magic_entry_t *pt; struct drm_hash_item *hash; DRM_DEBUG("%d\n", magic); mutex_lock(&dev->struct_mutex); if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { mutex_unlock(&dev->struct_mutex); return -EINVAL; } pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item); drm_ht_remove_item(&dev->magiclist, hash); list_del(&pt->head); mutex_unlock(&dev->struct_mutex); kfree(pt); return 0; }
int ttm_base_object_init(struct ttm_object_file *tfile, struct ttm_base_object *base, bool shareable, enum ttm_object_type object_type, void (*rcount_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 = rcount_release; base->ref_obj_release = ref_obj_release; base->object_type = object_type; refcount_init(&base->refcount, 1); rw_init(&tdev->object_lock, "ttmbao"); rw_wlock(&tdev->object_lock); ret = drm_ht_just_insert_please(&tdev->object_hash, &base->hash, (unsigned long)base, 31, 0, 0); rw_wunlock(&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: rw_wlock(&tdev->object_lock); (void)drm_ht_remove_item(&tdev->object_hash, &base->hash); rw_wunlock(&tdev->object_lock); out_err0: return ret; }
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; if (atomic_read(&kref->refcount)) { lockmgr(&tdev->object_lock, LK_RELEASE); return; } (void)drm_ht_remove_item(&tdev->object_hash, &base->hash); lockmgr(&tdev->object_lock, LK_RELEASE); /* * 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(). */ if (base->refcount_release) { ttm_object_file_unref(&base->tfile); base->refcount_release(&base); } }