diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a54a9631f59e..825d75c548b8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3262,7 +3262,13 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file) vma = radix_tree_delete(&ctx->handles_vma, lut->handle); - if (!i915_vma_is_ggtt(vma)) + GEM_BUG_ON(vma->obj != obj); + + /* We allow the process to have multiple handles to the same + * vma, in the same fd namespace, by virtue of flink/open. + */ + GEM_BUG_ON(!vma->open_count); + if (!--vma->open_count && !i915_vma_is_ggtt(vma)) i915_vma_close(vma); list_del(&lut->obj_link); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 25b14d492d91..944e9e543573 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -720,6 +720,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) goto err_obj; } + vma->open_count++; list_add(&lut->obj_link, &obj->lut_list); list_add(&lut->ctx_link, &eb->ctx->handles_list); lut->ctx = eb->ctx; diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 1fd61e88cfd0..e811067c7724 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -59,6 +59,12 @@ struct i915_vma { u32 fence_size; u32 fence_alignment; + /** + * Count of the number of times this vma has been opened by different + * handles (but same file) for execbuf, i.e. the number of aliases + * that exist in the ctx->handle_vmas LUT for this vma. + */ + unsigned int open_count; unsigned int flags; /** * How many users have pinned this object in GTT space. The following