Skip to content

Commit f6cd7da

Browse files
ickledanvet
authored andcommitted
drm: Release driver references to handle before making it available again
When userspace closes a handle, we remove it from the file->object_idr and then tell the driver to drop its references to that file/handle. However, as the file/handle is already available again for reuse, it may be reallocated back to userspace and active on a new object before the driver has had a chance to drop the old file/handle references. Whilst calling back into the driver, we have to drop the file->table_lock spinlock and so to prevent reusing the closed handle we mark that handle as stale in the idr, perform the callback and then remove the handle. We set the stale handle to point to the NULL object, then any idr_find() whilst the driver is removing the handle will return NULL, just as if the handle is already removed from idr. Note: This will be used to have a direct handle -> vma lookup table, instead of first a handle -> obj lookup, and then an (obj, vm) -> vma lookup. v2: Use NULL rather than an ERR_PTR to avoid having to adjust callers. idr_alloc() tracks existing handles using an internal bitmap, so we are free to use the NULL object as our stale identifier. v3: Needed to update the return value check after changing from using the stale error pointer to NULL. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: dri-devel@lists.freedesktop.org Cc: David Airlie <airlied@linux.ie> Cc: Daniel Vetter <daniel.vetter@intel.com> Cc: Rob Clark <robdclark@gmail.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Thierry Reding <treding@nvidia.com> [danvet: Add note about the use-case.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1460721308-32405-1-git-send-email-chris@chris-wilson.co.uk
1 parent 40ae80c commit f6cd7da

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

drivers/gpu/drm/drm_gem.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
279279
int
280280
drm_gem_handle_delete(struct drm_file *filp, u32 handle)
281281
{
282-
struct drm_device *dev;
283282
struct drm_gem_object *obj;
284283

285284
/* This is gross. The idr system doesn't let us try a delete and
@@ -294,18 +293,19 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
294293
spin_lock(&filp->table_lock);
295294

296295
/* Check if we currently have a reference on the object */
297-
obj = idr_find(&filp->object_idr, handle);
298-
if (obj == NULL) {
299-
spin_unlock(&filp->table_lock);
296+
obj = idr_replace(&filp->object_idr, NULL, handle);
297+
spin_unlock(&filp->table_lock);
298+
if (IS_ERR_OR_NULL(obj))
300299
return -EINVAL;
301-
}
302-
dev = obj->dev;
303300

304-
/* Release reference and decrement refcount. */
301+
/* Release driver's reference and decrement refcount. */
302+
drm_gem_object_release_handle(handle, obj, filp);
303+
304+
/* And finally make the handle available for future allocations. */
305+
spin_lock(&filp->table_lock);
305306
idr_remove(&filp->object_idr, handle);
306307
spin_unlock(&filp->table_lock);
307308

308-
drm_gem_object_release_handle(handle, obj, filp);
309309
return 0;
310310
}
311311
EXPORT_SYMBOL(drm_gem_handle_delete);

0 commit comments

Comments
 (0)