[PATCH] drm/i915/gem: Prefer unlocked engine iteration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In most cases, we can walk the array of engines underneath the context
using plain RCU protection -- we've set a flag on the context, and just
need to propagate that flag to the current engines, if those engines
are replaced as we do so, the new engines will get the new flag.

However, in one case, we need to keep the existing serialisation with
replacing the engines (set_ringsize) and that also needs to be run from
a blocking context.

Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 42 ++++++++++++++++-----
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index cb6b6be48978..50ecc0b2b235 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -747,9 +747,31 @@ __create_context(struct drm_i915_private *i915)
 }
 
 static int
-context_apply_all(struct i915_gem_context *ctx,
-		  int (*fn)(struct intel_context *ce, void *data),
-		  void *data)
+context_apply_all_rcu(struct i915_gem_context *ctx,
+		      int (*fn)(struct intel_context *ce, void *data),
+		      void *data)
+{
+	struct i915_gem_engines *engines;
+	struct i915_gem_engines_iter it;
+	struct intel_context *ce;
+	int err = 0;
+
+	rcu_read_lock();
+	engines = rcu_dereference(ctx->engines);
+	for_each_gem_engine(ce, engines, it) {
+		err = fn(ce, data);
+		if (err)
+			break;
+	}
+	rcu_read_unlock();
+
+	return err;
+}
+
+static int
+context_apply_all_locked(struct i915_gem_context *ctx,
+			 int (*fn)(struct intel_context *ce, void *data),
+			 void *data)
 {
 	struct i915_gem_engines_iter it;
 	struct intel_context *ce;
@@ -780,7 +802,7 @@ __set_ppgtt(struct i915_gem_context *ctx, struct i915_address_space *vm)
 	GEM_BUG_ON(old && i915_vm_is_4lvl(vm) != i915_vm_is_4lvl(old));
 
 	rcu_assign_pointer(ctx->vm, i915_vm_open(vm));
-	context_apply_all(ctx, __apply_ppgtt, vm);
+	context_apply_all_rcu(ctx, __apply_ppgtt, vm);
 
 	return old;
 }
@@ -817,7 +839,7 @@ static void __assign_timeline(struct i915_gem_context *ctx,
 			      struct intel_timeline *timeline)
 {
 	__set_timeline(&ctx->timeline, timeline);
-	context_apply_all(ctx, __apply_timeline, timeline);
+	context_apply_all_rcu(ctx, __apply_timeline, timeline);
 }
 
 static struct i915_gem_context *
@@ -1324,9 +1346,9 @@ static int set_ringsize(struct i915_gem_context *ctx,
 	if (args->value > 128 * I915_GTT_PAGE_SIZE)
 		return -EINVAL;
 
-	return context_apply_all(ctx,
-				 __apply_ringsize,
-				 __intel_context_ring_size(args->value));
+	return context_apply_all_locked(ctx,
+					__apply_ringsize,
+					__intel_context_ring_size(args->value));
 }
 
 static int __get_ringsize(struct intel_context *ce, void *arg)
@@ -1350,7 +1372,7 @@ static int get_ringsize(struct i915_gem_context *ctx,
 	if (args->size)
 		return -EINVAL;
 
-	sz = context_apply_all(ctx, __get_ringsize, NULL);
+	sz = context_apply_all_rcu(ctx, __get_ringsize, NULL);
 	if (sz < 0)
 		return sz;
 
@@ -1962,7 +1984,7 @@ static int set_priority(struct i915_gem_context *ctx,
 		return -EPERM;
 
 	ctx->sched.priority = I915_USER_PRIORITY(priority);
-	context_apply_all(ctx, __apply_priority, ctx);
+	context_apply_all_rcu(ctx, __apply_priority, ctx);
 
 	return 0;
 }
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx



[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux