[Intel-gfx] [PATCH 04/14] drm/i915/perf: add property to select an engine sseu configuration

Lionel Landwerlin lionel.g.landwerlin at intel.com
Wed May 17 10:59:01 UTC 2017


When monitoring a particular context, we also want to select what
engine we interested in monitoring as different engine can have
different sseu configurations. This is required because the reports
produced by the OA unit have to be interpreted using the
slice/subslice configuration.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h            | 11 +++++++++++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 31 ++++++++++++++++--------------
 drivers/gpu/drm/i915/i915_perf.c           | 22 +++++++++++++++++++++
 include/uapi/drm/i915_drm.h                |  7 +++++++
 4 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 33bc0b04400b..10ffbfec3b2e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2332,6 +2332,12 @@ struct drm_i915_private {
 
 			u32 specific_ctx_id;
 
+			/**
+			 * Configuration at which the GPU is locked for the
+			 * duration of the monitoring.
+			 */
+			struct sseu_dev_info sseu;
+
 			struct hrtimer poll_check_timer;
 			wait_queue_head_t poll_wq;
 			bool pollin;
@@ -3162,6 +3168,11 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
 int i915_gem_object_unbind(struct drm_i915_gem_object *obj);
 void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
 
+struct intel_engine_cs *
+i915_gem_engine_from_user_flags(struct drm_i915_private *dev_priv,
+				struct drm_file *file,
+				u64 user_flags);
+
 void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv);
 
 static inline int __sg_page_count(const struct scatterlist *sg)
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index af1965774e7b..bc14014eec83 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1502,37 +1502,40 @@ static const enum intel_engine_id user_ring_map[I915_USER_RINGS + 1] = {
 	[I915_EXEC_VEBOX]	= VECS
 };
 
-static struct intel_engine_cs *
-eb_select_engine(struct drm_i915_private *dev_priv,
-		 struct drm_file *file,
-		 struct drm_i915_gem_execbuffer2 *args)
+struct intel_engine_cs *
+i915_gem_engine_from_user_flags(struct drm_i915_private *dev_priv,
+				struct drm_file *file,
+				u64 user_flags)
 {
-	unsigned int user_ring_id = args->flags & I915_EXEC_RING_MASK;
+	unsigned int user_ring_id = user_flags & I915_EXEC_RING_MASK;
 	struct intel_engine_cs *engine;
 
 	if (user_ring_id > I915_USER_RINGS) {
-		DRM_DEBUG("execbuf with unknown ring: %u\n", user_ring_id);
+		DRM_DEBUG("user flags with unknown ring: %u\n", user_ring_id);
 		return NULL;
 	}
 
 	if ((user_ring_id != I915_EXEC_BSD) &&
-	    ((args->flags & I915_EXEC_BSD_MASK) != 0)) {
-		DRM_DEBUG("execbuf with non bsd ring but with invalid "
-			  "bsd dispatch flags: %d\n", (int)(args->flags));
+	    ((user_flags & I915_EXEC_BSD_MASK) != 0)) {
+		DRM_DEBUG("user flags with non bsd ring but with invalid "
+			  "bsd dispatch flags: %d\n", (int)(user_flags));
 		return NULL;
 	}
 
 	if (user_ring_id == I915_EXEC_BSD && HAS_BSD2(dev_priv)) {
-		unsigned int bsd_idx = args->flags & I915_EXEC_BSD_MASK;
+		unsigned int bsd_idx = user_flags & I915_EXEC_BSD_MASK;
 
 		if (bsd_idx == I915_EXEC_BSD_DEFAULT) {
-			bsd_idx = gen8_dispatch_bsd_engine(dev_priv, file);
+			if (file)
+				bsd_idx = gen8_dispatch_bsd_engine(dev_priv, file);
+			else
+				bsd_idx = 0;
 		} else if (bsd_idx >= I915_EXEC_BSD_RING1 &&
 			   bsd_idx <= I915_EXEC_BSD_RING2) {
 			bsd_idx >>= I915_EXEC_BSD_SHIFT;
 			bsd_idx--;
 		} else {
-			DRM_DEBUG("execbuf with unknown bsd ring: %u\n",
+			DRM_DEBUG("user flags with unknown bsd ring: %u\n",
 				  bsd_idx);
 			return NULL;
 		}
@@ -1543,7 +1546,7 @@ eb_select_engine(struct drm_i915_private *dev_priv,
 	}
 
 	if (!engine) {
-		DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id);
+		DRM_DEBUG("user flags with invalid ring: %u\n", user_ring_id);
 		return NULL;
 	}
 
@@ -1590,7 +1593,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	if (args->flags & I915_EXEC_IS_PINNED)
 		dispatch_flags |= I915_DISPATCH_PINNED;
 
-	engine = eb_select_engine(dev_priv, file, args);
+	engine = i915_gem_engine_from_user_flags(dev_priv, file, args->flags);
 	if (!engine)
 		return -EINVAL;
 
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 85269bcc8372..5f4eccaa06d6 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -325,6 +325,8 @@ struct perf_open_properties {
 	u64 single_context:1;
 	u64 ctx_handle;
 
+	struct intel_engine_cs *ctx_engine;
+
 	/* OA sampling state */
 	int metrics_set;
 	int oa_format;
@@ -1272,6 +1274,11 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
 		return -EINVAL;
 	}
 
+	if (!props->ctx_handle && props->ctx_engine) {
+		DRM_DEBUG("OA engine specified with no associated context\n");
+		return -EINVAL;
+	}
+
 	/* We set up some ratelimit state to potentially throttle any _NOTES
 	 * about spurious, invalid OA reports which we don't forward to
 	 * userspace.
@@ -1313,9 +1320,15 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
 		dev_priv->perf.oa.period_exponent = props->oa_period_exponent;
 
 	if (stream->ctx) {
+		enum intel_engine_id engine_id =
+			props->ctx_engine ? props->ctx_engine->id : RCS;
+		dev_priv->perf.oa.sseu = stream->ctx->engine[engine_id].sseu;
+
 		ret = oa_get_render_ctx_id(stream);
 		if (ret)
 			return ret;
+	} else {
+		dev_priv->perf.oa.sseu = INTEL_INFO(dev_priv)->sseu;
 	}
 
 	ret = alloc_oa_buffer(dev_priv);
@@ -1986,6 +1999,15 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
 			props->oa_periodic = true;
 			props->oa_period_exponent = value;
 			break;
+		case DRM_I915_PERF_PROP_CTX_RING: {
+			props->ctx_engine =
+				i915_gem_engine_from_user_flags(dev_priv, NULL, value);
+			if (props->ctx_engine == NULL) {
+				DRM_DEBUG("OA context ring invalid\n");
+				return -EINVAL;
+			}
+			break;
+		}
 		case DRM_I915_PERF_PROP_MAX:
 			MISSING_CASE(id);
 			return -EINVAL;
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index f24a80d2d42e..ba722fb343a4 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1353,6 +1353,13 @@ enum drm_i915_perf_property_id {
 	 */
 	DRM_I915_PERF_PROP_OA_EXPONENT,
 
+	/**
+	 * Configure the stream to monitor a particular ring (this is only
+	 * valid when monitoring a particular context), if omitted
+	 * I915_EXEC_DEFAULT will be used.
+	 */
+	DRM_I915_PERF_PROP_CTX_RING,
+
 	DRM_I915_PERF_PROP_MAX /* non-ABI */
 };
 
-- 
2.11.0



More information about the Intel-gfx mailing list