[Intel-gfx] [PATCH] drm/i915/gem: Safely acquire the ctx->vm when copying
Niranjan Vishwanathapura
niranjana.vishwanathapura at intel.com
Thu Nov 7 16:09:31 UTC 2019
On Wed, Nov 06, 2019 at 09:13:12AM +0000, Chris Wilson wrote:
>As we read the ctx->vm unlocked before cloning/exporting, we should
>validate our reference is correct before returning it. We already do for
>clone_vm() but were not so strict around get_ppgtt().
>
>Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
>---
> drivers/gpu/drm/i915/gem/i915_gem_context.c | 80 +++++++++++----------
> 1 file changed, 43 insertions(+), 37 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>index de6e55af82cf..a06cc8e63281 100644
>--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
>+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>@@ -995,6 +995,38 @@ static int context_barrier_task(struct i915_gem_context *ctx,
> return err;
> }
>
>+static struct i915_address_space *
>+context_get_vm_rcu(struct i915_gem_context *ctx)
>+{
>+ do {
>+ struct i915_address_space *vm;
>+
>+ vm = rcu_dereference(ctx->vm);
>+ if (!kref_get_unless_zero(&vm->ref))
>+ continue;
But should we check for NULL vm?
I know the callers are ensuring ctx->vm will not be NULL, but just wondering.
>+
>+ /*
>+ * This ppgtt may have be reallocated between
>+ * the read and the kref, and reassigned to a third
>+ * context. In order to avoid inadvertent sharing
>+ * of this ppgtt with that third context (and not
>+ * src), we have to confirm that we have the same
>+ * ppgtt after passing through the strong memory
>+ * barrier implied by a successful
>+ * kref_get_unless_zero().
>+ *
>+ * Once we have acquired the current ppgtt of src,
>+ * we no longer care if it is released from src, as
>+ * it cannot be reallocated elsewhere.
>+ */
Comment should be made generic? It is too specific to cloning case.
Other than that, patch looks good to me.
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura at intel.com>
>+
>+ if (vm == rcu_access_pointer(ctx->vm))
>+ return rcu_pointer_handoff(vm);
>+
>+ i915_vm_put(vm);
>+ } while (1);
>+}
>+
> static int get_ppgtt(struct drm_i915_file_private *file_priv,
> struct i915_gem_context *ctx,
> struct drm_i915_gem_context_param *args)
>@@ -1006,7 +1038,7 @@ static int get_ppgtt(struct drm_i915_file_private *file_priv,
> return -ENODEV;
>
> rcu_read_lock();
>- vm = i915_vm_get(ctx->vm);
>+ vm = context_get_vm_rcu(ctx);
> rcu_read_unlock();
>
> ret = mutex_lock_interruptible(&file_priv->vm_idr_lock);
>@@ -2035,47 +2067,21 @@ static int clone_vm(struct i915_gem_context *dst,
> struct i915_address_space *vm;
> int err = 0;
>
>- rcu_read_lock();
>- do {
>- vm = rcu_dereference(src->vm);
>- if (!vm)
>- break;
>-
>- if (!kref_get_unless_zero(&vm->ref))
>- continue;
>-
>- /*
>- * This ppgtt may have be reallocated between
>- * the read and the kref, and reassigned to a third
>- * context. In order to avoid inadvertent sharing
>- * of this ppgtt with that third context (and not
>- * src), we have to confirm that we have the same
>- * ppgtt after passing through the strong memory
>- * barrier implied by a successful
>- * kref_get_unless_zero().
>- *
>- * Once we have acquired the current ppgtt of src,
>- * we no longer care if it is released from src, as
>- * it cannot be reallocated elsewhere.
>- */
>-
>- if (vm == rcu_access_pointer(src->vm))
>- break;
>+ if (!rcu_access_pointer(src->vm))
>+ return 0;
>
>- i915_vm_put(vm);
>- } while (1);
>+ rcu_read_lock();
>+ vm = context_get_vm_rcu(src);
> rcu_read_unlock();
>
>- if (vm) {
>- if (!mutex_lock_interruptible(&dst->mutex)) {
>- __assign_ppgtt(dst, vm);
>- mutex_unlock(&dst->mutex);
>- } else {
>- err = -EINTR;
>- }
>- i915_vm_put(vm);
>+ if (!mutex_lock_interruptible(&dst->mutex)) {
>+ __assign_ppgtt(dst, vm);
>+ mutex_unlock(&dst->mutex);
>+ } else {
>+ err = -EINTR;
> }
>
>+ i915_vm_put(vm);
> return err;
> }
>
>--
>2.24.0
>
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx at lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list