[PATCH v2 09/11] drm/i915/perf: allowing opening the perf stream without sampling

Lionel Landwerlin lionel.g.landwerlin at intel.com
Fri Mar 23 15:56:34 UTC 2018


We want to allow a user to configure the OA hardware so that
MI_RECORD_PERF_COUNT is functional but without having to deal with the
OA buffer.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
 drivers/gpu/drm/i915/i915_perf.c | 56 ++++++++++++++++++++++++++++++----------
 1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index c91ad447207e..55c7631ad3c2 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -421,6 +421,14 @@ static u32 gen7_oa_hw_tail_read(struct drm_i915_private *dev_priv)
 	return oastatus1 & GEN7_OASTATUS1_TAIL_MASK;
 }
 
+static bool i915_perf_stream_produces_reports(struct i915_perf_stream *stream)
+{
+	struct drm_i915_private *dev_priv = stream->dev_priv;
+
+	return (stream->sample_flags & SAMPLE_OA_REPORT) != 0 &&
+		dev_priv->perf.oa.periodic;
+}
+
 /**
  * oa_buffer_check_unlocked - check for data and update tail ptr state
  * @dev_priv: i915 device instance
@@ -453,6 +461,8 @@ static bool oa_buffer_check_unlocked(struct drm_i915_private *dev_priv)
 	u32 head, hw_tail, aged_tail, aging_tail;
 	u64 now;
 
+	GEM_BUG_ON(!i915_perf_stream_produces_reports(dev_priv->perf.oa.exclusive_stream));
+
 	/* We have to consider the (unlikely) possibility that read() errors
 	 * could result in an OA buffer reset which might reset the head,
 	 * tails[] and aged_tail state.
@@ -1153,8 +1163,7 @@ static int i915_oa_wait_unlocked(struct i915_perf_stream *stream)
 {
 	struct drm_i915_private *dev_priv = stream->dev_priv;
 
-	/* We would wait indefinitely if periodic sampling is not enabled */
-	if (!dev_priv->perf.oa.periodic)
+	if (!i915_perf_stream_produces_reports(stream))
 		return -EIO;
 
 	return wait_event_interruptible(dev_priv->perf.oa.poll_wq,
@@ -1821,6 +1830,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
 				  const struct i915_perf_stream *stream)
 {
 	struct i915_oa_config *oa_config = stream->oa_config;
+	u32 oa_debug_value = 0;
 	int ret;
 
 	/*
@@ -1847,11 +1857,23 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
 	 * RPT_ID field.
 	 */
 	if (IS_GEN9(dev_priv) || IS_GEN10(dev_priv)) {
-		I915_WRITE(GEN8_OA_DEBUG,
-			   _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
-					      GEN9_OA_DEBUG_INCLUDE_CLK_RATIO));
+		oa_debug_value |=
+			_MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS |
+					   GEN9_OA_DEBUG_INCLUDE_CLK_RATIO);
 	}
 
+	/*
+	 * If the user didn't require OA reports, instruct the hardware not to
+	 * emit ctx switch reports (mind your head, we might be disabling the
+	 * disable).
+	 */
+	oa_debug_value |=
+		(stream->sample_flags & SAMPLE_OA_REPORT) ?
+		_MASKED_BIT_DISABLE(GEN9_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS) :
+		_MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS);
+
+	I915_WRITE(GEN8_OA_DEBUG, oa_debug_value);
+
 	/*
 	 * Update all contexts prior writing the mux configurations as we need
 	 * to make sure all slices/subslices are ON before writing to NOA
@@ -1960,7 +1982,7 @@ static void i915_oa_stream_enable(struct i915_perf_stream *stream)
 
 	dev_priv->perf.oa.ops.oa_enable(dev_priv, stream);
 
-	if (dev_priv->perf.oa.periodic)
+	if (i915_perf_stream_produces_reports(stream))
 		hrtimer_start(&dev_priv->perf.oa.poll_check_timer,
 			      ns_to_ktime(POLL_PERIOD),
 			      HRTIMER_MODE_REL_PINNED);
@@ -1990,7 +2012,7 @@ static void i915_oa_stream_disable(struct i915_perf_stream *stream)
 
 	dev_priv->perf.oa.ops.oa_disable(dev_priv);
 
-	if (dev_priv->perf.oa.periodic)
+	if (i915_perf_stream_produces_reports(stream))
 		hrtimer_cancel(&dev_priv->perf.oa.poll_check_timer);
 }
 
@@ -2038,11 +2060,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
 		return -EINVAL;
 	}
 
-	if (!(props->sample_flags & SAMPLE_OA_REPORT)) {
-		DRM_DEBUG("Only OA report sampling supported\n");
-		return -EINVAL;
-	}
-
 	if (!dev_priv->perf.oa.ops.init_oa_buffer) {
 		DRM_DEBUG("OA unit not supported\n");
 		return -ENODEV;
@@ -2086,8 +2103,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
 
 	format_size = dev_priv->perf.oa.oa_formats[props->oa_format].size;
 
-	stream->sample_flags |= SAMPLE_OA_REPORT;
-	stream->sample_size += format_size;
+	if (props->sample_flags & SAMPLE_OA_REPORT) {
+		stream->sample_flags |= SAMPLE_OA_REPORT;
+		stream->sample_size += format_size;
+	}
 
 	dev_priv->perf.oa.oa_buffer.format_size = format_size;
 	if (WARN_ON(dev_priv->perf.oa.oa_buffer.format_size == 0))
@@ -2255,6 +2274,12 @@ static ssize_t i915_perf_read(struct file *file,
 	struct drm_i915_private *dev_priv = stream->dev_priv;
 	ssize_t ret;
 
+	/* If the user opened the stream only to snapshot counters through
+	 * MI_RECORD_PERF_COUNT, there is nothing to read from the OA buffer.
+	 */
+	if (!i915_perf_stream_produces_reports(stream))
+		return -EIO;
+
 	/* To ensure it's handled consistently we simply treat all reads of a
 	 * disabled stream as an error. In particular it might otherwise lead
 	 * to a deadlock for blocking file descriptors...
@@ -2343,6 +2368,9 @@ static __poll_t i915_perf_poll_locked(struct drm_i915_private *dev_priv,
 {
 	__poll_t events = 0;
 
+	if (!i915_perf_stream_produces_reports(stream))
+		return events;
+
 	stream->ops->poll_wait(stream, file, wait);
 
 	/* Note: we don't explicitly check whether there's something to read
-- 
2.16.2



More information about the Intel-gfx-trybot mailing list