[Intel-gfx] [PATCH v2] drm/i915: Allow sharing the idle-barrier from other kernel requests

2019-08-02 Thread Chris Wilson
By placing our idle-barriers in the i915_active fence tree, we expose
those for reuse by other components that are issuing requests along the
kernel_context. Reusing the proto-barrier active_node is perfectly fine
as the new request implies a context-switch, and so an opportune point
to run the idle-barrier. However, the proto-barrier is not equivalent
to a normal active_node and care must be taken to avoid dereferencing the
ERR_PTR used as its request marker.

v2: Comment the more egregious cheek

Reported-by: Lionel Landwerlin 
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 
Cc: Lionel Landwerlin 
Cc: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  40 ++-
 drivers/gpu/drm/i915/gt/intel_context.h   |  13 +-
 drivers/gpu/drm/i915/gt/intel_engine_pm.c |   2 +-
 drivers/gpu/drm/i915/gt/selftest_context.c| 310 ++
 drivers/gpu/drm/i915/i915_active.c| 265 ---
 drivers/gpu/drm/i915/i915_active.h|   2 +-
 drivers/gpu/drm/i915/i915_active_types.h  |   2 +-
 .../drm/i915/selftests/i915_live_selftests.h  |   3 +-
 8 files changed, 574 insertions(+), 63 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 f30441a140f8..34c8e37a73b8 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -162,23 +162,41 @@ static int __intel_context_active(struct i915_active 
*active)
if (err)
goto err_ring;
 
+   return 0;
+
+err_ring:
+   intel_ring_unpin(ce->ring);
+err_put:
+   intel_context_put(ce);
+   return err;
+}
+
+int intel_context_active_acquire(struct intel_context *ce)
+{
+   int err;
+
+   err = i915_active_acquire(>active);
+   if (err)
+   return err;
+
/* Preallocate tracking nodes */
if (!i915_gem_context_is_kernel(ce->gem_context)) {
err = i915_active_acquire_preallocate_barrier(>active,
  ce->engine);
-   if (err)
-   goto err_state;
+   if (err) {
+   i915_active_release(>active);
+   return err;
+   }
}
 
return 0;
+}
 
-err_state:
-   __context_unpin_state(ce->state);
-err_ring:
-   intel_ring_unpin(ce->ring);
-err_put:
-   intel_context_put(ce);
-   return err;
+void intel_context_active_release(struct intel_context *ce)
+{
+   /* Nodes preallocated in intel_context_active() */
+   i915_active_acquire_barrier(>active);
+   i915_active_release(>active);
 }
 
 void
@@ -301,3 +319,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(>active);
-}
-
-static inline void intel_context_active_release(struct intel_context *ce)
-{
-   /* Nodes preallocated in intel_context_active() */
-   i915_active_acquire_barrier(>active);
-   i915_active_release(>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/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index e74fbf04a68d..ce54092475da 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -90,7 +90,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs 
*engine)
/* Check again on the next retirement. */
engine->wakeref_serial = engine->serial + 1;
 
-   i915_request_add_barriers(rq);
+   i915_request_add_active_barriers(rq);
__i915_request_commit(rq);
 
return false;
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 ..d39b5594cb02
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/selftest_context.c
@@ -0,0 +1,310 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "i915_selftest.h"
+#include "intel_gt.h"
+
+#include 

[Intel-gfx] [PATCH v2] drm/i915: Allow sharing the idle-barrier from other kernel requests

2019-07-26 Thread Chris Wilson
By placing our idle-barriers in the i915_active fence tree, we expose
those for reuse by other components that are issuing requests along the
kernel_context. Reusing the proto-barrier active_node is perfectly fine
as the new request implies a context-switch, and so an opportune point
to run the idle-barrier. However, the proto-barrier is not equivalent
to a normal active_node and care must be taken to avoid dereferencing the
ERR_PTR used as its request marker.

Reported-by: Lionel Landwerlin 
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 
Cc: Lionel Landwerlin 
Cc: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  40 ++-
 drivers/gpu/drm/i915/gt/intel_context.h   |  13 +-
 drivers/gpu/drm/i915/gt/intel_engine_pm.c |   2 +-
 drivers/gpu/drm/i915/gt/selftest_context.c| 310 ++
 drivers/gpu/drm/i915/i915_active.c| 215 +---
 drivers/gpu/drm/i915/i915_active.h|   2 +-
 drivers/gpu/drm/i915/i915_active_types.h  |   2 +-
 .../drm/i915/selftests/i915_live_selftests.h  |   3 +-
 8 files changed, 525 insertions(+), 62 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 d64b45f7ec6d..211ac6568a5d 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -162,23 +162,41 @@ static int __intel_context_active(struct i915_active 
*active)
if (err)
goto err_ring;
 
+   return 0;
+
+err_ring:
+   intel_ring_unpin(ce->ring);
+err_put:
+   intel_context_put(ce);
+   return err;
+}
+
+int intel_context_active_acquire(struct intel_context *ce)
+{
+   int err;
+
+   err = i915_active_acquire(>active);
+   if (err)
+   return err;
+
/* Preallocate tracking nodes */
if (!i915_gem_context_is_kernel(ce->gem_context)) {
err = i915_active_acquire_preallocate_barrier(>active,
  ce->engine);
-   if (err)
-   goto err_state;
+   if (err) {
+   i915_active_release(>active);
+   return err;
+   }
}
 
return 0;
+}
 
-err_state:
-   __context_unpin_state(ce->state);
-err_ring:
-   intel_ring_unpin(ce->ring);
-err_put:
-   intel_context_put(ce);
-   return err;
+void intel_context_active_release(struct intel_context *ce)
+{
+   /* Nodes preallocated in intel_context_active() */
+   i915_active_acquire_barrier(>active);
+   i915_active_release(>active);
 }
 
 void
@@ -297,3 +315,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(>active);
-}
-
-static inline void intel_context_active_release(struct intel_context *ce)
-{
-   /* Nodes preallocated in intel_context_active() */
-   i915_active_acquire_barrier(>active);
-   i915_active_release(>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/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index e74fbf04a68d..ce54092475da 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -90,7 +90,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs 
*engine)
/* Check again on the next retirement. */
engine->wakeref_serial = engine->serial + 1;
 
-   i915_request_add_barriers(rq);
+   i915_request_add_active_barriers(rq);
__i915_request_commit(rq);
 
return false;
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 ..e3b45fe747ae
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/selftest_context.c
@@ -0,0 +1,310 @@
+/*
+ * 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