Skip to content

Commit 7dc4071

Browse files
committed
drm/i915: Introduce a mutex for file_priv->context_idr
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.) v2: s/context_lock/context_idr_lock/ Signed-off-by: Chris Wilson <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Reviewed-by: Tvrtko Ursulin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 3aa9945 commit 7dc4071

File tree

2 files changed

+23
-26
lines changed

2 files changed

+23
-26
lines changed

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,9 @@ struct drm_i915_file_private {
216216
*/
217217
#define DRM_I915_THROTTLE_JIFFIES msecs_to_jiffies(20)
218218
} mm;
219+
219220
struct idr context_idr;
221+
struct mutex context_idr_lock; /* guards context_idr */
220222

221223
unsigned int bsd_engine;
222224

drivers/gpu/drm/i915/i915_gem_context.c

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -579,9 +579,7 @@ void i915_gem_contexts_fini(struct drm_i915_private *i915)
579579

580580
static int context_idr_cleanup(int id, void *p, void *data)
581581
{
582-
struct i915_gem_context *ctx = p;
583-
584-
context_close(ctx);
582+
context_close(p);
585583
return 0;
586584
}
587585

@@ -603,13 +601,15 @@ static int gem_context_register(struct i915_gem_context *ctx,
603601
}
604602

605603
/* And finally expose ourselves to userspace via the idr */
604+
mutex_lock(&fpriv->context_idr_lock);
606605
ret = idr_alloc(&fpriv->context_idr, ctx,
607606
DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
607+
if (ret >= 0)
608+
ctx->user_handle = ret;
609+
mutex_unlock(&fpriv->context_idr_lock);
608610
if (ret < 0)
609611
goto err_name;
610612

611-
ctx->user_handle = ret;
612-
613613
return 0;
614614

615615
err_name:
@@ -627,10 +627,11 @@ int i915_gem_context_open(struct drm_i915_private *i915,
627627
int err;
628628

629629
idr_init(&file_priv->context_idr);
630+
mutex_init(&file_priv->context_idr_lock);
630631

631632
mutex_lock(&i915->drm.struct_mutex);
632-
633633
ctx = i915_gem_create_context(i915);
634+
mutex_unlock(&i915->drm.struct_mutex);
634635
if (IS_ERR(ctx)) {
635636
err = PTR_ERR(ctx);
636637
goto err;
@@ -643,14 +644,14 @@ int i915_gem_context_open(struct drm_i915_private *i915,
643644
GEM_BUG_ON(ctx->user_handle != DEFAULT_CONTEXT_HANDLE);
644645
GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
645646

646-
mutex_unlock(&i915->drm.struct_mutex);
647-
648647
return 0;
649648

650649
err_ctx:
650+
mutex_lock(&i915->drm.struct_mutex);
651651
context_close(ctx);
652-
err:
653652
mutex_unlock(&i915->drm.struct_mutex);
653+
err:
654+
mutex_destroy(&file_priv->context_idr_lock);
654655
idr_destroy(&file_priv->context_idr);
655656
return PTR_ERR(ctx);
656657
}
@@ -663,6 +664,7 @@ void i915_gem_context_close(struct drm_file *file)
663664

664665
idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
665666
idr_destroy(&file_priv->context_idr);
667+
mutex_destroy(&file_priv->context_idr_lock);
666668
}
667669

668670
static struct i915_request *
@@ -845,25 +847,22 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
845847
return ret;
846848

847849
ctx = i915_gem_create_context(i915);
848-
if (IS_ERR(ctx)) {
849-
ret = PTR_ERR(ctx);
850-
goto err_unlock;
851-
}
850+
mutex_unlock(&dev->struct_mutex);
851+
if (IS_ERR(ctx))
852+
return PTR_ERR(ctx);
852853

853854
ret = gem_context_register(ctx, file_priv);
854855
if (ret)
855856
goto err_ctx;
856857

857-
mutex_unlock(&dev->struct_mutex);
858-
859858
args->ctx_id = ctx->user_handle;
860859
DRM_DEBUG("HW context %d created\n", args->ctx_id);
861860

862861
return 0;
863862

864863
err_ctx:
864+
mutex_lock(&dev->struct_mutex);
865865
context_close(ctx);
866-
err_unlock:
867866
mutex_unlock(&dev->struct_mutex);
868867
return ret;
869868
}
@@ -874,29 +873,25 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
874873
struct drm_i915_gem_context_destroy *args = data;
875874
struct drm_i915_file_private *file_priv = file->driver_priv;
876875
struct i915_gem_context *ctx;
877-
int ret;
878876

879877
if (args->pad != 0)
880878
return -EINVAL;
881879

882880
if (args->ctx_id == DEFAULT_CONTEXT_HANDLE)
883881
return -ENOENT;
884882

885-
ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
883+
if (mutex_lock_interruptible(&file_priv->context_idr_lock))
884+
return -EINTR;
885+
886+
ctx = idr_remove(&file_priv->context_idr, args->ctx_id);
887+
mutex_unlock(&file_priv->context_idr_lock);
886888
if (!ctx)
887889
return -ENOENT;
888890

889-
ret = mutex_lock_interruptible(&dev->struct_mutex);
890-
if (ret)
891-
goto out;
892-
893-
idr_remove(&file_priv->context_idr, ctx->user_handle);
891+
mutex_lock(&dev->struct_mutex);
894892
context_close(ctx);
895-
896893
mutex_unlock(&dev->struct_mutex);
897894

898-
out:
899-
i915_gem_context_put(ctx);
900895
return 0;
901896
}
902897

0 commit comments

Comments
 (0)