/** * Called at device close to release the file's * handle references on objects. */ static int drm_gem_object_release_handle(int id, void *ptr, void *data) { struct drm_file *file_priv = data; struct drm_gem_object *obj = ptr; struct drm_device *dev = obj->dev; drm_gem_remove_prime_handles(obj, file_priv); if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, file_priv); drm_gem_object_handle_unreference_unlocked(obj); return 0; }
/* * Called at device close to release the file's * handle references on objects. */ static int drm_gem_object_release_handle(int id, void *ptr, void *data) { struct drm_file *file_priv = data; struct drm_gem_object *obj = ptr; struct drm_device *dev = obj->dev; if (drm_core_check_feature(dev, DRIVER_PRIME)) drm_gem_remove_prime_handles(obj, file_priv); drm_vma_node_revoke(&obj->vma_node, file_priv->filp); if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, file_priv); drm_gem_object_handle_unreference_unlocked(obj); return 0; }
static int drm_gem_object_release_handle(uint32_t name, void *ptr, void *data) { struct drm_file *file_priv = data; struct drm_gem_object *obj = ptr; struct drm_device *dev = obj->dev; #if defined(FREEBSD_NOTYET) drm_gem_remove_prime_handles(obj, file_priv); #endif if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, file_priv); drm_gem_object_handle_unreference_unlocked(obj); return 0; }
/** * drm_gem_handle_delete - deletes the given file-private handle * @filp: drm file-private structure to use for the handle look up * @handle: userspace handle to delete * * Removes the GEM handle from the @filp lookup table and if this is the last * handle also cleans up linked resources like GEM names. */ int drm_gem_handle_delete(struct drm_file *filp, u32 handle) { struct drm_device *dev; struct drm_gem_object *obj; /* This is gross. The idr system doesn't let us try a delete and * return an error code. It just spews if you fail at deleting. * So, we have to grab a lock around finding the object and then * doing the delete on it and dropping the refcount, or the user * could race us to double-decrement the refcount and cause a * use-after-free later. Given the frequency of our handle lookups, * we may want to use ida for number allocation and a hash table * for the pointers, anyway. */ spin_lock(&filp->table_lock); /* Check if we currently have a reference on the object */ obj = idr_find(&filp->object_idr, handle); if (obj == NULL) { spin_unlock(&filp->table_lock); return -EINVAL; } dev = obj->dev; /* Release reference and decrement refcount. */ idr_remove(&filp->object_idr, handle); spin_unlock(&filp->table_lock); if (drm_core_check_feature(dev, DRIVER_PRIME)) drm_gem_remove_prime_handles(obj, filp); drm_vma_node_revoke(&obj->vma_node, filp->filp); if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, filp); drm_gem_object_handle_unreference_unlocked(obj); return 0; }
/** * Removes the mapping from handle to filp for this object. */ int drm_gem_handle_delete(struct drm_file *filp, u32 handle) { struct drm_device *dev; struct drm_gem_object *obj; obj = drm_gem_names_remove(&filp->object_names, handle); if (obj == NULL) { return -EINVAL; } dev = obj->dev; #if defined(FREEBSD_NOTYET) drm_gem_remove_prime_handles(obj, filp); #endif if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, filp); drm_gem_object_handle_unreference_unlocked(obj); return 0; }