All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests
@ 2019-07-25  7:43 Chris Wilson
  2019-07-25  8:26 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev3) Patchwork
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Chris Wilson @ 2019-07-25  7:43 UTC (permalink / raw)
  To: intel-gfx

Under some circumstances (see intel_context_prepare_remote_request), we
may use a request along a kernel context to modify the logical state of
another. To keep the target context in place while the request executes,
we take an active reference on it using the kernel timeline. This is the
same timeline as we use for the idle-barrier, and so we end up reusing
the same active node. Except that the idle barrier is special and cannot
be reused in this manner! Give the idle-barrier a reserved timeline
index (0) so that it will always be unique (give or take we may issue
multiple idle barriers across multiple engines).

Reported-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: ce476c80b8bf ("drm/i915: Keep contexts pinned until after the next kernel context switch")
Fixes: a9877da2d629 ("drm/i915/oa: Reconfigure contexts on the fly")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
Now with a successful testcase!
---
 drivers/gpu/drm/i915/gt/intel_context.c       |  42 ++-
 drivers/gpu/drm/i915/gt/intel_context.h       |  13 +-
 drivers/gpu/drm/i915/gt/selftest_context.c    | 321 ++++++++++++++++++
 drivers/gpu/drm/i915/i915_active.c            |  59 +++-
 .../drm/i915/selftests/i915_live_selftests.h  |   3 +-
 5 files changed, 400 insertions(+), 38 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/selftest_context.c

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 9292b6ca5e9c..bc20161bab9f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -162,18 +162,8 @@ static int __intel_context_active(struct i915_active *active)
 	if (err)
 		goto err_ring;
 
-	/* Preallocate tracking nodes */
-	if (!i915_gem_context_is_kernel(ce->gem_context)) {
-		err = i915_active_acquire_preallocate_barrier(&ce->active,
-							      ce->engine);
-		if (err)
-			goto err_state;
-	}
-
 	return 0;
 
-err_state:
-	__context_unpin_state(ce->state);
 err_ring:
 	intel_ring_unpin(ce->ring);
 err_put:
@@ -181,6 +171,34 @@ static int __intel_context_active(struct i915_active *active)
 	return err;
 }
 
