Define a mutex for the exclusive use of interacting with the per-file context-idr, that was previously guarded by struct_mutex. This allows us to reduce the coverage of struct_mutex, with a view to removing the last bits coordinating GEM context later. (In the short term, we avoid taking struct_mutex while using the extended constructor functions, preventing some nasty recursion.) Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem_context.c | 43 +++++++++++-------------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 86080a6e0f45..90389333dd47 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -216,7 +216,9 @@ struct drm_i915_file_private { */ #define DRM_I915_THROTTLE_JIFFIES msecs_to_jiffies(20) } mm; + struct idr context_idr; + struct mutex context_lock; /* guards context_idr */ unsigned int bsd_engine; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 5df3d423ec6c..94c466d4b29e 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -579,9 +579,7 @@ void i915_gem_contexts_fini(struct drm_i915_private *i915) static int context_idr_cleanup(int id, void *p, void *data) { - struct i915_gem_context *ctx = p; - - context_close(ctx); + context_close(p); return 0; } @@ -596,8 +594,10 @@ static int gem_context_register(struct i915_gem_context *ctx, ctx->ppgtt->vm.file = fpriv; /* And (nearly) finally expose ourselves to userspace via the idr */ + mutex_lock(&fpriv->context_lock); ret = idr_alloc(&fpriv->context_idr, ctx, DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL); + mutex_unlock(&fpriv->context_lock); if (ret < 0) goto err_pid; @@ -616,7 +616,9 @@ static int gem_context_register(struct i915_gem_context *ctx, return 0; err_idr: + mutex_lock(&fpriv->context_lock); idr_remove(&fpriv->context_idr, ctx->user_handle); + mutex_unlock(&fpriv->context_lock); ctx->file_priv = NULL; err_pid: put_pid(ctx->pid); @@ -632,10 +634,11 @@ int i915_gem_context_open(struct drm_i915_private *i915, int err; idr_init(&file_priv->context_idr); + mutex_init(&file_priv->context_lock); mutex_lock(&i915->drm.struct_mutex); - ctx = i915_gem_create_context(i915); + mutex_unlock(&i915->drm.struct_mutex); if (IS_ERR(ctx)) { err = PTR_ERR(ctx); goto err; @@ -648,14 +651,14 @@ int i915_gem_context_open(struct drm_i915_private *i915, GEM_BUG_ON(ctx->user_handle != DEFAULT_CONTEXT_HANDLE); GEM_BUG_ON(i915_gem_context_is_kernel(ctx)); - mutex_unlock(&i915->drm.struct_mutex); - return 0; err_ctx: + mutex_lock(&i915->drm.struct_mutex); context_close(ctx); -err: mutex_unlock(&i915->drm.struct_mutex); +err: + mutex_destroy(&file_priv->context_lock); idr_destroy(&file_priv->context_idr); return PTR_ERR(ctx); } @@ -668,6 +671,7 @@ void i915_gem_context_close(struct drm_file *file) idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); idr_destroy(&file_priv->context_idr); + mutex_destroy(&file_priv->context_lock); } static struct i915_request * @@ -850,25 +854,22 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, return ret; ctx = i915_gem_create_context(i915); - if (IS_ERR(ctx)) { - ret = PTR_ERR(ctx); - goto err_unlock; - } + mutex_unlock(&dev->struct_mutex); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ret = gem_context_register(ctx, file_priv); if (ret) goto err_ctx; - mutex_unlock(&dev->struct_mutex); - args->ctx_id = ctx->user_handle; DRM_DEBUG("HW context %d created\n", args->ctx_id); return 0; err_ctx: + mutex_lock(&dev->struct_mutex); context_close(ctx); -err_unlock: mutex_unlock(&dev->struct_mutex); return ret; } @@ -879,7 +880,6 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_context_destroy *args = data; struct drm_i915_file_private *file_priv = file->driver_priv; struct i915_gem_context *ctx; - int ret; if (args->pad != 0) return -EINVAL; @@ -887,21 +887,16 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, if (args->ctx_id == DEFAULT_CONTEXT_HANDLE) return -ENOENT; - ctx = i915_gem_context_lookup(file_priv, args->ctx_id); + mutex_lock(&file_priv->context_lock); + ctx = idr_remove(&file_priv->context_idr, args->ctx_id); + mutex_lock(&file_priv->context_lock); if (!ctx) return -ENOENT; - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - goto out; - - idr_remove(&file_priv->context_idr, ctx->user_handle); + mutex_lock(&dev->struct_mutex); context_close(ctx); - mutex_unlock(&dev->struct_mutex); -out: - i915_gem_context_put(ctx); return 0; } -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx