diff mbox series

[29/31] drm/i915/gem: Roll all of context creation together

Message ID 20210609174418.249585-30-jason@jlekstrand.net (mailing list archive)
State New, archived
Headers show
Series drm/i915/gem: ioctl clean-ups (v6) | expand

Commit Message

Jason Ekstrand June 9, 2021, 5:44 p.m. UTC
Now that we have the whole engine set and VM at context creation time,
we can just assign those fields instead of creating first and handling
the VM and engines later.  This lets us avoid creating useless VMs and
engine sets and lets us get rid of the complex VM setting code.

Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 176 ++++++------------
 .../gpu/drm/i915/gem/selftests/mock_context.c |  33 ++--
 2 files changed, 73 insertions(+), 136 deletions(-)

Comments

kernel test robot June 16, 2021, 8:11 p.m. UTC | #1
Hi Jason,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-intel/for-linux-next]
[also build test WARNING on drm-tip/drm-tip drm-exynos/exynos-drm-next next-20210616]
[cannot apply to tegra-drm/drm/tegra/for-next drm/drm-next v5.13-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jason-Ekstrand/drm-i915-gem-ioctl-clean-ups-v6/20210616-151016
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: i386-randconfig-s001-20210615 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-341-g8af24329-dirty
        # https://github.com/0day-ci/linux/commit/18d43c75e6489f1e8485d8f4e809d83bbc179326
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jason-Ekstrand/drm-i915-gem-ioctl-clean-ups-v6/20210616-151016
        git checkout 18d43c75e6489f1e8485d8f4e809d83bbc179326
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/i915/gem/i915_gem_context.c:1412:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct i915_address_space *vm @@     got struct i915_address_space [noderef] __rcu *vm @@
   drivers/gpu/drm/i915/gem/i915_gem_context.c:1412:34: sparse:     expected struct i915_address_space *vm
   drivers/gpu/drm/i915/gem/i915_gem_context.c:1412:34: sparse:     got struct i915_address_space [noderef] __rcu *vm
   drivers/gpu/drm/i915/gem/i915_gem_context.c: note: in included file:
>> drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct i915_address_space [noderef] __rcu *vm @@     got struct i915_address_space * @@
   drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25: sparse:     expected struct i915_address_space [noderef] __rcu *vm
   drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25: sparse:     got struct i915_address_space *
>> drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct i915_address_space *vm @@     got struct i915_address_space [noderef] __rcu *vm @@
   drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34: sparse:     expected struct i915_address_space *vm
   drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34: sparse:     got struct i915_address_space [noderef] __rcu *vm

vim +1412 drivers/gpu/drm/i915/gem/i915_gem_context.c

  1324	
  1325	static struct i915_gem_context *
  1326	i915_gem_create_context(struct drm_i915_private *i915,
  1327				const struct i915_gem_proto_context *pc)
  1328	{
  1329		struct i915_gem_context *ctx;
  1330		struct i915_address_space *vm = NULL;
  1331		struct i915_gem_engines *e;
  1332		int err;
  1333		int i;
  1334	
  1335		ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
  1336		if (!ctx)
  1337			return ERR_PTR(-ENOMEM);
  1338	
  1339		kref_init(&ctx->ref);
  1340		ctx->i915 = i915;
  1341		ctx->sched = pc->sched;
  1342		mutex_init(&ctx->mutex);
  1343		INIT_LIST_HEAD(&ctx->link);
  1344	
  1345		spin_lock_init(&ctx->stale.lock);
  1346		INIT_LIST_HEAD(&ctx->stale.engines);
  1347	
  1348		if (pc->vm) {
  1349			vm = i915_vm_get(pc->vm);
  1350		} else if (HAS_FULL_PPGTT(i915)) {
  1351			struct i915_ppgtt *ppgtt;
  1352	
  1353			ppgtt = i915_ppgtt_create(&i915->gt);
  1354			if (IS_ERR(ppgtt)) {
  1355				drm_dbg(&i915->drm, "PPGTT setup failed (%ld)\n",
  1356					PTR_ERR(ppgtt));
  1357				err = PTR_ERR(ppgtt);
  1358				goto err_ctx;
  1359			}
  1360			vm = &ppgtt->vm;
  1361		}
  1362		if (vm) {
  1363			RCU_INIT_POINTER(ctx->vm, i915_vm_open(vm));
  1364	
  1365			/* i915_vm_open() takes a reference */
  1366			i915_vm_put(vm);
  1367		}
  1368	
  1369		mutex_init(&ctx->engines_mutex);
  1370		if (pc->num_user_engines >= 0) {
  1371			i915_gem_context_set_user_engines(ctx);
  1372			e = user_engines(ctx, pc->num_user_engines, pc->user_engines);
  1373		} else {
  1374			i915_gem_context_clear_user_engines(ctx);
  1375			e = default_engines(ctx, pc->legacy_rcs_sseu);
  1376		}
  1377		if (IS_ERR(e)) {
  1378			err = PTR_ERR(e);
  1379			goto err_vm;
  1380		}
  1381		RCU_INIT_POINTER(ctx->engines, e);
  1382	
  1383		INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
  1384		mutex_init(&ctx->lut_mutex);
  1385	
  1386		/* NB: Mark all slices as needing a remap so that when the context first
  1387		 * loads it will restore whatever remap state already exists. If there
  1388		 * is no remap info, it will be a NOP. */
  1389		ctx->remap_slice = ALL_L3_SLICES(i915);
  1390	
  1391		ctx->user_flags = pc->user_flags;
  1392	
  1393		for (i = 0; i < ARRAY_SIZE(ctx->hang_timestamp); i++)
  1394			ctx->hang_timestamp[i] = jiffies - CONTEXT_FAST_HANG_JIFFIES;
  1395	
  1396		if (pc->single_timeline) {
  1397			err = drm_syncobj_create(&ctx->syncobj,
  1398						 DRM_SYNCOBJ_CREATE_SIGNALED,
  1399						 NULL);
  1400			if (err)
  1401				goto err_engines;
  1402		}
  1403	
  1404		trace_i915_context_create(ctx);
  1405	
  1406		return ctx;
  1407	
  1408	err_engines:
  1409		free_engines(e);
  1410	err_vm:
  1411		if (ctx->vm)
> 1412			i915_vm_close(ctx->vm);
  1413	err_ctx:
  1414		kfree(ctx);
  1415		return ERR_PTR(err);
  1416	}
  1417	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 5f5375b15c530..c67e305f5bc74 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -1279,56 +1279,6 @@  static int __context_set_persistence(struct i915_gem_context *ctx, bool state)
 	return 0;
 }
 
-static struct i915_gem_context *
-__create_context(struct drm_i915_private *i915,
-		 const struct i915_gem_proto_context *pc)
-{
-	struct i915_gem_context *ctx;
-	struct i915_gem_engines *e;
-	int err;
-	int i;
-
-	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
-	if (!ctx)
-		return ERR_PTR(-ENOMEM);
-
-	kref_init(&ctx->ref);
-	ctx->i915 = i915;
-	ctx->sched = pc->sched;
-	mutex_init(&ctx->mutex);
-	INIT_LIST_HEAD(&ctx->link);
-
-	spin_lock_init(&ctx->stale.lock);
-	INIT_LIST_HEAD(&ctx->stale.engines);
-
-	mutex_init(&ctx->engines_mutex);
-	e = default_engines(ctx, pc->legacy_rcs_sseu);
-	if (IS_ERR(e)) {
-		err = PTR_ERR(e);
-		goto err_free;
-	}
-	RCU_INIT_POINTER(ctx->engines, e);
-
-	INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
-	mutex_init(&ctx->lut_mutex);
-
-	/* NB: Mark all slices as needing a remap so that when the context first
-	 * loads it will restore whatever remap state already exists. If there
-	 * is no remap info, it will be a NOP. */
-	ctx->remap_slice = ALL_L3_SLICES(i915);
-
-	ctx->user_flags = pc->user_flags;
-
-	for (i = 0; i < ARRAY_SIZE(ctx->hang_timestamp); i++)
-		ctx->hang_timestamp[i] = jiffies - CONTEXT_FAST_HANG_JIFFIES;
-
-	return ctx;
-
-err_free:
-	kfree(ctx);
-	return ERR_PTR(err);
-}
-
 static inline struct i915_gem_engines *
 __context_engines_await(const struct i915_gem_context *ctx,
 			bool *user_engines)
@@ -1372,54 +1322,31 @@  context_apply_all(struct i915_gem_context *ctx,
 	i915_sw_fence_complete(&e->fence);
 }
 
-static void __apply_ppgtt(struct intel_context *ce, void *vm)
-{
-	i915_vm_put(ce->vm);
-	ce->vm = i915_vm_get(vm);
-}
-
-static struct i915_address_space *
-__set_ppgtt(struct i915_gem_context *ctx, struct i915_address_space *vm)
-{
-	struct i915_address_space *old;
-
-	old = rcu_replace_pointer(ctx->vm,
-				  i915_vm_open(vm),
-				  lockdep_is_held(&ctx->mutex));
-	GEM_BUG_ON(old && i915_vm_is_4lvl(vm) != i915_vm_is_4lvl(old));
-
-	context_apply_all(ctx, __apply_ppgtt, vm);
-
-	return old;
-}
-
-static void __assign_ppgtt(struct i915_gem_context *ctx,
-			   struct i915_address_space *vm)
-{
-	if (vm == rcu_access_pointer(ctx->vm))
-		return;
-
-	vm = __set_ppgtt(ctx, vm);
-	if (vm)
-		i915_vm_close(vm);
-}
-
 static struct i915_gem_context *
 i915_gem_create_context(struct drm_i915_private *i915,
 			const struct i915_gem_proto_context *pc)
 {
 	struct i915_gem_context *ctx;
-	int ret;
+	struct i915_address_space *vm = NULL;
+	struct i915_gem_engines *e;
+	int err;
+	int i;
 
-	ctx = __create_context(i915, pc);
-	if (IS_ERR(ctx))
-		return ctx;
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return ERR_PTR(-ENOMEM);
+
+	kref_init(&ctx->ref);
+	ctx->i915 = i915;
+	ctx->sched = pc->sched;
+	mutex_init(&ctx->mutex);
+	INIT_LIST_HEAD(&ctx->link);
+
+	spin_lock_init(&ctx->stale.lock);
+	INIT_LIST_HEAD(&ctx->stale.engines);
 
 	if (pc->vm) {
-		/* __assign_ppgtt() requires this mutex to be held */
-		mutex_lock(&ctx->mutex);
-		__assign_ppgtt(ctx, pc->vm);
-		mutex_unlock(&ctx->mutex);
+		vm = i915_vm_get(pc->vm);
 	} else if (HAS_FULL_PPGTT(i915)) {
 		struct i915_ppgtt *ppgtt;
 
@@ -1427,50 +1354,65 @@  i915_gem_create_context(struct drm_i915_private *i915,
 		if (IS_ERR(ppgtt)) {
 			drm_dbg(&i915->drm, "PPGTT setup failed (%ld)\n",
 				PTR_ERR(ppgtt));
-			context_close(ctx);
-			return ERR_CAST(ppgtt);
+			err = PTR_ERR(ppgtt);
+			goto err_ctx;
 		}
+		vm = &ppgtt->vm;
+	}
+	if (vm) {
+		RCU_INIT_POINTER(ctx->vm, i915_vm_open(vm));
 
-		/* __assign_ppgtt() requires this mutex to be held */
-		mutex_lock(&ctx->mutex);
-		__assign_ppgtt(ctx, &ppgtt->vm);
-		mutex_unlock(&ctx->mutex);
-
-		/* __assign_ppgtt() takes another reference for us */
-		i915_vm_put(&ppgtt->vm);
+		/* i915_vm_open() takes a reference */
+		i915_vm_put(vm);
 	}
 
+	mutex_init(&ctx->engines_mutex);
 	if (pc->num_user_engines >= 0) {
-		struct i915_gem_engines *engines;
+		i915_gem_context_set_user_engines(ctx);
+		e = user_engines(ctx, pc->num_user_engines, pc->user_engines);
+	} else {
+		i915_gem_context_clear_user_engines(ctx);
+		e = default_engines(ctx, pc->legacy_rcs_sseu);
+	}
+	if (IS_ERR(e)) {
+		err = PTR_ERR(e);
+		goto err_vm;
+	}
+	RCU_INIT_POINTER(ctx->engines, e);
 
-		engines = user_engines(ctx, pc->num_user_engines,
-				       pc->user_engines);
-		if (IS_ERR(engines)) {
-			context_close(ctx);
-			return ERR_CAST(engines);
-		}
+	INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
+	mutex_init(&ctx->lut_mutex);
 
-		mutex_lock(&ctx->engines_mutex);
-		i915_gem_context_set_user_engines(ctx);
-		engines = rcu_replace_pointer(ctx->engines, engines, 1);
-		mutex_unlock(&ctx->engines_mutex);
+	/* NB: Mark all slices as needing a remap so that when the context first
+	 * loads it will restore whatever remap state already exists. If there
+	 * is no remap info, it will be a NOP. */
+	ctx->remap_slice = ALL_L3_SLICES(i915);
 
-		free_engines(engines);
-	}
+	ctx->user_flags = pc->user_flags;
+
+	for (i = 0; i < ARRAY_SIZE(ctx->hang_timestamp); i++)
+		ctx->hang_timestamp[i] = jiffies - CONTEXT_FAST_HANG_JIFFIES;
 
 	if (pc->single_timeline) {
-		ret = drm_syncobj_create(&ctx->syncobj,
+		err = drm_syncobj_create(&ctx->syncobj,
 					 DRM_SYNCOBJ_CREATE_SIGNALED,
 					 NULL);
-		if (ret) {
-			context_close(ctx);
-			return ERR_PTR(ret);
-		}
+		if (err)
+			goto err_engines;
 	}
 
 	trace_i915_context_create(ctx);
 
 	return ctx;
+
+err_engines:
+	free_engines(e);
+err_vm:
+	if (ctx->vm)
+		i915_vm_close(ctx->vm);
+err_ctx:
+	kfree(ctx);
+	return ERR_PTR(err);
 }
 
 static void init_contexts(struct i915_gem_contexts *gc)
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_context.c b/drivers/gpu/drm/i915/gem/selftests/mock_context.c
index 500ef27ba4771..fee070df1c97b 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_context.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_context.c
@@ -31,15 +31,6 @@  mock_context(struct drm_i915_private *i915,
 
 	i915_gem_context_set_persistence(ctx);
 
-	mutex_init(&ctx->engines_mutex);
-	e = default_engines(ctx, null_sseu);
-	if (IS_ERR(e))
-		goto err_free;
-	RCU_INIT_POINTER(ctx->engines, e);
-
-	INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
-	mutex_init(&ctx->lut_mutex);
-
 	if (name) {
 		struct i915_ppgtt *ppgtt;
 
@@ -47,25 +38,29 @@  mock_context(struct drm_i915_private *i915,
 
 		ppgtt = mock_ppgtt(i915, name);
 		if (!ppgtt)
-			goto err_put;
-
-		mutex_lock(&ctx->mutex);
-		__set_ppgtt(ctx, &ppgtt->vm);
-		mutex_unlock(&ctx->mutex);
+			goto err_free;
 
+		ctx->vm = i915_vm_open(&ppgtt->vm);
 		i915_vm_put(&ppgtt->vm);
 	}
 
+	mutex_init(&ctx->engines_mutex);
+	e = default_engines(ctx, null_sseu);
+	if (IS_ERR(e))
+		goto err_vm;
+	RCU_INIT_POINTER(ctx->engines, e);
+
+	INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
+	mutex_init(&ctx->lut_mutex);
+
 	return ctx;
 
+err_vm:
+	if (ctx->vm)
+		i915_vm_close(ctx->vm);
 err_free:
 	kfree(ctx);
 	return NULL;
-
-err_put:
-	i915_gem_context_set_closed(ctx);
-	i915_gem_context_put(ctx);
-	return NULL;
 }
 
 void mock_context_close(struct i915_gem_context *ctx)