+int intel_context_active_acquire(struct intel_context *ce)
+{
+	int err;
+
+	err = i915_active_acquire(&ce->active);
+	if (err)
+		return err;
+
+	/* Preallocate tracking nodes */
+	if (ce->state && !i915_gem_context_is_kernel(ce->gem_context)) {
+		err = i915_active_acquire_preallocate_barrier(&ce->active,
+							      ce->engine);
+		if (err) {
+			i915_active_release(&ce->active);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+void intel_context_active_release(struct intel_context *ce)
+{
+	/* Nodes preallocated in intel_context_active() */
+	i915_active_acquire_barrier(&ce->active);
+	i915_active_release(&ce->active);
+}
+
 void
 intel_context_init(struct intel_context *ce,
 		   struct i915_gem_context *ctx,
@@ -284,3 +302,7 @@ struct i915_request *intel_context_create_request(struct intel_context *ce)
 
 	return rq;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftest_context.c"
+#endif
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index 23c7e4c0ce7c..07f9924de48f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -104,17 +104,8 @@ static inline void intel_context_exit(struct intel_context *ce)
 		ce->ops->exit(ce);
 }
 
-static inline int intel_context_active_acquire(struct intel_context *ce)
-{
-	return i915_active_acquire(&ce->active);
-}
-
-static inline void intel_context_active_release(struct intel_context *ce)
-{
-	/* Nodes preallocated in intel_context_active() */
-	i915_active_acquire_barrier(&ce->active);
-	i915_active_release(&ce->active);
-}
+int intel_context_active_acquire(struct intel_context *ce);
+void intel_context_active_release(struct intel_context *ce);
 
 static inline struct intel_context *intel_context_get(struct intel_context *ce)
 {
diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c
new file mode 100644
index 000000000000..d92cebadf97d
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/selftest_context.c
@@ -0,0 +1,321 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "i915_selftest.h"
+#include "intel_gt.h"
+
+#include "gem/selftests/mock_context.h"
+#include "selftests/igt_flush_test.h"
+#include "selftests/mock_drm.h"
+
+static int request_sync(struct i915_request *rq)
+{
+	long timeout;
+	int err = 0;
+
+	i915_request_get(rq);
+
+	i915_request_add(rq);
+	timeout = i915_request_wait(rq, 0, HZ / 10);
+	if (timeout < 0)
+		err = timeout;
+	else
+		i915_request_retire_upto(rq);
+
+	i915_request_put(rq);
+
+	return err;
+}
+
+static int context_sync(struct intel_context *ce)
+{
+	struct intel_timeline *tl = ce->ring->timeline;
+	int err = 0;
+
+	do {
+		struct i915_request *rq;
+		long timeout;
+
+		rcu_read_lock();
+		rq = rcu_dereference(tl->last_request.request);
+		if (rq)
+			rq = i915_request_get_rcu(rq);
+		rcu_read_unlock();
+		if (!rq)
+			return 0;
+
+		timeout = i915_request_wait(rq, 0, HZ / 10);
+		if (timeout < 0)
+			err = timeout;
+		else
+			i915_request_retire_upto(rq);
+
+		i915_request_put(rq);
+	} while (!err);
+
+	return err;
+}
+
+static int __live_active_context(struct intel_engine_cs *engine,
+				 struct i915_gem_context *fixme)
+{
+	struct intel_context *ce;
+	int pass;
+	int err;
+
+	/*
+	 * We keep active contexts alive until after a subsequent context
+	 * switch as the final write from the context-save will be after
+	 * we retire the final request. We track when we unpin the context,
+	 * under the presumption that the final pin is from the last request,
+	 * and instead of immediately unpinning the context, we add a task
+	 * to unpin the context from the next idle-barrier.
+	 *
+	 * This test makes sure that the context is kept alive until a
+	 * subsequent idle-barrier (emitted when the engine wakeref hits 0
+	 * with no more outstanding requests).
+	 */
+
+	if (intel_engine_pm_is_awake(engine)) {
+		pr_err("%s is awake before starting %s!\n",
+		       engine->name, __func__);
+		return -EINVAL;
+	}
+
+	ce = intel_context_create(fixme, engine);
+	if (!ce)
+		return -ENOMEM;
+
+	for (pass = 0; pass <= 2; pass++) {
+		struct i915_request *rq;
+
+		rq = intel_context_create_request(ce);
+		if (IS_ERR(rq)) {
+			err = PTR_ERR(rq);
+			goto err;
+		}
+
+		err = request_sync(rq);
+		if (err)
+			goto err;
+
+		/* Context will be kept active until after an idle-barrier. */
+		if (i915_active_is_idle(&ce->active)) {
+			pr_err("context is not active; expected idle-barrier (pass %d)\n", pass);
+			err = -EINVAL;
+			goto err;
+		}
+
+		if (!intel_engine_pm_is_awake(engine)) {
+			pr_err("%s is asleep before idle-barrier %s!\n",
+			       engine->name, __func__);
+			err = -EINVAL;
+			goto err;
+		}
+	}
+
+	/* Now make sure our idle-barriers are flushed */
+	err = context_sync(engine->kernel_context);
+	if (err)
+		goto err;
+
+	if (!i915_active_is_idle(&ce->active)) {
+		pr_err("context is still active!");
+		err = -EINVAL;
+	}
+
+	if (intel_engine_pm_is_awake(engine)) {
+		struct drm_printer p = drm_debug_printer(__func__);
+
+		intel_engine_dump(engine, &p,
+				  "%s is still awake after idle-barriers\n",
+				  engine->name);
+		GEM_TRACE_DUMP();
+
+		err = -EINVAL;
+		goto err;
+	}
+
+err:
+	intel_context_put(ce);
+	return err;
+}
+
+static int live_active_context(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct intel_engine_cs *engine;
+	struct i915_gem_context *fixme;
+	enum intel_engine_id id;
+	struct drm_file *file;
+	int err = 0;
+
+	file = mock_file(gt->i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	mutex_lock(&gt->i915->drm.struct_mutex);
+
+	fixme = live_context(gt->i915, file);
+	if (!fixme) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	for_each_engine(engine, gt->i915, id) {
+		err = __live_active_context(engine, fixme);
+		if (err)
+			break;
+
+		err = igt_flush_test(gt->i915, I915_WAIT_LOCKED);
+		if (err)
+			break;
+	}
+
+unlock:
+	mutex_unlock(&gt->i915->drm.struct_mutex);
+	mock_file_free(gt->i915, file);
+	return err;
+}
+
+static int __live_remote_context(struct intel_engine_cs *engine,
+				 struct i915_gem_context *fixme)
+{
+	struct intel_context *local, *remote;
+	struct i915_request *rq;
+	int pass;
+	int err;
+
+	/*
+	 * Check that our idle barriers do not interfere with normal
+	 * activity tracking. In particular, check that operating
+	 * on the context image remotely (intel_context_prepare_remote_request)
+	 * which inserts foriegn fences into intel_context.active are not
+	 * clobbered.
+	 */
+
+	remote = intel_context_create(fixme, engine);
+	if (!remote)
+		return -ENOMEM;
+
+	local = intel_context_create(fixme, engine);
+	if (!local) {
+		err = -ENOMEM;
+		goto err_remote;
+	}
+
+	for (pass = 0; pass <= 2; pass++) {
+		err = intel_context_pin(remote);
+		if (err)
+			goto err_local;
+
+		rq = intel_context_create_request(local);
+		if (IS_ERR(rq)) {
+			err = PTR_ERR(rq);
+			goto err_unpin;
+		}
+
+		err = intel_context_prepare_remote_request(remote, rq);
+		if (err) {
+			i915_request_add(rq);
+			goto err_unpin;
+		}
+
+		err = request_sync(rq);
+		if (err)
+			goto err_unpin;
+
+		intel_context_unpin(remote);
+		err = intel_context_pin(remote);
+		if (err)
+			goto err_local;
+
+		rq = i915_request_create(engine->kernel_context);
+		if (IS_ERR(rq)) {
+			err = PTR_ERR(rq);
+			goto err_unpin;
+		}
+
+		err = intel_context_prepare_remote_request(remote, rq);
+		if (err) {
+			i915_request_add(rq);
+			goto err_unpin;
+		}
+
+		err = request_sync(rq);
+		if (err)
+			goto err_unpin;
+
+		intel_context_unpin(remote);
+
+		if (i915_active_is_idle(&remote->active)) {
+			pr_err("remote context is not active; expected idle-barrier (pass %d)\n", pass);
+			err = -EINVAL;
+			goto err_local;
+		}
+	}
+
+	goto err_local;
+
+err_unpin:
+	intel_context_unpin(remote);
+err_local:
+	intel_context_put(local);
+err_remote:
+	intel_context_put(remote);
+	return err;
+}
+
+static int live_remote_context(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct intel_engine_cs *engine;
+	struct i915_gem_context *fixme;
+	enum intel_engine_id id;
+	struct drm_file *file;
+	int err = 0;
+
+	file = mock_file(gt->i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	mutex_lock(&gt->i915->drm.struct_mutex);
+
+	fixme = live_context(gt->i915, file);
+	if (!fixme) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	for_each_engine(engine, gt->i915, id) {
+		err = __live_remote_context(engine, fixme);
+		if (err)
+			break;
+
+		err = igt_flush_test(gt->i915, I915_WAIT_LOCKED);
+		if (err)
+			break;
+	}
+
+unlock:
+	mutex_unlock(&gt->i915->drm.struct_mutex);
+	mock_file_free(gt->i915, file);
+	return err;
+}
+
+int intel_context_live_selftests(struct drm_i915_private *i915)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(live_active_context),
+		SUBTEST(live_remote_context),
+	};
+	struct intel_gt *gt = &i915->gt;
+
+	if (intel_gt_is_wedged(gt))
+		return 0;
+
+	return intel_gt_live_subtests(tests, gt);
+}
diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 13f304a29fc8..057b33eb7055 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -184,6 +184,7 @@ active_instance(struct i915_active *ref, u64 idx)
 	ref->cache = node;
 	mutex_unlock(&ref->mutex);
 
+	BUILD_BUG_ON(offsetof(typeof(*node), base));
 	return &node->base;
 }
 
@@ -212,6 +213,8 @@ int i915_active_ref(struct i915_active *ref,
 	struct i915_active_request *active;
 	int err;
 
+	GEM_BUG_ON(!timeline); /* reserved for idle-barrier */
+
 	/* Prevent reaping in case we malloc/wait while building the tree */
 	err = i915_active_acquire(ref);
 	if (err)
@@ -222,6 +225,7 @@ int i915_active_ref(struct i915_active *ref,
 		err = -ENOMEM;
 		goto out;
 	}
+	GEM_BUG_ON(IS_ERR(active->request));
 
 	if (!i915_active_request_isset(active))
 		atomic_inc(&ref->count);
@@ -342,6 +346,26 @@ void i915_active_fini(struct i915_active *ref)
 }
 #endif
 
+static struct active_node *idle_barrier(struct i915_active *ref)
+{
+	struct active_node *node;
+	struct rb_node *rb;
+
+	lockdep_assert_held(&ref->mutex);
+	rb = rb_first(&ref->tree);
+	if (!rb)
+		return NULL;
+
+	node = rb_entry(rb, typeof(*node), node);
+	if (node->timeline || i915_active_request_isset(&node->base))
+		return NULL;
+
+	GEM_BUG_ON(!list_empty(&node->base.link));
+	rb_erase(rb, &ref->tree);
+
+	return node;
+}
+
 int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
 					    struct intel_engine_cs *engine)
 {
@@ -352,22 +376,29 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
 
 	GEM_BUG_ON(!engine->mask);
 	for_each_engine_masked(engine, i915, engine->mask, tmp) {
-		struct intel_context *kctx = engine->kernel_context;
 		struct active_node *node;
 
-		node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
-		if (unlikely(!node)) {
-			err = -ENOMEM;
-			goto unwind;
+		node = idle_barrier(ref);
+		if (!node) {
+			node = kmem_cache_alloc(global.slab_cache,
+						GFP_KERNEL |
+						__GFP_RETRY_MAYFAIL |
+						__GFP_NOWARN);
+			if (unlikely(!node)) {
+				err = -ENOMEM;
+				goto unwind;
+			}
+
+			node->ref = ref;
+			node->timeline = 0;
+			node->base.retire = node_retire;
 		}
 
-		i915_active_request_init(&node->base,
-					 (void *)engine, node_retire);
-		node->timeline = kctx->ring->timeline->fence_context;
-		node->ref = ref;
+		intel_engine_pm_get(engine);
+
+		RCU_INIT_POINTER(node->base.request, (void *)engine);
 		atomic_inc(&ref->count);
 
-		intel_engine_pm_get(engine);
 		llist_add((struct llist_node *)&node->base.link,
 			  &ref->barriers);
 	}
@@ -402,6 +433,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 
 		node = container_of((struct list_head *)pos,
 				    typeof(*node), base.link);
+		GEM_BUG_ON(node->timeline);
 
 		engine = (void *)rcu_access_pointer(node->base.request);
 		RCU_INIT_POINTER(node->base.request, ERR_PTR(-EAGAIN));
@@ -410,12 +442,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 		p = &ref->tree.rb_node;
 		while (*p) {
 			parent = *p;
-			if (rb_entry(parent,
-				     struct active_node,
-				     node)->timeline < node->timeline)
-				p = &parent->rb_right;
-			else
-				p = &parent->rb_left;
+			p = &parent->rb_left;
 		}
 		rb_link_node(&node->node, parent, p);
 		rb_insert_color(&node->node, &ref->tree);
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 2b31a4ee0b4c..a841d3f9bedc 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -15,6 +15,7 @@ selftest(workarounds, intel_workarounds_live_selftests)
 selftest(timelines, intel_timeline_live_selftests)
 selftest(requests, i915_request_live_selftests)
 selftest(active, i915_active_live_selftests)
+selftest(gt_contexts, intel_context_live_selftests)
 selftest(objects, i915_gem_object_live_selftests)
 selftest(mman, i915_gem_mman_live_selftests)
 selftest(dmabuf, i915_gem_dmabuf_live_selftests)
@@ -24,7 +25,7 @@ selftest(gtt, i915_gem_gtt_live_selftests)
 selftest(gem, i915_gem_live_selftests)
 selftest(evict, i915_gem_evict_live_selftests)
 selftest(hugepages, i915_gem_huge_page_live_selftests)
-selftest(contexts, i915_gem_context_live_selftests)
+selftest(gem_contexts, i915_gem_context_live_selftests)
 selftest(blt, i915_gem_object_blt_live_selftests)
 selftest(client, i915_gem_client_blt_live_selftests)
 selftest(reset, intel_reset_live_selftests)
-- 
2.22.0

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev3)
  2019-07-25  7:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
@ 2019-07-25  8:26 ` Patchwork
  2019-07-25  9:12 ` ✗ Fi.CI.BAT: failure " Patchwork
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2019-07-25  8:26 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Unshare the idle-barrier from other kernel requests (rev3)
URL   : https://patchwork.freedesktop.org/series/64171/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
4db89a82be2b drm/i915: Unshare the idle-barrier from other kernel requests
-:114: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#114: 
new file mode 100644

-:119: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#119: FILE: drivers/gpu/drm/i915/gt/selftest_context.c:1:
+/*

-:120: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#120: FILE: drivers/gpu/drm/i915/gt/selftest_context.c:2:
+ * SPDX-License-Identifier: GPL-2.0

-:373: WARNING:LONG_LINE: line over 100 characters
#373: FILE: drivers/gpu/drm/i915/gt/selftest_context.c:255:
+			pr_err("remote context is not active; expected idle-barrier (pass %d)\n", pass);

total: 0 errors, 4 warnings, 0 checks, 521 lines checked

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* ✗ Fi.CI.BAT: failure for drm/i915: Unshare the idle-barrier from other kernel requests (rev3)
  2019-07-25  7:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
  2019-07-25  8:26 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev3) Patchwork
@ 2019-07-25  9:12 ` Patchwork
  2019-07-25  9:38 ` [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2019-07-25  9:12 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Unshare the idle-barrier from other kernel requests (rev3)
URL   : https://patchwork.freedesktop.org/series/64171/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_6547 -> Patchwork_13742
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_13742 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_13742, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_13742:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_busy@busy-all:
    - fi-bdw-5557u:       [PASS][1] -> [DMESG-WARN][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-bdw-5557u/igt@gem_busy@busy-all.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bdw-5557u/igt@gem_busy@busy-all.html
    - fi-bsw-kefka:       [PASS][3] -> [DMESG-WARN][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-bsw-kefka/igt@gem_busy@busy-all.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bsw-kefka/igt@gem_busy@busy-all.html
    - fi-kbl-guc:         [PASS][5] -> [DMESG-WARN][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-kbl-guc/igt@gem_busy@busy-all.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-guc/igt@gem_busy@busy-all.html
    - fi-hsw-4770r:       [PASS][7] -> [DMESG-WARN][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-hsw-4770r/igt@gem_busy@busy-all.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-hsw-4770r/igt@gem_busy@busy-all.html
    - fi-kbl-7500u:       [PASS][9] -> [DMESG-WARN][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-kbl-7500u/igt@gem_busy@busy-all.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-7500u/igt@gem_busy@busy-all.html
    - fi-icl-u2:          [PASS][11] -> [DMESG-WARN][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-icl-u2/igt@gem_busy@busy-all.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-icl-u2/igt@gem_busy@busy-all.html
    - fi-cfl-8700k:       [PASS][13] -> [DMESG-WARN][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-cfl-8700k/igt@gem_busy@busy-all.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cfl-8700k/igt@gem_busy@busy-all.html
    - fi-snb-2520m:       [PASS][15] -> [DMESG-WARN][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-snb-2520m/igt@gem_busy@busy-all.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-snb-2520m/igt@gem_busy@busy-all.html
    - fi-ivb-3770:        [PASS][17] -> [DMESG-WARN][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-ivb-3770/igt@gem_busy@busy-all.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-ivb-3770/igt@gem_busy@busy-all.html
    - fi-glk-dsi:         [PASS][19] -> [DMESG-WARN][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-glk-dsi/igt@gem_busy@busy-all.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-glk-dsi/igt@gem_busy@busy-all.html
    - fi-skl-guc:         [PASS][21] -> [DMESG-WARN][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-skl-guc/igt@gem_busy@busy-all.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-skl-guc/igt@gem_busy@busy-all.html
    - fi-cfl-guc:         [PASS][23] -> [DMESG-WARN][24]
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-cfl-guc/igt@gem_busy@busy-all.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cfl-guc/igt@gem_busy@busy-all.html
    - fi-bxt-j4205:       [PASS][25] -> [DMESG-WARN][26]
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-bxt-j4205/igt@gem_busy@busy-all.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bxt-j4205/igt@gem_busy@busy-all.html
    - fi-bdw-gvtdvm:      [PASS][27] -> [DMESG-WARN][28]
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-bdw-gvtdvm/igt@gem_busy@busy-all.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bdw-gvtdvm/igt@gem_busy@busy-all.html
    - fi-hsw-4770:        [PASS][29] -> [DMESG-WARN][30]
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-hsw-4770/igt@gem_busy@busy-all.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-hsw-4770/igt@gem_busy@busy-all.html
    - fi-bsw-n3050:       [PASS][31] -> [DMESG-WARN][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-bsw-n3050/igt@gem_busy@busy-all.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bsw-n3050/igt@gem_busy@busy-all.html
    - fi-ilk-650:         [PASS][33] -> [DMESG-WARN][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-ilk-650/igt@gem_busy@busy-all.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-ilk-650/igt@gem_busy@busy-all.html
    - fi-icl-u3:          [PASS][35] -> [DMESG-WARN][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-icl-u3/igt@gem_busy@busy-all.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-icl-u3/igt@gem_busy@busy-all.html
    - fi-cml-u2:          [PASS][37] -> [DMESG-WARN][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-cml-u2/igt@gem_busy@busy-all.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cml-u2/igt@gem_busy@busy-all.html
    - fi-skl-gvtdvm:      [PASS][39] -> [DMESG-WARN][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-skl-gvtdvm/igt@gem_busy@busy-all.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-skl-gvtdvm/igt@gem_busy@busy-all.html
    - fi-snb-2600:        [PASS][41] -> [DMESG-WARN][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-snb-2600/igt@gem_busy@busy-all.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-snb-2600/igt@gem_busy@busy-all.html
    - fi-skl-6260u:       [PASS][43] -> [DMESG-WARN][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-skl-6260u/igt@gem_busy@busy-all.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-skl-6260u/igt@gem_busy@busy-all.html
    - fi-bxt-dsi:         [PASS][45] -> [DMESG-WARN][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-bxt-dsi/igt@gem_busy@busy-all.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bxt-dsi/igt@gem_busy@busy-all.html
    - fi-skl-lmem:        [PASS][47] -> [DMESG-WARN][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-skl-lmem/igt@gem_busy@busy-all.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-skl-lmem/igt@gem_busy@busy-all.html
    - fi-kbl-8809g:       [PASS][49] -> [DMESG-WARN][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-kbl-8809g/igt@gem_busy@busy-all.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-8809g/igt@gem_busy@busy-all.html
    - fi-byt-n2820:       [PASS][51] -> [DMESG-WARN][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-byt-n2820/igt@gem_busy@busy-all.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-byt-n2820/igt@gem_busy@busy-all.html
    - fi-skl-6770hq:      NOTRUN -> [DMESG-WARN][53]
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-skl-6770hq/igt@gem_busy@busy-all.html
    - fi-kbl-r:           [PASS][54] -> [DMESG-WARN][55]
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-kbl-r/igt@gem_busy@busy-all.html
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-r/igt@gem_busy@busy-all.html
    - fi-icl-dsi:         NOTRUN -> [DMESG-WARN][56]
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-icl-dsi/igt@gem_busy@busy-all.html
    - fi-kbl-x1275:       [PASS][57] -> [DMESG-WARN][58]
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-kbl-x1275/igt@gem_busy@busy-all.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-x1275/igt@gem_busy@busy-all.html
    - fi-hsw-peppy:       [PASS][59] -> [DMESG-WARN][60]
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-hsw-peppy/igt@gem_busy@busy-all.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-hsw-peppy/igt@gem_busy@busy-all.html
    - fi-skl-6600u:       [PASS][61] -> [DMESG-WARN][62]
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-skl-6600u/igt@gem_busy@busy-all.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-skl-6600u/igt@gem_busy@busy-all.html
    - fi-apl-guc:         [PASS][63] -> [DMESG-WARN][64]
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-apl-guc/igt@gem_busy@busy-all.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-apl-guc/igt@gem_busy@busy-all.html
    - fi-kbl-7567u:       [PASS][65] -> [DMESG-WARN][66]
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-kbl-7567u/igt@gem_busy@busy-all.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-7567u/igt@gem_busy@busy-all.html
    - fi-skl-iommu:       [PASS][67] -> [DMESG-WARN][68]
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-skl-iommu/igt@gem_busy@busy-all.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-skl-iommu/igt@gem_busy@busy-all.html
    - fi-elk-e7500:       [PASS][69] -> [DMESG-WARN][70]
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-elk-e7500/igt@gem_busy@busy-all.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-elk-e7500/igt@gem_busy@busy-all.html
    - fi-skl-6700k2:      [PASS][71] -> [DMESG-WARN][72]
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-skl-6700k2/igt@gem_busy@busy-all.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-skl-6700k2/igt@gem_busy@busy-all.html
    - fi-whl-u:           [PASS][73] -> [DMESG-WARN][74]
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-whl-u/igt@gem_busy@busy-all.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-whl-u/igt@gem_busy@busy-all.html
    - fi-byt-j1900:       [PASS][75] -> [DMESG-WARN][76]
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-byt-j1900/igt@gem_busy@busy-all.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-byt-j1900/igt@gem_busy@busy-all.html
    - fi-cml-u:           [PASS][77] -> [DMESG-WARN][78]
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-cml-u/igt@gem_busy@busy-all.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cml-u/igt@gem_busy@busy-all.html
    - fi-cfl-8109u:       [PASS][79] -> [DMESG-WARN][80]
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-cfl-8109u/igt@gem_busy@busy-all.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cfl-8109u/igt@gem_busy@busy-all.html

  * igt@gem_close_race@basic-process:
    - fi-bwr-2160:        [PASS][81] -> [DMESG-WARN][82]
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-bwr-2160/igt@gem_close_race@basic-process.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bwr-2160/igt@gem_close_race@basic-process.html

  * {igt@i915_selftest@live_gt_contexts} (NEW):
    - fi-pnv-d510:        NOTRUN -> [DMESG-FAIL][83]
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-pnv-d510/igt@i915_selftest@live_gt_contexts.html
    - fi-gdg-551:         NOTRUN -> [DMESG-FAIL][84]
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-gdg-551/igt@i915_selftest@live_gt_contexts.html

  * igt@runner@aborted:
    - fi-ilk-650:         NOTRUN -> [FAIL][85]
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-ilk-650/igt@runner@aborted.html
    - fi-bdw-gvtdvm:      NOTRUN -> [FAIL][86]
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bdw-gvtdvm/igt@runner@aborted.html
    - fi-cfl-8109u:       NOTRUN -> [FAIL][87]
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cfl-8109u/igt@runner@aborted.html
    - fi-hsw-peppy:       NOTRUN -> [FAIL][88]
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-hsw-peppy/igt@runner@aborted.html
    - fi-snb-2520m:       NOTRUN -> [FAIL][89]
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-snb-2520m/igt@runner@aborted.html
    - fi-hsw-4770:        NOTRUN -> [FAIL][90]
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-hsw-4770/igt@runner@aborted.html
    - fi-kbl-7500u:       NOTRUN -> [FAIL][91]
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-7500u/igt@runner@aborted.html
    - fi-bxt-j4205:       NOTRUN -> [FAIL][92]
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bxt-j4205/igt@runner@aborted.html
    - fi-whl-u:           NOTRUN -> [FAIL][93]
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-whl-u/igt@runner@aborted.html
    - fi-cml-u2:          NOTRUN -> [FAIL][94]
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cml-u2/igt@runner@aborted.html
    - fi-cml-u:           NOTRUN -> [FAIL][95]
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cml-u/igt@runner@aborted.html
    - fi-ivb-3770:        NOTRUN -> [FAIL][96]
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-ivb-3770/igt@runner@aborted.html
    - fi-bxt-dsi:         NOTRUN -> [FAIL][97]
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bxt-dsi/igt@runner@aborted.html
    - fi-byt-j1900:       NOTRUN -> [FAIL][98]
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-byt-j1900/igt@runner@aborted.html
    - fi-cfl-guc:         NOTRUN -> [FAIL][99]
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cfl-guc/igt@runner@aborted.html
    - fi-kbl-7567u:       NOTRUN -> [FAIL][100]
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-7567u/igt@runner@aborted.html
    - fi-kbl-x1275:       NOTRUN -> [FAIL][101]
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-x1275/igt@runner@aborted.html
    - fi-cfl-8700k:       NOTRUN -> [FAIL][102]
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-cfl-8700k/igt@runner@aborted.html
    - fi-hsw-4770r:       NOTRUN -> [FAIL][103]
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-hsw-4770r/igt@runner@aborted.html
    - fi-kbl-8809g:       NOTRUN -> [FAIL][104]
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-8809g/igt@runner@aborted.html
    - fi-apl-guc:         NOTRUN -> [FAIL][105]
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-apl-guc/igt@runner@aborted.html
    - fi-kbl-r:           NOTRUN -> [FAIL][106]
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-r/igt@runner@aborted.html
    - fi-bdw-5557u:       NOTRUN -> [FAIL][107]
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-bdw-5557u/igt@runner@aborted.html
    - fi-byt-n2820:       NOTRUN -> [FAIL][108]
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-byt-n2820/igt@runner@aborted.html
    - fi-kbl-guc:         NOTRUN -> [FAIL][109]
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-kbl-guc/igt@runner@aborted.html
    - fi-snb-2600:        NOTRUN -> [FAIL][110]
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-snb-2600/igt@runner@aborted.html

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@gem_busy@busy-all:
    - {fi-icl-u4}:        NOTRUN -> [DMESG-WARN][111]
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-icl-u4/igt@gem_busy@busy-all.html

  
New tests
---------

  New tests have been introduced between CI_DRM_6547 and Patchwork_13742:

### New IGT tests (2) ###

  * igt@i915_selftest@live_gem_contexts:
    - Statuses : 2 pass(s)
    - Exec time: [1.14, 1.30] s

  * igt@i915_selftest@live_gt_contexts:
    - Statuses : 2 dmesg-fail(s)
    - Exec time: [1.19, 1.36] s

  

Known issues
------------

  Here are the changes found in Patchwork_13742 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-blb-e6850:       [PASS][112] -> [INCOMPLETE][113] ([fdo#107718])
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6547/fi-blb-e6850/igt@gem_exec_suspend@basic-s3.html
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/fi-blb-e6850/igt@gem_exec_suspend@basic-s3.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718


Participating hosts (51 -> 46)
------------------------------

  Additional (3): fi-skl-6770hq fi-icl-u4 fi-icl-dsi 
  Missing    (8): fi-kbl-soraka fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-icl-y fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_6547 -> Patchwork_13742

  CI-20190529: 20190529
  CI_DRM_6547: 015f59f5b26406af6b2580fedd37fdb08e18f4a9 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5109: e5fd509e16ec649436be31f38eaa5b85cb7f72f1 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_13742: 4db89a82be2b0594d66dd5264eaf8a060d3d6586 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

4db89a82be2b drm/i915: Unshare the idle-barrier from other kernel requests

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13742/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests
  2019-07-25  7:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
  2019-07-25  8:26 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev3) Patchwork
  2019-07-25  9:12 ` ✗ Fi.CI.BAT: failure " Patchwork
@ 2019-07-25  9:38 ` Chris Wilson
  2019-07-25 10:26   ` Lionel Landwerlin
  2019-07-25 13:19   ` Tvrtko Ursulin
  2019-07-25 11:23 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev4) Patchwork
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 13+ messages in thread
From: Chris Wilson @ 2019-07-25  9:38 UTC (permalink / raw)
  To: intel-gfx

Under some circumstances (see intel_context_prepare_remote_request), we
may use a request along a kernel context to modify the logical state of
another. To keep the target context in place while the request executes,
we take an active reference on it using the kernel timeline. This is the
same timeline as we use for the idle-barrier, and so we end up reusing
the same active node. Except that the idle barrier is special and cannot
be reused in this manner! Give the idle-barrier a reserved timeline
index (0) so that it will always be unique (give or take we may issue
multiple idle barriers across multiple engines).

Reported-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: ce476c80b8bf ("drm/i915: Keep contexts pinned until after the next kernel context switch")
Fixes: a9877da2d629 ("drm/i915/oa: Reconfigure contexts on the fly")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_context.c       |  42 ++-
 drivers/gpu/drm/i915/gt/intel_context.h       |  13 +-
 drivers/gpu/drm/i915/gt/selftest_context.c    | 321 ++++++++++++++++++
 drivers/gpu/drm/i915/i915_active.c            |  67 +++-
 .../drm/i915/selftests/i915_live_selftests.h  |   3 +-
 5 files changed, 408 insertions(+), 38 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/selftest_context.c

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 9292b6ca5e9c..bc20161bab9f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -162,18 +162,8 @@ static int __intel_context_active(struct i915_active *active)
 	if (err)
 		goto err_ring;
 
-	/* Preallocate tracking nodes */
-	if (!i915_gem_context_is_kernel(ce->gem_context)) {
-		err = i915_active_acquire_preallocate_barrier(&ce->active,
-							      ce->engine);
-		if (err)
-			goto err_state;
-	}
-
 	return 0;
 
-err_state:
-	__context_unpin_state(ce->state);
 err_ring:
 	intel_ring_unpin(ce->ring);
 err_put:
@@ -181,6 +171,34 @@ static int __intel_context_active(struct i915_active *active)
 	return err;
 }
 
+int intel_context_active_acquire(struct intel_context *ce)
+{
+	int err;
+
+	err = i915_active_acquire(&ce->active);
+	if (err)
+		return err;
+
+	/* Preallocate tracking nodes */
+	if (ce->state && !i915_gem_context_is_kernel(ce->gem_context)) {
+		err = i915_active_acquire_preallocate_barrier(&ce->active,
+							      ce->engine);
+		if (err) {
+			i915_active_release(&ce->active);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+void intel_context_active_release(struct intel_context *ce)
+{
+	/* Nodes preallocated in intel_context_active() */
+	i915_active_acquire_barrier(&ce->active);
+	i915_active_release(&ce->active);
+}
+
 void
 intel_context_init(struct intel_context *ce,
 		   struct i915_gem_context *ctx,
@@ -284,3 +302,7 @@ struct i915_request *intel_context_create_request(struct intel_context *ce)
 
 	return rq;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftest_context.c"
+#endif
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index 23c7e4c0ce7c..07f9924de48f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -104,17 +104,8 @@ static inline void intel_context_exit(struct intel_context *ce)
 		ce->ops->exit(ce);
 }
 
-static inline int intel_context_active_acquire(struct intel_context *ce)
-{
-	return i915_active_acquire(&ce->active);
-}
-
-static inline void intel_context_active_release(struct intel_context *ce)
-{
-	/* Nodes preallocated in intel_context_active() */
-	i915_active_acquire_barrier(&ce->active);
-	i915_active_release(&ce->active);
-}
+int intel_context_active_acquire(struct intel_context *ce);
+void intel_context_active_release(struct intel_context *ce);
 
 static inline struct intel_context *intel_context_get(struct intel_context *ce)
 {
diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c
new file mode 100644
index 000000000000..4d251faafcc0
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/selftest_context.c
@@ -0,0 +1,321 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "i915_selftest.h"
+#include "intel_gt.h"
+
+#include "gem/selftests/mock_context.h"
+#include "selftests/igt_flush_test.h"
+#include "selftests/mock_drm.h"
+
+static int request_sync(struct i915_request *rq)
+{
+	long timeout;
+	int err = 0;
+
+	i915_request_get(rq);
+
+	i915_request_add(rq);
+	timeout = i915_request_wait(rq, 0, HZ / 10);
+	if (timeout < 0)
+		err = timeout;
+	else
+		i915_request_retire_upto(rq);
+
+	i915_request_put(rq);
+
+	return err;
+}
+
+static int context_sync(struct intel_context *ce)
+{
+	struct intel_timeline *tl = ce->ring->timeline;
+	int err = 0;
+
+	do {
+		struct i915_request *rq;
+		long timeout;
+
+		rcu_read_lock();
+		rq = rcu_dereference(tl->last_request.request);
+		if (rq)
+			rq = i915_request_get_rcu(rq);
+		rcu_read_unlock();
+		if (!rq)
+			break;
+
+		timeout = i915_request_wait(rq, 0, HZ / 10);
+		if (timeout < 0)
+			err = timeout;
+		else
+			i915_request_retire_upto(rq);
+
+		i915_request_put(rq);
+	} while (!err);
+
+	return err;
+}
+
+static int __live_active_context(struct intel_engine_cs *engine,
+				 struct i915_gem_context *fixme)
+{
+	struct intel_context *ce;
+	int pass;
+	int err;
+
+	/*
+	 * We keep active contexts alive until after a subsequent context
+	 * switch as the final write from the context-save will be after
+	 * we retire the final request. We track when we unpin the context,
+	 * under the presumption that the final pin is from the last request,
+	 * and instead of immediately unpinning the context, we add a task
+	 * to unpin the context from the next idle-barrier.
+	 *
+	 * This test makes sure that the context is kept alive until a
+	 * subsequent idle-barrier (emitted when the engine wakeref hits 0
+	 * with no more outstanding requests).
+	 */
+
+	if (intel_engine_pm_is_awake(engine)) {
+		pr_err("%s is awake before starting %s!\n",
+		       engine->name, __func__);
+		return -EINVAL;
+	}
+
+	ce = intel_context_create(fixme, engine);
+	if (!ce)
+		return -ENOMEM;
+
+	for (pass = 0; pass <= 2; pass++) {
+		struct i915_request *rq;
+
+		rq = intel_context_create_request(ce);
+		if (IS_ERR(rq)) {
+			err = PTR_ERR(rq);
+			goto err;
+		}
+
+		err = request_sync(rq);
+		if (err)
+			goto err;
+
+		/* Context will be kept active until after an idle-barrier. */
+		if (i915_active_is_idle(&ce->active)) {
+			pr_err("context is not active; expected idle-barrier (pass %d)\n", pass);
+			err = -EINVAL;
+			goto err;
+		}
+
+		if (!intel_engine_pm_is_awake(engine)) {
+			pr_err("%s is asleep before idle-barrier %s!\n",
+			       engine->name, __func__);
+			err = -EINVAL;
+			goto err;
+		}
+	}
+
+	/* Now make sure our idle-barriers are flushed */
+	err = context_sync(engine->kernel_context);
+	if (err)
+		goto err;
+
+	if (!i915_active_is_idle(&ce->active)) {
+		pr_err("context is still active!");
+		err = -EINVAL;
+	}
+
+	if (intel_engine_pm_is_awake(engine)) {
+		struct drm_printer p = drm_debug_printer(__func__);
+
+		intel_engine_dump(engine, &p,
+				  "%s is still awake after idle-barriers\n",
+				  engine->name);
+		GEM_TRACE_DUMP();
+
+		err = -EINVAL;
+		goto err;
+	}
+
+err:
+	intel_context_put(ce);
+	return err;
+}
+
+static int live_active_context(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct intel_engine_cs *engine;
+	struct i915_gem_context *fixme;
+	enum intel_engine_id id;
+	struct drm_file *file;
+	int err = 0;
+
+	file = mock_file(gt->i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	mutex_lock(&gt->i915->drm.struct_mutex);
+
+	fixme = live_context(gt->i915, file);
+	if (!fixme) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	for_each_engine(engine, gt->i915, id) {
+		err = __live_active_context(engine, fixme);
+		if (err)
+			break;
+
+		err = igt_flush_test(gt->i915, I915_WAIT_LOCKED);
+		if (err)
+			break;
+	}
+
+unlock:
+	mutex_unlock(&gt->i915->drm.struct_mutex);
+	mock_file_free(gt->i915, file);
+	return err;
+}
+
+static int __live_remote_context(struct intel_engine_cs *engine,
+				 struct i915_gem_context *fixme)
+{
+	struct intel_context *local, *remote;
+	struct i915_request *rq;
+	int pass;
+	int err;
+
+	/*
+	 * Check that our idle barriers do not interfere with normal
+	 * activity tracking. In particular, check that operating
+	 * on the context image remotely (intel_context_prepare_remote_request)
+	 * which inserts foriegn fences into intel_context.active are not
+	 * clobbered.
+	 */
+
+	remote = intel_context_create(fixme, engine);
+	if (!remote)
+		return -ENOMEM;
+
+	local = intel_context_create(fixme, engine);
+	if (!local) {
+		err = -ENOMEM;
+		goto err_remote;
+	}
+
+	for (pass = 0; pass <= 2; pass++) {
+		err = intel_context_pin(remote);
+		if (err)
+			goto err_local;
+
+		rq = intel_context_create_request(local);
+		if (IS_ERR(rq)) {
+			err = PTR_ERR(rq);
+			goto err_unpin;
+		}
+
+		err = intel_context_prepare_remote_request(remote, rq);
+		if (err) {
+			i915_request_add(rq);
+			goto err_unpin;
+		}
+
+		err = request_sync(rq);
+		if (err)
+			goto err_unpin;
+
+		intel_context_unpin(remote);
+		err = intel_context_pin(remote);
+		if (err)
+			goto err_local;
+
+		rq = i915_request_create(engine->kernel_context);
+		if (IS_ERR(rq)) {
+			err = PTR_ERR(rq);
+			goto err_unpin;
+		}
+
+		err = intel_context_prepare_remote_request(remote, rq);
+		if (err) {
+			i915_request_add(rq);
+			goto err_unpin;
+		}
+
+		err = request_sync(rq);
+		if (err)
+			goto err_unpin;
+
+		intel_context_unpin(remote);
+
+		if (i915_active_is_idle(&remote->active)) {
+			pr_err("remote context is not active; expected idle-barrier (pass %d)\n", pass);
+			err = -EINVAL;
+			goto err_local;
+		}
+	}
+
+	goto err_local;
+
+err_unpin:
+	intel_context_unpin(remote);
+err_local:
+	intel_context_put(local);
+err_remote:
+	intel_context_put(remote);
+	return err;
+}
+
+static int live_remote_context(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct intel_engine_cs *engine;
+	struct i915_gem_context *fixme;
+	enum intel_engine_id id;
+	struct drm_file *file;
+	int err = 0;
+
+	file = mock_file(gt->i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	mutex_lock(&gt->i915->drm.struct_mutex);
+
+	fixme = live_context(gt->i915, file);
+	if (!fixme) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	for_each_engine(engine, gt->i915, id) {
+		err = __live_remote_context(engine, fixme);
+		if (err)
+			break;
+
+		err = igt_flush_test(gt->i915, I915_WAIT_LOCKED);
+		if (err)
+			break;
+	}
+
+unlock:
+	mutex_unlock(&gt->i915->drm.struct_mutex);
+	mock_file_free(gt->i915, file);
+	return err;
+}
+
+int intel_context_live_selftests(struct drm_i915_private *i915)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(live_active_context),
+		SUBTEST(live_remote_context),
+	};
+	struct intel_gt *gt = &i915->gt;
+
+	if (intel_gt_is_wedged(gt))
+		return 0;
+
+	return intel_gt_live_subtests(tests, gt);
+}
diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 13f304a29fc8..e04afb519264 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -184,6 +184,7 @@ active_instance(struct i915_active *ref, u64 idx)
 	ref->cache = node;
 	mutex_unlock(&ref->mutex);
 
+	BUILD_BUG_ON(offsetof(typeof(*node), base));
 	return &node->base;
 }
 
@@ -212,6 +213,8 @@ int i915_active_ref(struct i915_active *ref,
 	struct i915_active_request *active;
 	int err;
 
+	GEM_BUG_ON(!timeline); /* reserved for idle-barrier */
+
 	/* Prevent reaping in case we malloc/wait while building the tree */
 	err = i915_active_acquire(ref);
 	if (err)
@@ -222,6 +225,7 @@ int i915_active_ref(struct i915_active *ref,
 		err = -ENOMEM;
 		goto out;
 	}
+	GEM_BUG_ON(IS_ERR(active->request));
 
 	if (!i915_active_request_isset(active))
 		atomic_inc(&ref->count);
@@ -342,6 +346,34 @@ void i915_active_fini(struct i915_active *ref)
 }
 #endif
 
+static struct active_node *idle_barrier(struct i915_active *ref)
+{
+	struct active_node *idle = NULL;
+	struct rb_node *rb;
+
+	if (RB_EMPTY_ROOT(&ref->tree))
+		return NULL;
+
+	mutex_lock(&ref->mutex);
+	for (rb = rb_first(&ref->tree); rb; rb = rb_next(rb)) {
+		struct active_node *node;
+
+		node = rb_entry(rb, typeof(*node), node);
+		if (node->timeline)
+			break;
+
+		if (!i915_active_request_isset(&node->base)) {
+			GEM_BUG_ON(!list_empty(&node->base.link));
+			rb_erase(rb, &ref->tree);
+			idle = node;
+			break;
+		}
+	}
+	mutex_unlock(&ref->mutex);
+
+	return idle;
+}
+
 int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
 					    struct intel_engine_cs *engine)
 {
@@ -352,22 +384,29 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
 
 	GEM_BUG_ON(!engine->mask);
 	for_each_engine_masked(engine, i915, engine->mask, tmp) {
-		struct intel_context *kctx = engine->kernel_context;
 		struct active_node *node;
 
-		node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
-		if (unlikely(!node)) {
-			err = -ENOMEM;
-			goto unwind;
+		node = idle_barrier(ref);
+		if (!node) {
+			node = kmem_cache_alloc(global.slab_cache,
+						GFP_KERNEL |
+						__GFP_RETRY_MAYFAIL |
+						__GFP_NOWARN);
+			if (unlikely(!node)) {
+				err = -ENOMEM;
+				goto unwind;
+			}
+
+			node->ref = ref;
+			node->timeline = 0;
+			node->base.retire = node_retire;
 		}
 
-		i915_active_request_init(&node->base,
-					 (void *)engine, node_retire);
-		node->timeline = kctx->ring->timeline->fence_context;
-		node->ref = ref;
+		intel_engine_pm_get(engine);
+
+		RCU_INIT_POINTER(node->base.request, (void *)engine);
 		atomic_inc(&ref->count);
 
-		intel_engine_pm_get(engine);
 		llist_add((struct llist_node *)&node->base.link,
 			  &ref->barriers);
 	}
@@ -402,6 +441,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 
 		node = container_of((struct list_head *)pos,
 				    typeof(*node), base.link);
+		GEM_BUG_ON(node->timeline);
 
 		engine = (void *)rcu_access_pointer(node->base.request);
 		RCU_INIT_POINTER(node->base.request, ERR_PTR(-EAGAIN));
@@ -410,12 +450,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 		p = &ref->tree.rb_node;
 		while (*p) {
 			parent = *p;
-			if (rb_entry(parent,
-				     struct active_node,
-				     node)->timeline < node->timeline)
-				p = &parent->rb_right;
-			else
-				p = &parent->rb_left;
+			p = &parent->rb_left;
 		}
 		rb_link_node(&node->node, parent, p);
 		rb_insert_color(&node->node, &ref->tree);
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 2b31a4ee0b4c..a841d3f9bedc 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -15,6 +15,7 @@ selftest(workarounds, intel_workarounds_live_selftests)
 selftest(timelines, intel_timeline_live_selftests)
 selftest(requests, i915_request_live_selftests)
 selftest(active, i915_active_live_selftests)
+selftest(gt_contexts, intel_context_live_selftests)
 selftest(objects, i915_gem_object_live_selftests)
 selftest(mman, i915_gem_mman_live_selftests)
 selftest(dmabuf, i915_gem_dmabuf_live_selftests)
@@ -24,7 +25,7 @@ selftest(gtt, i915_gem_gtt_live_selftests)
 selftest(gem, i915_gem_live_selftests)
 selftest(evict, i915_gem_evict_live_selftests)
 selftest(hugepages, i915_gem_huge_page_live_selftests)
-selftest(contexts, i915_gem_context_live_selftests)
+selftest(gem_contexts, i915_gem_context_live_selftests)
 selftest(blt, i915_gem_object_blt_live_selftests)
 selftest(client, i915_gem_client_blt_live_selftests)
 selftest(reset, intel_reset_live_selftests)
-- 
2.22.0

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests
  2019-07-25  9:38 ` [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
@ 2019-07-25 10:26   ` Lionel Landwerlin
  2019-07-25 13:19   ` Tvrtko Ursulin
  1 sibling, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2019-07-25 10:26 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On 25/07/2019 12:38, Chris Wilson wrote:
> Under some circumstances (see intel_context_prepare_remote_request), we
> may use a request along a kernel context to modify the logical state of
> another. To keep the target context in place while the request executes,
> we take an active reference on it using the kernel timeline. This is the
> same timeline as we use for the idle-barrier, and so we end up reusing
> the same active node. Except that the idle barrier is special and cannot
> be reused in this manner! Give the idle-barrier a reserved timeline
> index (0) so that it will always be unique (give or take we may issue
> multiple idle barriers across multiple engines).
>
> Reported-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Fixes: ce476c80b8bf ("drm/i915: Keep contexts pinned until after the next kernel context switch")
> Fixes: a9877da2d629 ("drm/i915/oa: Reconfigure contexts on the fly")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>


Not hugely stressed tested, but seems to solve the problem I'm seeing :


Tested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>


Thanks!


> ---
>   drivers/gpu/drm/i915/gt/intel_context.c       |  42 ++-
>   drivers/gpu/drm/i915/gt/intel_context.h       |  13 +-
>   drivers/gpu/drm/i915/gt/selftest_context.c    | 321 ++++++++++++++++++
>   drivers/gpu/drm/i915/i915_active.c            |  67 +++-
>   .../drm/i915/selftests/i915_live_selftests.h  |   3 +-
>   5 files changed, 408 insertions(+), 38 deletions(-)
>   create mode 100644 drivers/gpu/drm/i915/gt/selftest_context.c
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
> index 9292b6ca5e9c..bc20161bab9f 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -162,18 +162,8 @@ static int __intel_context_active(struct i915_active *active)
>   	if (err)
>   		goto err_ring;
>   
> -	/* Preallocate tracking nodes */
> -	if (!i915_gem_context_is_kernel(ce->gem_context)) {
> -		err = i915_active_acquire_preallocate_barrier(&ce->active,
> -							      ce->engine);
> -		if (err)
> -			goto err_state;
> -	}
> -
>   	return 0;
>   
> -err_state:
> -	__context_unpin_state(ce->state);
>   err_ring:
>   	intel_ring_unpin(ce->ring);
>   err_put:
> @@ -181,6 +171,34 @@ static int __intel_context_active(struct i915_active *active)
>   	return err;
>   }
>   
> +int intel_context_active_acquire(struct intel_context *ce)
> +{
> +	int err;
> +
> +	err = i915_active_acquire(&ce->active);
> +	if (err)
> +		return err;
> +
> +	/* Preallocate tracking nodes */
> +	if (ce->state && !i915_gem_context_is_kernel(ce->gem_context)) {
> +		err = i915_active_acquire_preallocate_barrier(&ce->active,
> +							      ce->engine);
> +		if (err) {
> +			i915_active_release(&ce->active);
> +			return err;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +void intel_context_active_release(struct intel_context *ce)
> +{
> +	/* Nodes preallocated in intel_context_active() */
> +	i915_active_acquire_barrier(&ce->active);
> +	i915_active_release(&ce->active);
> +}
> +
>   void
>   intel_context_init(struct intel_context *ce,
>   		   struct i915_gem_context *ctx,
> @@ -284,3 +302,7 @@ struct i915_request *intel_context_create_request(struct intel_context *ce)
>   
>   	return rq;
>   }
> +
> +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> +#include "selftest_context.c"
> +#endif
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
> index 23c7e4c0ce7c..07f9924de48f 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.h
> +++ b/drivers/gpu/drm/i915/gt/intel_context.h
> @@ -104,17 +104,8 @@ static inline void intel_context_exit(struct intel_context *ce)
>   		ce->ops->exit(ce);
>   }
>   
> -static inline int intel_context_active_acquire(struct intel_context *ce)
> -{
> -	return i915_active_acquire(&ce->active);
> -}
> -
> -static inline void intel_context_active_release(struct intel_context *ce)
> -{
> -	/* Nodes preallocated in intel_context_active() */
> -	i915_active_acquire_barrier(&ce->active);
> -	i915_active_release(&ce->active);
> -}
> +int intel_context_active_acquire(struct intel_context *ce);
> +void intel_context_active_release(struct intel_context *ce);
>   
>   static inline struct intel_context *intel_context_get(struct intel_context *ce)
>   {
> diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c
> new file mode 100644
> index 000000000000..4d251faafcc0
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/selftest_context.c
> @@ -0,0 +1,321 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0
> + *
> + * Copyright © 2019 Intel Corporation
> + */
> +
> +#include "i915_selftest.h"
> +#include "intel_gt.h"
> +
> +#include "gem/selftests/mock_context.h"
> +#include "selftests/igt_flush_test.h"
> +#include "selftests/mock_drm.h"
> +
> +static int request_sync(struct i915_request *rq)
> +{
> +	long timeout;
> +	int err = 0;
> +
> +	i915_request_get(rq);
> +
> +	i915_request_add(rq);
> +	timeout = i915_request_wait(rq, 0, HZ / 10);
> +	if (timeout < 0)
> +		err = timeout;
> +	else
> +		i915_request_retire_upto(rq);
> +
> +	i915_request_put(rq);
> +
> +	return err;
> +}
> +
> +static int context_sync(struct intel_context *ce)
> +{
> +	struct intel_timeline *tl = ce->ring->timeline;
> +	int err = 0;
> +
> +	do {
> +		struct i915_request *rq;
> +		long timeout;
> +
> +		rcu_read_lock();
> +		rq = rcu_dereference(tl->last_request.request);
> +		if (rq)
> +			rq = i915_request_get_rcu(rq);
> +		rcu_read_unlock();
> +		if (!rq)
> +			break;
> +
> +		timeout = i915_request_wait(rq, 0, HZ / 10);
> +		if (timeout < 0)
> +			err = timeout;
> +		else
> +			i915_request_retire_upto(rq);
> +
> +		i915_request_put(rq);
> +	} while (!err);
> +
> +	return err;
> +}
> +
> +static int __live_active_context(struct intel_engine_cs *engine,
> +				 struct i915_gem_context *fixme)
> +{
> +	struct intel_context *ce;
> +	int pass;
> +	int err;
> +
> +	/*
> +	 * We keep active contexts alive until after a subsequent context
> +	 * switch as the final write from the context-save will be after
> +	 * we retire the final request. We track when we unpin the context,
> +	 * under the presumption that the final pin is from the last request,
> +	 * and instead of immediately unpinning the context, we add a task
> +	 * to unpin the context from the next idle-barrier.
> +	 *
> +	 * This test makes sure that the context is kept alive until a
> +	 * subsequent idle-barrier (emitted when the engine wakeref hits 0
> +	 * with no more outstanding requests).
> +	 */
> +
> +	if (intel_engine_pm_is_awake(engine)) {
> +		pr_err("%s is awake before starting %s!\n",
> +		       engine->name, __func__);
> +		return -EINVAL;
> +	}
> +
> +	ce = intel_context_create(fixme, engine);
> +	if (!ce)
> +		return -ENOMEM;
> +
> +	for (pass = 0; pass <= 2; pass++) {
> +		struct i915_request *rq;
> +
> +		rq = intel_context_create_request(ce);
> +		if (IS_ERR(rq)) {
> +			err = PTR_ERR(rq);
> +			goto err;
> +		}
> +
> +		err = request_sync(rq);
> +		if (err)
> +			goto err;
> +
> +		/* Context will be kept active until after an idle-barrier. */
> +		if (i915_active_is_idle(&ce->active)) {
> +			pr_err("context is not active; expected idle-barrier (pass %d)\n", pass);
> +			err = -EINVAL;
> +			goto err;
> +		}
> +
> +		if (!intel_engine_pm_is_awake(engine)) {
> +			pr_err("%s is asleep before idle-barrier %s!\n",
> +			       engine->name, __func__);
> +			err = -EINVAL;
> +			goto err;
> +		}
> +	}
> +
> +	/* Now make sure our idle-barriers are flushed */
> +	err = context_sync(engine->kernel_context);
> +	if (err)
> +		goto err;
> +
> +	if (!i915_active_is_idle(&ce->active)) {
> +		pr_err("context is still active!");
> +		err = -EINVAL;
> +	}
> +
> +	if (intel_engine_pm_is_awake(engine)) {
> +		struct drm_printer p = drm_debug_printer(__func__);
> +
> +		intel_engine_dump(engine, &p,
> +				  "%s is still awake after idle-barriers\n",
> +				  engine->name);
> +		GEM_TRACE_DUMP();
> +
> +		err = -EINVAL;
> +		goto err;
> +	}
> +
> +err:
> +	intel_context_put(ce);
> +	return err;
> +}
> +
> +static int live_active_context(void *arg)
> +{
> +	struct intel_gt *gt = arg;
> +	struct intel_engine_cs *engine;
> +	struct i915_gem_context *fixme;
> +	enum intel_engine_id id;
> +	struct drm_file *file;
> +	int err = 0;
> +
> +	file = mock_file(gt->i915);
> +	if (IS_ERR(file))
> +		return PTR_ERR(file);
> +
> +	mutex_lock(&gt->i915->drm.struct_mutex);
> +
> +	fixme = live_context(gt->i915, file);
> +	if (!fixme) {
> +		err = -ENOMEM;
> +		goto unlock;
> +	}
> +
> +	for_each_engine(engine, gt->i915, id) {
> +		err = __live_active_context(engine, fixme);
> +		if (err)
> +			break;
> +
> +		err = igt_flush_test(gt->i915, I915_WAIT_LOCKED);
> +		if (err)
> +			break;
> +	}
> +
> +unlock:
> +	mutex_unlock(&gt->i915->drm.struct_mutex);
> +	mock_file_free(gt->i915, file);
> +	return err;
> +}
> +
> +static int __live_remote_context(struct intel_engine_cs *engine,
> +				 struct i915_gem_context *fixme)
> +{
> +	struct intel_context *local, *remote;
> +	struct i915_request *rq;
> +	int pass;
> +	int err;
> +
> +	/*
> +	 * Check that our idle barriers do not interfere with normal
> +	 * activity tracking. In particular, check that operating
> +	 * on the context image remotely (intel_context_prepare_remote_request)
> +	 * which inserts foriegn fences into intel_context.active are not
> +	 * clobbered.
> +	 */
> +
> +	remote = intel_context_create(fixme, engine);
> +	if (!remote)
> +		return -ENOMEM;
> +
> +	local = intel_context_create(fixme, engine);
> +	if (!local) {
> +		err = -ENOMEM;
> +		goto err_remote;
> +	}
> +
> +	for (pass = 0; pass <= 2; pass++) {
> +		err = intel_context_pin(remote);
> +		if (err)
> +			goto err_local;
> +
> +		rq = intel_context_create_request(local);
> +		if (IS_ERR(rq)) {
> +			err = PTR_ERR(rq);
> +			goto err_unpin;
> +		}
> +
> +		err = intel_context_prepare_remote_request(remote, rq);
> +		if (err) {
> +			i915_request_add(rq);
> +			goto err_unpin;
> +		}
> +
> +		err = request_sync(rq);
> +		if (err)
> +			goto err_unpin;
> +
> +		intel_context_unpin(remote);
> +		err = intel_context_pin(remote);
> +		if (err)
> +			goto err_local;
> +
> +		rq = i915_request_create(engine->kernel_context);
> +		if (IS_ERR(rq)) {
> +			err = PTR_ERR(rq);
> +			goto err_unpin;
> +		}
> +
> +		err = intel_context_prepare_remote_request(remote, rq);
> +		if (err) {
> +			i915_request_add(rq);
> +			goto err_unpin;
> +		}
> +
> +		err = request_sync(rq);
> +		if (err)
> +			goto err_unpin;
> +
> +		intel_context_unpin(remote);
> +
> +		if (i915_active_is_idle(&remote->active)) {
> +			pr_err("remote context is not active; expected idle-barrier (pass %d)\n", pass);
> +			err = -EINVAL;
> +			goto err_local;
> +		}
> +	}
> +
> +	goto err_local;
> +
> +err_unpin:
> +	intel_context_unpin(remote);
> +err_local:
> +	intel_context_put(local);
> +err_remote:
> +	intel_context_put(remote);
> +	return err;
> +}
> +
> +static int live_remote_context(void *arg)
> +{
> +	struct intel_gt *gt = arg;
> +	struct intel_engine_cs *engine;
> +	struct i915_gem_context *fixme;
> +	enum intel_engine_id id;
> +	struct drm_file *file;
> +	int err = 0;
> +
> +	file = mock_file(gt->i915);
> +	if (IS_ERR(file))
> +		return PTR_ERR(file);
> +
> +	mutex_lock(&gt->i915->drm.struct_mutex);
> +
> +	fixme = live_context(gt->i915, file);
> +	if (!fixme) {
> +		err = -ENOMEM;
> +		goto unlock;
> +	}
> +
> +	for_each_engine(engine, gt->i915, id) {
> +		err = __live_remote_context(engine, fixme);
> +		if (err)
> +			break;
> +
> +		err = igt_flush_test(gt->i915, I915_WAIT_LOCKED);
> +		if (err)
> +			break;
> +	}
> +
> +unlock:
> +	mutex_unlock(&gt->i915->drm.struct_mutex);
> +	mock_file_free(gt->i915, file);
> +	return err;
> +}
> +
> +int intel_context_live_selftests(struct drm_i915_private *i915)
> +{
> +	static const struct i915_subtest tests[] = {
> +		SUBTEST(live_active_context),
> +		SUBTEST(live_remote_context),
> +	};
> +	struct intel_gt *gt = &i915->gt;
> +
> +	if (intel_gt_is_wedged(gt))
> +		return 0;
> +
> +	return intel_gt_live_subtests(tests, gt);
> +}
> diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
> index 13f304a29fc8..e04afb519264 100644
> --- a/drivers/gpu/drm/i915/i915_active.c
> +++ b/drivers/gpu/drm/i915/i915_active.c
> @@ -184,6 +184,7 @@ active_instance(struct i915_active *ref, u64 idx)
>   	ref->cache = node;
>   	mutex_unlock(&ref->mutex);
>   
> +	BUILD_BUG_ON(offsetof(typeof(*node), base));
>   	return &node->base;
>   }
>   
> @@ -212,6 +213,8 @@ int i915_active_ref(struct i915_active *ref,
>   	struct i915_active_request *active;
>   	int err;
>   
> +	GEM_BUG_ON(!timeline); /* reserved for idle-barrier */
> +
>   	/* Prevent reaping in case we malloc/wait while building the tree */
>   	err = i915_active_acquire(ref);
>   	if (err)
> @@ -222,6 +225,7 @@ int i915_active_ref(struct i915_active *ref,
>   		err = -ENOMEM;
>   		goto out;
>   	}
> +	GEM_BUG_ON(IS_ERR(active->request));
>   
>   	if (!i915_active_request_isset(active))
>   		atomic_inc(&ref->count);
> @@ -342,6 +346,34 @@ void i915_active_fini(struct i915_active *ref)
>   }
>   #endif
>   
> +static struct active_node *idle_barrier(struct i915_active *ref)
> +{
> +	struct active_node *idle = NULL;
> +	struct rb_node *rb;
> +
> +	if (RB_EMPTY_ROOT(&ref->tree))
> +		return NULL;
> +
> +	mutex_lock(&ref->mutex);
> +	for (rb = rb_first(&ref->tree); rb; rb = rb_next(rb)) {
> +		struct active_node *node;
> +
> +		node = rb_entry(rb, typeof(*node), node);
> +		if (node->timeline)
> +			break;
> +
> +		if (!i915_active_request_isset(&node->base)) {
> +			GEM_BUG_ON(!list_empty(&node->base.link));
> +			rb_erase(rb, &ref->tree);
> +			idle = node;
> +			break;
> +		}
> +	}
> +	mutex_unlock(&ref->mutex);
> +
> +	return idle;
> +}
> +
>   int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
>   					    struct intel_engine_cs *engine)
>   {
> @@ -352,22 +384,29 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
>   
>   	GEM_BUG_ON(!engine->mask);
>   	for_each_engine_masked(engine, i915, engine->mask, tmp) {
> -		struct intel_context *kctx = engine->kernel_context;
>   		struct active_node *node;
>   
> -		node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
> -		if (unlikely(!node)) {
> -			err = -ENOMEM;
> -			goto unwind;
> +		node = idle_barrier(ref);
> +		if (!node) {
> +			node = kmem_cache_alloc(global.slab_cache,
> +						GFP_KERNEL |
> +						__GFP_RETRY_MAYFAIL |
> +						__GFP_NOWARN);
> +			if (unlikely(!node)) {
> +				err = -ENOMEM;
> +				goto unwind;
> +			}
> +
> +			node->ref = ref;
> +			node->timeline = 0;
> +			node->base.retire = node_retire;
>   		}
>   
> -		i915_active_request_init(&node->base,
> -					 (void *)engine, node_retire);
> -		node->timeline = kctx->ring->timeline->fence_context;
> -		node->ref = ref;
> +		intel_engine_pm_get(engine);
> +
> +		RCU_INIT_POINTER(node->base.request, (void *)engine);
>   		atomic_inc(&ref->count);
>   
> -		intel_engine_pm_get(engine);
>   		llist_add((struct llist_node *)&node->base.link,
>   			  &ref->barriers);
>   	}
> @@ -402,6 +441,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
>   
>   		node = container_of((struct list_head *)pos,
>   				    typeof(*node), base.link);
> +		GEM_BUG_ON(node->timeline);
>   
>   		engine = (void *)rcu_access_pointer(node->base.request);
>   		RCU_INIT_POINTER(node->base.request, ERR_PTR(-EAGAIN));
> @@ -410,12 +450,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
>   		p = &ref->tree.rb_node;
>   		while (*p) {
>   			parent = *p;
> -			if (rb_entry(parent,
> -				     struct active_node,
> -				     node)->timeline < node->timeline)
> -				p = &parent->rb_right;
> -			else
> -				p = &parent->rb_left;
> +			p = &parent->rb_left;
>   		}
>   		rb_link_node(&node->node, parent, p);
>   		rb_insert_color(&node->node, &ref->tree);
> diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> index 2b31a4ee0b4c..a841d3f9bedc 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> @@ -15,6 +15,7 @@ selftest(workarounds, intel_workarounds_live_selftests)
>   selftest(timelines, intel_timeline_live_selftests)
>   selftest(requests, i915_request_live_selftests)
>   selftest(active, i915_active_live_selftests)
> +selftest(gt_contexts, intel_context_live_selftests)
>   selftest(objects, i915_gem_object_live_selftests)
>   selftest(mman, i915_gem_mman_live_selftests)
>   selftest(dmabuf, i915_gem_dmabuf_live_selftests)
> @@ -24,7 +25,7 @@ selftest(gtt, i915_gem_gtt_live_selftests)
>   selftest(gem, i915_gem_live_selftests)
>   selftest(evict, i915_gem_evict_live_selftests)
>   selftest(hugepages, i915_gem_huge_page_live_selftests)
> -selftest(contexts, i915_gem_context_live_selftests)
> +selftest(gem_contexts, i915_gem_context_live_selftests)
>   selftest(blt, i915_gem_object_blt_live_selftests)
>   selftest(client, i915_gem_client_blt_live_selftests)
>   selftest(reset, intel_reset_live_selftests)


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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev4)
  2019-07-25  7:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
                   ` (2 preceding siblings ...)
  2019-07-25  9:38 ` [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
@ 2019-07-25 11:23 ` Patchwork
  2019-07-25 11:44 ` ✓ Fi.CI.BAT: success " Patchwork
  2019-07-25 17:53 ` ✓ Fi.CI.IGT: " Patchwork
  5 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2019-07-25 11:23 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Unshare the idle-barrier from other kernel requests (rev4)
URL   : https://patchwork.freedesktop.org/series/64171/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
7e8e9ad5e045 drm/i915: Unshare the idle-barrier from other kernel requests
-:115: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#115: 
new file mode 100644

-:120: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#120: FILE: drivers/gpu/drm/i915/gt/selftest_context.c:1:
+/*

-:121: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#121: FILE: drivers/gpu/drm/i915/gt/selftest_context.c:2:
+ * SPDX-License-Identifier: GPL-2.0

-:374: WARNING:LONG_LINE: line over 100 characters
#374: FILE: drivers/gpu/drm/i915/gt/selftest_context.c:255:
+			pr_err("remote context is not active; expected idle-barrier (pass %d)\n", pass);

total: 0 errors, 4 warnings, 0 checks, 529 lines checked

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: Unshare the idle-barrier from other kernel requests (rev4)
  2019-07-25  7:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
                   ` (3 preceding siblings ...)
  2019-07-25 11:23 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev4) Patchwork
@ 2019-07-25 11:44 ` Patchwork
  2019-07-25 11:48   ` Chris Wilson
  2019-07-25 17:53 ` ✓ Fi.CI.IGT: " Patchwork
  5 siblings, 1 reply; 13+ messages in thread
From: Patchwork @ 2019-07-25 11:44 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Unshare the idle-barrier from other kernel requests (rev4)
URL   : https://patchwork.freedesktop.org/series/64171/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_6549 -> Patchwork_13746
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_13746:

### IGT changes ###

#### Possible regressions ####

  * {igt@i915_selftest@live_gt_contexts} (NEW):
    - fi-hsw-4770r:       NOTRUN -> [DMESG-FAIL][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-hsw-4770r/igt@i915_selftest@live_gt_contexts.html
    - fi-pnv-d510:        NOTRUN -> [DMESG-FAIL][2]
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-pnv-d510/igt@i915_selftest@live_gt_contexts.html
    - fi-blb-e6850:       NOTRUN -> [DMESG-FAIL][3]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-blb-e6850/igt@i915_selftest@live_gt_contexts.html
    - fi-byt-j1900:       NOTRUN -> [DMESG-FAIL][4]
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-byt-j1900/igt@i915_selftest@live_gt_contexts.html
    - fi-elk-e7500:       NOTRUN -> [DMESG-FAIL][5]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-elk-e7500/igt@i915_selftest@live_gt_contexts.html
    - fi-snb-2600:        NOTRUN -> [DMESG-FAIL][6]
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-snb-2600/igt@i915_selftest@live_gt_contexts.html
    - fi-byt-n2820:       NOTRUN -> [DMESG-FAIL][7]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-byt-n2820/igt@i915_selftest@live_gt_contexts.html
    - fi-gdg-551:         NOTRUN -> [DMESG-FAIL][8]
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-gdg-551/igt@i915_selftest@live_gt_contexts.html
    - fi-hsw-peppy:       NOTRUN -> [DMESG-FAIL][9]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-hsw-peppy/igt@i915_selftest@live_gt_contexts.html
    - fi-snb-2520m:       NOTRUN -> [DMESG-FAIL][10]
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-snb-2520m/igt@i915_selftest@live_gt_contexts.html
    - fi-ilk-650:         NOTRUN -> [DMESG-FAIL][11]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-ilk-650/igt@i915_selftest@live_gt_contexts.html
    - fi-ivb-3770:        NOTRUN -> [DMESG-FAIL][12]
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-ivb-3770/igt@i915_selftest@live_gt_contexts.html
    - fi-hsw-4770:        NOTRUN -> [DMESG-FAIL][13]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-hsw-4770/igt@i915_selftest@live_gt_contexts.html

  
New tests
---------

  New tests have been introduced between CI_DRM_6549 and Patchwork_13746:

### New IGT tests (2) ###

  * igt@i915_selftest@live_gem_contexts:
    - Statuses : 41 pass(s)
    - Exec time: [0.37, 28.34] s

  * igt@i915_selftest@live_gt_contexts:
    - Statuses : 13 dmesg-fail(s) 1 incomplete(s) 28 pass(s)
    - Exec time: [0.0, 1.31] s

  

Known issues
------------

  Here are the changes found in Patchwork_13746 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_busy@basic-flip-a:
    - fi-kbl-7567u:       [PASS][14] -> [SKIP][15] ([fdo#109271] / [fdo#109278]) +2 similar issues
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/fi-kbl-7567u/igt@kms_busy@basic-flip-a.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-kbl-7567u/igt@kms_busy@basic-flip-a.html

  * igt@prime_busy@basic-before-default:
    - fi-icl-u3:          [PASS][16] -> [DMESG-WARN][17] ([fdo#107724]) +1 similar issue
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/fi-icl-u3/igt@prime_busy@basic-before-default.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-icl-u3/igt@prime_busy@basic-before-default.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-blb-e6850:       [INCOMPLETE][18] ([fdo#107718]) -> [PASS][19]
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/fi-blb-e6850/igt@gem_exec_suspend@basic-s3.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-blb-e6850/igt@gem_exec_suspend@basic-s3.html

  * igt@i915_module_load@reload-with-fault-injection:
    - fi-snb-2600:        [INCOMPLETE][20] ([fdo#105411]) -> [PASS][21]
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/fi-snb-2600/igt@i915_module_load@reload-with-fault-injection.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-snb-2600/igt@i915_module_load@reload-with-fault-injection.html
    - fi-snb-2520m:       [INCOMPLETE][22] -> [PASS][23]
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/fi-snb-2520m/igt@i915_module_load@reload-with-fault-injection.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-snb-2520m/igt@i915_module_load@reload-with-fault-injection.html

  * igt@kms_chamelium@common-hpd-after-suspend:
    - fi-kbl-7567u:       [WARN][24] ([fdo#109380]) -> [PASS][25]
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/fi-kbl-7567u/igt@kms_chamelium@common-hpd-after-suspend.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-kbl-7567u/igt@kms_chamelium@common-hpd-after-suspend.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-c:
    - fi-kbl-7567u:       [SKIP][26] ([fdo#109271]) -> [PASS][27] +23 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/fi-kbl-7567u/igt@kms_pipe_crc_basic@read-crc-pipe-c.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-kbl-7567u/igt@kms_pipe_crc_basic@read-crc-pipe-c.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#105411]: https://bugs.freedesktop.org/show_bug.cgi?id=105411
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
  [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109380]: https://bugs.freedesktop.org/show_bug.cgi?id=109380


Participating hosts (54 -> 44)
------------------------------

  Missing    (10): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-icl-u2 fi-bsw-cyan fi-ctg-p8600 fi-byt-clapper fi-icl-y fi-icl-dsi fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_6549 -> Patchwork_13746

  CI-20190529: 20190529
  CI_DRM_6549: b3ff1a4436815b4baf26a73dccfa71527a2bfc4e @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5110: 9085f552a11156c5b856593361b30606a9424c01 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_13746: 7e8e9ad5e04512df6232dfba871029a25a0a0ce9 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

7e8e9ad5e045 drm/i915: Unshare the idle-barrier from other kernel requests

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: ✓ Fi.CI.BAT: success for drm/i915: Unshare the idle-barrier from other kernel requests (rev4)
  2019-07-25 11:44 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2019-07-25 11:48   ` Chris Wilson
  0 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2019-07-25 11:48 UTC (permalink / raw)
  To: Patchwork; +Cc: intel-gfx

Quoting Patchwork (2019-07-25 12:44:16)
> == Series Details ==
> 
> Series: drm/i915: Unshare the idle-barrier from other kernel requests (rev4)
> URL   : https://patchwork.freedesktop.org/series/64171/
> State : success
> 
> == Summary ==
> 
> CI Bug Log - changes from CI_DRM_6549 -> Patchwork_13746
> ====================================================
> 
> Summary
> -------
> 
>   **SUCCESS**
> 
> #### Possible regressions ####
> 
>   * {igt@i915_selftest@live_gt_contexts} (NEW):
>     - fi-hsw-4770r:       NOTRUN -> [DMESG-FAIL][1]
>    [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/fi-hsw-4770r/igt@i915_selftest@live_gt_contexts.html

I like your thinking CI!
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests
  2019-07-25  9:38 ` [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
  2019-07-25 10:26   ` Lionel Landwerlin
@ 2019-07-25 13:19   ` Tvrtko Ursulin
  2019-07-25 13:26     ` Chris Wilson
  1 sibling, 1 reply; 13+ messages in thread
From: Tvrtko Ursulin @ 2019-07-25 13:19 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 25/07/2019 10:38, Chris Wilson wrote:
> Under some circumstances (see intel_context_prepare_remote_request), we
> may use a request along a kernel context to modify the logical state of
> another. To keep the target context in place while the request executes,
> we take an active reference on it using the kernel timeline. This is the
> same timeline as we use for the idle-barrier, and so we end up reusing
> the same active node. Except that the idle barrier is special and cannot
> be reused in this manner! Give the idle-barrier a reserved timeline
> index (0) so that it will always be unique (give or take we may issue
> multiple idle barriers across multiple engines).
> 
> Reported-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Fixes: ce476c80b8bf ("drm/i915: Keep contexts pinned until after the next kernel context switch")
> Fixes: a9877da2d629 ("drm/i915/oa: Reconfigure contexts on the fly")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
>   drivers/gpu/drm/i915/gt/intel_context.c       |  42 ++-
>   drivers/gpu/drm/i915/gt/intel_context.h       |  13 +-
>   drivers/gpu/drm/i915/gt/selftest_context.c    | 321 ++++++++++++++++++
>   drivers/gpu/drm/i915/i915_active.c            |  67 +++-
>   .../drm/i915/selftests/i915_live_selftests.h  |   3 +-
>   5 files changed, 408 insertions(+), 38 deletions(-)
>   create mode 100644 drivers/gpu/drm/i915/gt/selftest_context.c
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
> index 9292b6ca5e9c..bc20161bab9f 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -162,18 +162,8 @@ static int __intel_context_active(struct i915_active *active)
>   	if (err)
>   		goto err_ring;
>   
> -	/* Preallocate tracking nodes */
> -	if (!i915_gem_context_is_kernel(ce->gem_context)) {
> -		err = i915_active_acquire_preallocate_barrier(&ce->active,
> -							      ce->engine);
> -		if (err)
> -			goto err_state;
> -	}
> -
>   	return 0;
>   
> -err_state:
> -	__context_unpin_state(ce->state);
>   err_ring:
>   	intel_ring_unpin(ce->ring);
>   err_put:
> @@ -181,6 +171,34 @@ static int __intel_context_active(struct i915_active *active)
>   	return err;
>   }
>   
> +int intel_context_active_acquire(struct intel_context *ce)
> +{
> +	int err;
> +
> +	err = i915_active_acquire(&ce->active);
> +	if (err)
> +		return err;
> +
> +	/* Preallocate tracking nodes */
> +	if (ce->state && !i915_gem_context_is_kernel(ce->gem_context)) {
> +		err = i915_active_acquire_preallocate_barrier(&ce->active,
> +							      ce->engine);
> +		if (err) {
> +			i915_active_release(&ce->active);
> +			return err;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +void intel_context_active_release(struct intel_context *ce)
> +{
> +	/* Nodes preallocated in intel_context_active() */
> +	i915_active_acquire_barrier(&ce->active);
> +	i915_active_release(&ce->active);
> +}
> +
>   void
>   intel_context_init(struct intel_context *ce,
>   		   struct i915_gem_context *ctx,
> @@ -284,3 +302,7 @@ struct i915_request *intel_context_create_request(struct intel_context *ce)
>   
>   	return rq;
>   }
> +
> +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> +#include "selftest_context.c"
> +#endif
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
> index 23c7e4c0ce7c..07f9924de48f 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.h
> +++ b/drivers/gpu/drm/i915/gt/intel_context.h
> @@ -104,17 +104,8 @@ static inline void intel_context_exit(struct intel_context *ce)
>   		ce->ops->exit(ce);
>   }
>   
> -static inline int intel_context_active_acquire(struct intel_context *ce)
> -{
> -	return i915_active_acquire(&ce->active);
> -}
> -
> -static inline void intel_context_active_release(struct intel_context *ce)
> -{
> -	/* Nodes preallocated in intel_context_active() */
> -	i915_active_acquire_barrier(&ce->active);
> -	i915_active_release(&ce->active);
> -}
> +int intel_context_active_acquire(struct intel_context *ce);
> +void intel_context_active_release(struct intel_context *ce);
>   
>   static inline struct intel_context *intel_context_get(struct intel_context *ce)
>   {
> diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c
> new file mode 100644
> index 000000000000..4d251faafcc0
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/selftest_context.c
> @@ -0,0 +1,321 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0
> + *
> + * Copyright © 2019 Intel Corporation
> + */
> +
> +#include "i915_selftest.h"
> +#include "intel_gt.h"
> +
> +#include "gem/selftests/mock_context.h"
> +#include "selftests/igt_flush_test.h"
> +#include "selftests/mock_drm.h"
> +
> +static int request_sync(struct i915_request *rq)
> +{
> +	long timeout;
> +	int err = 0;
> +
> +	i915_request_get(rq);
> +
> +	i915_request_add(rq);
> +	timeout = i915_request_wait(rq, 0, HZ / 10);
> +	if (timeout < 0)
> +		err = timeout;
> +	else
> +		i915_request_retire_upto(rq);
> +
> +	i915_request_put(rq);
> +
> +	return err;
> +}
> +
> +static int context_sync(struct intel_context *ce)
> +{
> +	struct intel_timeline *tl = ce->ring->timeline;
> +	int err = 0;
> +
> +	do {
> +		struct i915_request *rq;
> +		long timeout;
> +
> +		rcu_read_lock();
> +		rq = rcu_dereference(tl->last_request.request);
> +		if (rq)
> +			rq = i915_request_get_rcu(rq);
> +		rcu_read_unlock();
> +		if (!rq)
> +			break;
> +
> +		timeout = i915_request_wait(rq, 0, HZ / 10);
> +		if (timeout < 0)
> +			err = timeout;
> +		else
> +			i915_request_retire_upto(rq);
> +
> +		i915_request_put(rq);
> +	} while (!err);
> +
> +	return err;
> +}
> +
> +static int __live_active_context(struct intel_engine_cs *engine,
> +				 struct i915_gem_context *fixme)
> +{
> +	struct intel_context *ce;
> +	int pass;
> +	int err;
> +
> +	/*
> +	 * We keep active contexts alive until after a subsequent context
> +	 * switch as the final write from the context-save will be after
> +	 * we retire the final request. We track when we unpin the context,
> +	 * under the presumption that the final pin is from the last request,
> +	 * and instead of immediately unpinning the context, we add a task
> +	 * to unpin the context from the next idle-barrier.
> +	 *
> +	 * This test makes sure that the context is kept alive until a
> +	 * subsequent idle-barrier (emitted when the engine wakeref hits 0
> +	 * with no more outstanding requests).
> +	 */
> +
> +	if (intel_engine_pm_is_awake(engine)) {
> +		pr_err("%s is awake before starting %s!\n",
> +		       engine->name, __func__);
> +		return -EINVAL;
> +	}
> +
> +	ce = intel_context_create(fixme, engine);
> +	if (!ce)
> +		return -ENOMEM;
> +
> +	for (pass = 0; pass <= 2; pass++) {
> +		struct i915_request *rq;
> +
> +		rq = intel_context_create_request(ce);
> +		if (IS_ERR(rq)) {
> +			err = PTR_ERR(rq);
> +			goto err;
> +		}
> +
> +		err = request_sync(rq);
> +		if (err)
> +			goto err;
> +
> +		/* Context will be kept active until after an idle-barrier. */
> +		if (i915_active_is_idle(&ce->active)) {
> +			pr_err("context is not active; expected idle-barrier (pass %d)\n", pass);
> +			err = -EINVAL;
> +			goto err;
> +		}
> +
> +		if (!intel_engine_pm_is_awake(engine)) {
> +			pr_err("%s is asleep before idle-barrier %s!\n",
> +			       engine->name, __func__);
> +			err = -EINVAL;
> +			goto err;
> +		}
> +	}
> +
> +	/* Now make sure our idle-barriers are flushed */
> +	err = context_sync(engine->kernel_context);
> +	if (err)
> +		goto err;
> +
> +	if (!i915_active_is_idle(&ce->active)) {
> +		pr_err("context is still active!");
> +		err = -EINVAL;
> +	}
> +
> +	if (intel_engine_pm_is_awake(engine)) {
> +		struct drm_printer p = drm_debug_printer(__func__);
> +
> +		intel_engine_dump(engine, &p,
> +				  "%s is still awake after idle-barriers\n",
> +				  engine->name);
> +		GEM_TRACE_DUMP();
> +
> +		err = -EINVAL;
> +		goto err;
> +	}
> +
> +err:
> +	intel_context_put(ce);
> +	return err;
> +}
> +
> +static int live_active_context(void *arg)
> +{
> +	struct intel_gt *gt = arg;
> +	struct intel_engine_cs *engine;
> +	struct i915_gem_context *fixme;
> +	enum intel_engine_id id;
> +	struct drm_file *file;
> +	int err = 0;
> +
> +	file = mock_file(gt->i915);
> +	if (IS_ERR(file))
> +		return PTR_ERR(file);
> +
> +	mutex_lock(&gt->i915->drm.struct_mutex);
> +
> +	fixme = live_context(gt->i915, file);
> +	if (!fixme) {
> +		err = -ENOMEM;
> +		goto unlock;
> +	}
> +
> +	for_each_engine(engine, gt->i915, id) {
> +		err = __live_active_context(engine, fixme);
> +		if (err)
> +			break;
> +
> +		err = igt_flush_test(gt->i915, I915_WAIT_LOCKED);
> +		if (err)
> +			break;
> +	}
> +
> +unlock:
> +	mutex_unlock(&gt->i915->drm.struct_mutex);
> +	mock_file_free(gt->i915, file);
> +	return err;
> +}
> +
> +static int __live_remote_context(struct intel_engine_cs *engine,
> +				 struct i915_gem_context *fixme)
> +{
> +	struct intel_context *local, *remote;
> +	struct i915_request *rq;
> +	int pass;
> +	int err;
> +
> +	/*
> +	 * Check that our idle barriers do not interfere with normal
> +	 * activity tracking. In particular, check that operating
> +	 * on the context image remotely (intel_context_prepare_remote_request)
> +	 * which inserts foriegn fences into intel_context.active are not
> +	 * clobbered.
> +	 */
> +
> +	remote = intel_context_create(fixme, engine);
> +	if (!remote)
> +		return -ENOMEM;
> +
> +	local = intel_context_create(fixme, engine);
> +	if (!local) {
> +		err = -ENOMEM;
> +		goto err_remote;
> +	}
> +
> +	for (pass = 0; pass <= 2; pass++) {
> +		err = intel_context_pin(remote);
> +		if (err)
> +			goto err_local;
> +
> +		rq = intel_context_create_request(local);
> +		if (IS_ERR(rq)) {
> +			err = PTR_ERR(rq);
> +			goto err_unpin;
> +		}
> +
> +		err = intel_context_prepare_remote_request(remote, rq);
> +		if (err) {
> +			i915_request_add(rq);
> +			goto err_unpin;
> +		}
> +
> +		err = request_sync(rq);
> +		if (err)
> +			goto err_unpin;
> +
> +		intel_context_unpin(remote);
> +		err = intel_context_pin(remote);
> +		if (err)
> +			goto err_local;
> +
> +		rq = i915_request_create(engine->kernel_context);
> +		if (IS_ERR(rq)) {
> +			err = PTR_ERR(rq);
> +			goto err_unpin;
> +		}
> +
> +		err = intel_context_prepare_remote_request(remote, rq);
> +		if (err) {
> +			i915_request_add(rq);
> +			goto err_unpin;
> +		}
> +
> +		err = request_sync(rq);
> +		if (err)
> +			goto err_unpin;
> +
> +		intel_context_unpin(remote);
> +
> +		if (i915_active_is_idle(&remote->active)) {
> +			pr_err("remote context is not active; expected idle-barrier (pass %d)\n", pass);
> +			err = -EINVAL;
> +			goto err_local;
> +		}
> +	}
> +
> +	goto err_local;
> +
> +err_unpin:
> +	intel_context_unpin(remote);
> +err_local:
> +	intel_context_put(local);
> +err_remote:
> +	intel_context_put(remote);
> +	return err;
> +}
> +
> +static int live_remote_context(void *arg)
> +{
> +	struct intel_gt *gt = arg;
> +	struct intel_engine_cs *engine;
> +	struct i915_gem_context *fixme;
> +	enum intel_engine_id id;
> +	struct drm_file *file;
> +	int err = 0;
> +
> +	file = mock_file(gt->i915);
> +	if (IS_ERR(file))
> +		return PTR_ERR(file);
> +
> +	mutex_lock(&gt->i915->drm.struct_mutex);
> +
> +	fixme = live_context(gt->i915, file);
> +	if (!fixme) {
> +		err = -ENOMEM;
> +		goto unlock;
> +	}
> +
> +	for_each_engine(engine, gt->i915, id) {
> +		err = __live_remote_context(engine, fixme);
> +		if (err)
> +			break;
> +
> +		err = igt_flush_test(gt->i915, I915_WAIT_LOCKED);
> +		if (err)
> +			break;
> +	}
> +
> +unlock:
> +	mutex_unlock(&gt->i915->drm.struct_mutex);
> +	mock_file_free(gt->i915, file);
> +	return err;
> +}
> +
> +int intel_context_live_selftests(struct drm_i915_private *i915)
> +{
> +	static const struct i915_subtest tests[] = {
> +		SUBTEST(live_active_context),
> +		SUBTEST(live_remote_context),
> +	};
> +	struct intel_gt *gt = &i915->gt;
> +
> +	if (intel_gt_is_wedged(gt))
> +		return 0;
> +
> +	return intel_gt_live_subtests(tests, gt);
> +}
> diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
> index 13f304a29fc8..e04afb519264 100644
> --- a/drivers/gpu/drm/i915/i915_active.c
> +++ b/drivers/gpu/drm/i915/i915_active.c
> @@ -184,6 +184,7 @@ active_instance(struct i915_active *ref, u64 idx)
>   	ref->cache = node;
>   	mutex_unlock(&ref->mutex);
>   
> +	BUILD_BUG_ON(offsetof(typeof(*node), base));
>   	return &node->base;
>   }
>   
> @@ -212,6 +213,8 @@ int i915_active_ref(struct i915_active *ref,
>   	struct i915_active_request *active;
>   	int err;
>   
> +	GEM_BUG_ON(!timeline); /* reserved for idle-barrier */
> +
>   	/* Prevent reaping in case we malloc/wait while building the tree */
>   	err = i915_active_acquire(ref);
>   	if (err)
> @@ -222,6 +225,7 @@ int i915_active_ref(struct i915_active *ref,
>   		err = -ENOMEM;
>   		goto out;
>   	}
> +	GEM_BUG_ON(IS_ERR(active->request));
>   
>   	if (!i915_active_request_isset(active))
>   		atomic_inc(&ref->count);
> @@ -342,6 +346,34 @@ void i915_active_fini(struct i915_active *ref)
>   }
>   #endif
>   
> +static struct active_node *idle_barrier(struct i915_active *ref)
> +{
> +	struct active_node *idle = NULL;
> +	struct rb_node *rb;
> +
> +	if (RB_EMPTY_ROOT(&ref->tree))
> +		return NULL;
> +
> +	mutex_lock(&ref->mutex);
> +	for (rb = rb_first(&ref->tree); rb; rb = rb_next(rb)) {
> +		struct active_node *node;
> +
> +		node = rb_entry(rb, typeof(*node), node);
> +		if (node->timeline)
> +			break;

I think the code needs to be more explicit for readability. Special 
timeline value zero at least as a #define. Plus some comments.

> +
> +		if (!i915_active_request_isset(&node->base)) {
> +			GEM_BUG_ON(!list_empty(&node->base.link));
> +			rb_erase(rb, &ref->tree);
> +			idle = node;
> +			break;
> +		}
> +	}
> +	mutex_unlock(&ref->mutex);
> +
> +	return idle;
> +}
> +
>   int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
>   					    struct intel_engine_cs *engine)
>   {
> @@ -352,22 +384,29 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
>   
>   	GEM_BUG_ON(!engine->mask);
>   	for_each_engine_masked(engine, i915, engine->mask, tmp) {
> -		struct intel_context *kctx = engine->kernel_context;
>   		struct active_node *node;
>   
> -		node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
> -		if (unlikely(!node)) {
> -			err = -ENOMEM;
> -			goto unwind;
> +		node = idle_barrier(ref);
> +		if (!node) {
> +			node = kmem_cache_alloc(global.slab_cache,
> +						GFP_KERNEL |
> +						__GFP_RETRY_MAYFAIL |
> +						__GFP_NOWARN);
> +			if (unlikely(!node)) {
> +				err = -ENOMEM;
> +				goto unwind;
> +			}
> +
> +			node->ref = ref;
> +			node->timeline = 0;
> +			node->base.retire = node_retire;
>   		}
>   
> -		i915_active_request_init(&node->base,
> -					 (void *)engine, node_retire);
> -		node->timeline = kctx->ring->timeline->fence_context;
> -		node->ref = ref;
> +		intel_engine_pm_get(engine);

AFAIU this could comfortably be moved last instead of going even higher 
with this patch.

> +
> +		RCU_INIT_POINTER(node->base.request, (void *)engine);

What happens with the engine in request slot? Nothing if there is no 
retire hook set? But who uses it then?

>   		atomic_inc(&ref->count);
>   
> -		intel_engine_pm_get(engine);
>   		llist_add((struct llist_node *)&node->base.link,
>   			  &ref->barriers);
>   	}
> @@ -402,6 +441,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
>   
>   		node = container_of((struct list_head *)pos,
>   				    typeof(*node), base.link);
> +		GEM_BUG_ON(node->timeline);
>   
>   		engine = (void *)rcu_access_pointer(node->base.request);
>   		RCU_INIT_POINTER(node->base.request, ERR_PTR(-EAGAIN));
> @@ -410,12 +450,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
>   		p = &ref->tree.rb_node;
>   		while (*p) {
>   			parent = *p;
> -			if (rb_entry(parent,
> -				     struct active_node,
> -				     node)->timeline < node->timeline)
> -				p = &parent->rb_right;
> -			else
> -				p = &parent->rb_left;
> +			p = &parent->rb_left;

I don't get this hunk at all - how can it be okay to ignore the timeline 
value. Is this the buggy bit you mentioned on IRC?

First pass, I'll come back later.

Regards,

Tvrtko

>   		}
>   		rb_link_node(&node->node, parent, p);
>   		rb_insert_color(&node->node, &ref->tree);
> diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> index 2b31a4ee0b4c..a841d3f9bedc 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> @@ -15,6 +15,7 @@ selftest(workarounds, intel_workarounds_live_selftests)
>   selftest(timelines, intel_timeline_live_selftests)
>   selftest(requests, i915_request_live_selftests)
>   selftest(active, i915_active_live_selftests)
> +selftest(gt_contexts, intel_context_live_selftests)
>   selftest(objects, i915_gem_object_live_selftests)
>   selftest(mman, i915_gem_mman_live_selftests)
>   selftest(dmabuf, i915_gem_dmabuf_live_selftests)
> @@ -24,7 +25,7 @@ selftest(gtt, i915_gem_gtt_live_selftests)
>   selftest(gem, i915_gem_live_selftests)
>   selftest(evict, i915_gem_evict_live_selftests)
>   selftest(hugepages, i915_gem_huge_page_live_selftests)
> -selftest(contexts, i915_gem_context_live_selftests)
> +selftest(gem_contexts, i915_gem_context_live_selftests)
>   selftest(blt, i915_gem_object_blt_live_selftests)
>   selftest(client, i915_gem_client_blt_live_selftests)
>   selftest(reset, intel_reset_live_selftests)
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests
  2019-07-25 13:19   ` Tvrtko Ursulin
@ 2019-07-25 13:26     ` Chris Wilson
  0 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2019-07-25 13:26 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2019-07-25 14:19:22)
> 
> On 25/07/2019 10:38, Chris Wilson wrote:
> > @@ -352,22 +384,29 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
> >   
> >       GEM_BUG_ON(!engine->mask);
> >       for_each_engine_masked(engine, i915, engine->mask, tmp) {
> > -             struct intel_context *kctx = engine->kernel_context;
> >               struct active_node *node;
> >   
> > -             node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
> > -             if (unlikely(!node)) {
> > -                     err = -ENOMEM;
> > -                     goto unwind;
> > +             node = idle_barrier(ref);
> > +             if (!node) {
> > +                     node = kmem_cache_alloc(global.slab_cache,
> > +                                             GFP_KERNEL |
> > +                                             __GFP_RETRY_MAYFAIL |
> > +                                             __GFP_NOWARN);
> > +                     if (unlikely(!node)) {
> > +                             err = -ENOMEM;
> > +                             goto unwind;
> > +                     }
> > +
> > +                     node->ref = ref;
> > +                     node->timeline = 0;
> > +                     node->base.retire = node_retire;
> >               }
> >   
> > -             i915_active_request_init(&node->base,
> > -                                      (void *)engine, node_retire);
> > -             node->timeline = kctx->ring->timeline->fence_context;
> > -             node->ref = ref;
> > +             intel_engine_pm_get(engine);
> 
> AFAIU this could comfortably be moved last instead of going even higher 
> with this patch.

Sure, the wakeref is pinned by the caller this acquires one for the
barrier. I moved it out of the way as I felt grouping the linkage of the
preallocated barrier was more interesting.
 
> > +
> > +             RCU_INIT_POINTER(node->base.request, (void *)engine);
> 
> What happens with the engine in request slot? Nothing if there is no 
> retire hook set? But who uses it then?

We're just stashing a pointer back to the engine in an unused location.

> 
> >               atomic_inc(&ref->count);
> >   
> > -             intel_engine_pm_get(engine);
> >               llist_add((struct llist_node *)&node->base.link,
> >                         &ref->barriers);
> >       }
> > @@ -402,6 +441,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
> >   
> >               node = container_of((struct list_head *)pos,
> >                                   typeof(*node), base.link);
> > +             GEM_BUG_ON(node->timeline);
> >   
> >               engine = (void *)rcu_access_pointer(node->base.request);
> >               RCU_INIT_POINTER(node->base.request, ERR_PTR(-EAGAIN));
> > @@ -410,12 +450,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
> >               p = &ref->tree.rb_node;
> >               while (*p) {
> >                       parent = *p;
> > -                     if (rb_entry(parent,
> > -                                  struct active_node,
> > -                                  node)->timeline < node->timeline)
> > -                             p = &parent->rb_right;
> > -                     else
> > -                             p = &parent->rb_left;
> > +                     p = &parent->rb_left;
> 
> I don't get this hunk at all - how can it be okay to ignore the timeline 
> value. Is this the buggy bit you mentioned on IRC?

We don't ignore, we know it's 0.

No, the bug is whether or not the ppGTT counts as part of the pinned
state for the legacy ringbuffer. Currently we do not and my selftest
required that we always insert an idle-barrier after use. Erring on the
side of safety says we should always utilise the idle-barriers.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* ✓ Fi.CI.IGT: success for drm/i915: Unshare the idle-barrier from other kernel requests (rev4)
  2019-07-25  7:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
                   ` (4 preceding siblings ...)
  2019-07-25 11:44 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2019-07-25 17:53 ` Patchwork
  5 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2019-07-25 17:53 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Unshare the idle-barrier from other kernel requests (rev4)
URL   : https://patchwork.freedesktop.org/series/64171/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_6549_full -> Patchwork_13746_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_13746_full:

### IGT changes ###

#### Possible regressions ####

  * {igt@i915_selftest@live_gt_contexts} (NEW):
    - shard-hsw:          NOTRUN -> [DMESG-FAIL][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-hsw2/igt@i915_selftest@live_gt_contexts.html
    - shard-snb:          NOTRUN -> [DMESG-FAIL][2]
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-snb5/igt@i915_selftest@live_gt_contexts.html

  
New tests
---------

  New tests have been introduced between CI_DRM_6549_full and Patchwork_13746_full:

### New IGT tests (2) ###

  * igt@i915_selftest@live_gem_contexts:
    - Statuses : 7 pass(s)
    - Exec time: [5.06, 34.34] s

  * igt@i915_selftest@live_gt_contexts:
    - Statuses : 2 dmesg-fail(s) 5 pass(s)
    - Exec time: [0.39, 2.33] s

  

Known issues
------------

  Here are the changes found in Patchwork_13746_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_isolation@rcs0-s3:
    - shard-skl:          [PASS][3] -> [INCOMPLETE][4] ([fdo#104108])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-skl10/igt@gem_ctx_isolation@rcs0-s3.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-skl4/igt@gem_ctx_isolation@rcs0-s3.html

  * igt@i915_pm_rpm@i2c:
    - shard-hsw:          [PASS][5] -> [FAIL][6] ([fdo#104097])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-hsw4/igt@i915_pm_rpm@i2c.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-hsw2/igt@i915_pm_rpm@i2c.html

  * igt@i915_suspend@debugfs-reader:
    - shard-apl:          [PASS][7] -> [DMESG-WARN][8] ([fdo#108566])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-apl3/igt@i915_suspend@debugfs-reader.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-apl5/igt@i915_suspend@debugfs-reader.html

  * igt@kms_busy@basic-modeset-a:
    - shard-apl:          [PASS][9] -> [INCOMPLETE][10] ([fdo#103927])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-apl3/igt@kms_busy@basic-modeset-a.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-apl1/igt@kms_busy@basic-modeset-a.html

  * igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-gtt:
    - shard-iclb:         [PASS][11] -> [FAIL][12] ([fdo#103167]) +7 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-iclb2/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-gtt.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-iclb6/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-gtt.html

  * igt@kms_plane_lowres@pipe-a-tiling-y:
    - shard-iclb:         [PASS][13] -> [FAIL][14] ([fdo#103166])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-iclb2/igt@kms_plane_lowres@pipe-a-tiling-y.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-iclb4/igt@kms_plane_lowres@pipe-a-tiling-y.html

  * igt@kms_psr2_su@page_flip:
    - shard-iclb:         [PASS][15] -> [SKIP][16] ([fdo#109642] / [fdo#111068])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-iclb2/igt@kms_psr2_su@page_flip.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-iclb7/igt@kms_psr2_su@page_flip.html

  * igt@kms_psr@no_drrs:
    - shard-iclb:         [PASS][17] -> [FAIL][18] ([fdo#108341])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-iclb6/igt@kms_psr@no_drrs.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-iclb1/igt@kms_psr@no_drrs.html

  * igt@kms_psr@psr2_primary_page_flip:
    - shard-iclb:         [PASS][19] -> [SKIP][20] ([fdo#109441]) +5 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-iclb2/igt@kms_psr@psr2_primary_page_flip.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-iclb4/igt@kms_psr@psr2_primary_page_flip.html

  * igt@kms_setmode@basic:
    - shard-kbl:          [PASS][21] -> [FAIL][22] ([fdo#99912])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-kbl6/igt@kms_setmode@basic.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-kbl4/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-kbl:          [PASS][23] -> [DMESG-WARN][24] ([fdo#108566]) +5 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-kbl4/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-kbl3/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  
#### Possible fixes ####

  * igt@gem_tiled_swapping@non-threaded:
    - shard-kbl:          [DMESG-WARN][25] ([fdo#108686]) -> [PASS][26]
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-kbl3/igt@gem_tiled_swapping@non-threaded.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-kbl6/igt@gem_tiled_swapping@non-threaded.html

  * igt@i915_selftest@live_hangcheck:
    - shard-iclb:         [INCOMPLETE][27] ([fdo#107713] / [fdo#108569]) -> [PASS][28]
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-iclb7/igt@i915_selftest@live_hangcheck.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-iclb4/igt@i915_selftest@live_hangcheck.html

  * igt@kms_cursor_crc@pipe-b-cursor-suspend:
    - shard-kbl:          [DMESG-WARN][29] ([fdo#108566]) -> [PASS][30]
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-kbl3/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-kbl6/igt@kms_cursor_crc@pipe-b-cursor-suspend.html

  * igt@kms_cursor_crc@pipe-c-cursor-suspend:
    - shard-apl:          [DMESG-WARN][31] ([fdo#108566]) -> [PASS][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-apl5/igt@kms_cursor_crc@pipe-c-cursor-suspend.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-apl3/igt@kms_cursor_crc@pipe-c-cursor-suspend.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-hsw:          [INCOMPLETE][33] ([fdo#103540]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-hsw4/igt@kms_flip@flip-vs-suspend.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-hsw7/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-render:
    - shard-iclb:         [FAIL][35] ([fdo#103167]) -> [PASS][36] +10 similar issues
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-iclb6/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-render.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-iclb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-render.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min:
    - shard-skl:          [FAIL][37] ([fdo#108145]) -> [PASS][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-skl10/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-skl4/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html

  * igt@kms_psr@psr2_cursor_plane_move:
    - shard-iclb:         [SKIP][39] ([fdo#109441]) -> [PASS][40] +2 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-iclb8/igt@kms_psr@psr2_cursor_plane_move.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-iclb2/igt@kms_psr@psr2_cursor_plane_move.html

  * igt@perf@polling:
    - shard-skl:          [FAIL][41] ([fdo#110728]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-skl1/igt@perf@polling.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-skl4/igt@perf@polling.html

  * igt@perf@short-reads:
    - shard-kbl:          [FAIL][43] ([fdo#103183]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6549/shard-kbl6/igt@perf@short-reads.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/shard-kbl4/igt@perf@short-reads.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#103166]: https://bugs.freedesktop.org/show_bug.cgi?id=103166
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#103183]: https://bugs.freedesktop.org/show_bug.cgi?id=103183
  [fdo#103540]: https://bugs.freedesktop.org/show_bug.cgi?id=103540
  [fdo#103665]: https://bugs.freedesktop.org/show_bug.cgi?id=103665
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#104097]: https://bugs.freedesktop.org/show_bug.cgi?id=104097
  [fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#108341]: https://bugs.freedesktop.org/show_bug.cgi?id=108341
  [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
  [fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569
  [fdo#108686]: https://bugs.freedesktop.org/show_bug.cgi?id=108686
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110728]: https://bugs.freedesktop.org/show_bug.cgi?id=110728
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912


Participating hosts (9 -> 9)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_6549 -> Patchwork_13746

  CI-20190529: 20190529
  CI_DRM_6549: b3ff1a4436815b4baf26a73dccfa71527a2bfc4e @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5110: 9085f552a11156c5b856593361b30606a9424c01 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_13746: 7e8e9ad5e04512df6232dfba871029a25a0a0ce9 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13746/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests
  2019-07-24 12:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
@ 2019-07-24 12:50 ` Chris Wilson
  0 siblings, 0 replies; 13+ messages in thread
From: Chris Wilson @ 2019-07-24 12:50 UTC (permalink / raw)
  To: intel-gfx

Under some circumstances (see intel_context_prepare_remote_request), we
may use a request along a kernel context to modify the logical state of
another. To keep the target context in place while the request executes,
we take an active reference on it using the kernel timeline. This is the
same timeline as we use for the idle-barrier, and so we end up reusing
the same active node. Except that the idle barrier is special and cannot
be reused in this manner! Give the idle-barrier a reserved timeline
index (0) so that it will always be unique (give or take we may issue
multiple idle barriers across multiple engines).

Reported-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: ce476c80b8bf ("drm/i915: Keep contexts pinned until after the next kernel context switch")
Fixes: a9877da2d629 ("drm/i915/oa: Reconfigure contexts on the fly")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
Replace recursive attempt to acquire the i915_active.mutex with a
lockdep annotation.
---
 drivers/gpu/drm/i915/i915_active.c | 58 +++++++++++++++++++++---------
 1 file changed, 42 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 13f304a29fc8..99bebd77f364 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -184,6 +184,7 @@ active_instance(struct i915_active *ref, u64 idx)
 	ref->cache = node;
 	mutex_unlock(&ref->mutex);
 
+	BUILD_BUG_ON(offsetof(typeof(*node), base));
 	return &node->base;
 }
 
@@ -212,6 +213,8 @@ int i915_active_ref(struct i915_active *ref,
 	struct i915_active_request *active;
 	int err;
 
+	GEM_BUG_ON(!timeline); /* reserved for idle-barrier */
+
 	/* Prevent reaping in case we malloc/wait while building the tree */
 	err = i915_active_acquire(ref);
 	if (err)
@@ -342,6 +345,26 @@ void i915_active_fini(struct i915_active *ref)
 }
 #endif
 
+static struct active_node *idle_barrier(struct i915_active *ref)
+{
+	struct active_node *node;
+	struct rb_node *rb;
+
+	lockdep_assert_held(&ref->mutex);
+	rb = rb_first(&ref->tree);
+	if (!rb)
+		return NULL;
+
+	node = rb_entry(rb, typeof(*node), node);
+	if (node->timeline || i915_active_request_isset(&node->base))
+		return NULL;
+
+	GEM_BUG_ON(!list_empty(&node->base.link));
+	rb_erase(rb, &ref->tree);
+
+	return node;
+}
+
 int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
 					    struct intel_engine_cs *engine)
 {
@@ -352,22 +375,29 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
 
 	GEM_BUG_ON(!engine->mask);
 	for_each_engine_masked(engine, i915, engine->mask, tmp) {
-		struct intel_context *kctx = engine->kernel_context;
 		struct active_node *node;
 
-		node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
-		if (unlikely(!node)) {
-			err = -ENOMEM;
-			goto unwind;
+		node = idle_barrier(ref);
+		if (!node) {
+			node = kmem_cache_alloc(global.slab_cache,
+						GFP_KERNEL |
+						__GFP_RETRY_MAYFAIL |
+						__GFP_NOWARN);
+			if (unlikely(!node)) {
+				err = -ENOMEM;
+				goto unwind;
+			}
+
+			node->ref = ref;
+			node->timeline = 0;
+			node->base.retire = node_retire;
 		}
 
-		i915_active_request_init(&node->base,
-					 (void *)engine, node_retire);
-		node->timeline = kctx->ring->timeline->fence_context;
-		node->ref = ref;
+		intel_engine_pm_get(engine);
+
+		RCU_INIT_POINTER(node->base.request, (void *)engine);
 		atomic_inc(&ref->count);
 
-		intel_engine_pm_get(engine);
 		llist_add((struct llist_node *)&node->base.link,
 			  &ref->barriers);
 	}
@@ -402,6 +432,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 
 		node = container_of((struct list_head *)pos,
 				    typeof(*node), base.link);
+		GEM_BUG_ON(node->timeline);
 
 		engine = (void *)rcu_access_pointer(node->base.request);
 		RCU_INIT_POINTER(node->base.request, ERR_PTR(-EAGAIN));
@@ -410,12 +441,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 		p = &ref->tree.rb_node;
 		while (*p) {
 			parent = *p;
-			if (rb_entry(parent,
-				     struct active_node,
-				     node)->timeline < node->timeline)
-				p = &parent->rb_right;
-			else
-				p = &parent->rb_left;
+			p = &parent->rb_left;
 		}
 		rb_link_node(&node->node, parent, p);
 		rb_insert_color(&node->node, &ref->tree);
-- 
2.22.0

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests
@ 2019-07-24 12:43 Chris Wilson
  2019-07-24 12:50 ` Chris Wilson
  0 siblings, 1 reply; 13+ messages in thread
From: Chris Wilson @ 2019-07-24 12:43 UTC (permalink / raw)
  To: intel-gfx

Under some circumstances (see intel_context_prepare_remote_request), we
may use a requst along a kernel context to modify the logical state of
another. To keep the target context in place while the request executes,
we take an active reference on it using the kernel timeline. This is the
same timeline as we use for the idle-barrier, and so we end up reusing
the same active node. Except that the idle barrier is special and cannot
be reused in this manner! Give the idle-barrier a reserved timeline
index (0) so that is will always be unique (give or take we may issue
multiple idle barriers across multiple engines).

Reported-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: ce476c80b8bf ("drm/i915: Keep contexts pinned until after the next kernel context switch")
Fixes: a9877da2d629 ("drm/i915/oa: Reconfigure contexts on the fly")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/i915_active.c | 63 ++++++++++++++++++++++--------
 1 file changed, 47 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 13f304a29fc8..4f7f698bff15 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -184,6 +184,7 @@ active_instance(struct i915_active *ref, u64 idx)
 	ref->cache = node;
 	mutex_unlock(&ref->mutex);
 
+	BUILD_BUG_ON(offsetof(typeof(*node), base));
 	return &node->base;
 }
 
@@ -212,6 +213,8 @@ int i915_active_ref(struct i915_active *ref,
 	struct i915_active_request *active;
 	int err;
 
+	GEM_BUG_ON(!timeline); /* reserved for idle-barrier */
+
 	/* Prevent reaping in case we malloc/wait while building the tree */
 	err = i915_active_acquire(ref);
 	if (err)
@@ -342,6 +345,31 @@ void i915_active_fini(struct i915_active *ref)
 }
 #endif
 
+static struct active_node *idle_barrier(struct i915_active *ref)
+{
+	struct active_node *node = NULL;
+	struct rb_node *rb;
+
+	mutex_lock(&ref->mutex);
+
+	rb = rb_first(&ref->tree);
+	if (!rb)
+		goto unlock;
+
+	node = rb_entry(rb, typeof(*node), node);
+	if (node->timeline || i915_active_request_isset(&node->base)) {
+		node = NULL;
+		goto unlock;
+	}
+
+	GEM_BUG_ON(!list_empty(&node->base.link));
+	rb_erase(rb, &ref->tree);
+
+unlock:
+	mutex_unlock(&ref->mutex);
+	return node;
+}
+
 int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
 					    struct intel_engine_cs *engine)
 {
@@ -352,22 +380,29 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
 
 	GEM_BUG_ON(!engine->mask);
 	for_each_engine_masked(engine, i915, engine->mask, tmp) {
-		struct intel_context *kctx = engine->kernel_context;
 		struct active_node *node;
 
-		node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
-		if (unlikely(!node)) {
-			err = -ENOMEM;
-			goto unwind;
+		node = idle_barrier(ref);
+		if (!node) {
+			node = kmem_cache_alloc(global.slab_cache,
+						GFP_KERNEL |
+						__GFP_RETRY_MAYFAIL |
+						__GFP_NOWARN);
+			if (unlikely(!node)) {
+				err = -ENOMEM;
+				goto unwind;
+			}
+
+			node->ref = ref;
+			node->timeline = 0;
+			node->base.retire = node_retire;
 		}
 
-		i915_active_request_init(&node->base,
-					 (void *)engine, node_retire);
-		node->timeline = kctx->ring->timeline->fence_context;
-		node->ref = ref;
+		intel_engine_pm_get(engine);
+
+		RCU_INIT_POINTER(node->base.request, (void *)engine);
 		atomic_inc(&ref->count);
 
-		intel_engine_pm_get(engine);
 		llist_add((struct llist_node *)&node->base.link,
 			  &ref->barriers);
 	}
@@ -402,6 +437,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 
 		node = container_of((struct list_head *)pos,
 				    typeof(*node), base.link);
+		GEM_BUG_ON(node->timeline);
 
 		engine = (void *)rcu_access_pointer(node->base.request);
 		RCU_INIT_POINTER(node->base.request, ERR_PTR(-EAGAIN));
@@ -410,12 +446,7 @@ void i915_active_acquire_barrier(struct i915_active *ref)
 		p = &ref->tree.rb_node;
 		while (*p) {
 			parent = *p;
-			if (rb_entry(parent,
-				     struct active_node,
-				     node)->timeline < node->timeline)
-				p = &parent->rb_right;
-			else
-				p = &parent->rb_left;
+			p = &parent->rb_left;
 		}
 		rb_link_node(&node->node, parent, p);
 		rb_insert_color(&node->node, &ref->tree);
-- 
2.22.0

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2019-07-25 17:53 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-25  7:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
2019-07-25  8:26 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev3) Patchwork
2019-07-25  9:12 ` ✗ Fi.CI.BAT: failure " Patchwork
2019-07-25  9:38 ` [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
2019-07-25 10:26   ` Lionel Landwerlin
2019-07-25 13:19   ` Tvrtko Ursulin
2019-07-25 13:26     ` Chris Wilson
2019-07-25 11:23 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Unshare the idle-barrier from other kernel requests (rev4) Patchwork
2019-07-25 11:44 ` ✓ Fi.CI.BAT: success " Patchwork
2019-07-25 11:48   ` Chris Wilson
2019-07-25 17:53 ` ✓ Fi.CI.IGT: " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2019-07-24 12:43 [PATCH] drm/i915: Unshare the idle-barrier from other kernel requests Chris Wilson
2019-07-24 12:50 ` Chris Wilson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.