[Mesa-dev] [PATCH] i965: oa-counters: keep on reading reports until delimiting timestamp

Lionel Landwerlin lionel.g.landwerlin at intel.com
Thu Mar 30 15:16:27 UTC 2017


While exercising reading report with moderate load, we might have to
wait for all the reports to land in the OA buffer, otherwise we might
miss some reports. That means we need to keep on reading the OA stream
until the last report we read has a timestamp older that the timestamp
recorded by the MI_REPORT_PERF_COUNT at the end of the performance
query.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Cc: Robert Bragg <robert at sixbynine.org>
---
 src/mesa/drivers/dri/i965/brw_performance_query.c | 51 ++++++++++++++---------
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_performance_query.c b/src/mesa/drivers/dri/i965/brw_performance_query.c
index 4a94e4b3cc..076c59e633 100644
--- a/src/mesa/drivers/dri/i965/brw_performance_query.c
+++ b/src/mesa/drivers/dri/i965/brw_performance_query.c
@@ -647,38 +647,50 @@ discard_all_queries(struct brw_context *brw)
 }
 
 static bool
-read_oa_samples(struct brw_context *brw)
+read_oa_samples_until(struct brw_context *brw,
+                      uint32_t start_timestamp,
+                      uint32_t end_timestamp)
 {
-   while (1) {
+   uint32_t last_timestamp = start_timestamp;
+
+   while (last_timestamp < end_timestamp) {
       struct brw_oa_sample_buf *buf = get_free_sample_buf(brw);
+      uint32_t offset;
       int len;
 
       while ((len = read(brw->perfquery.oa_stream_fd, buf->buf,
-                         sizeof(buf->buf))) < 0 && errno == EINTR)
+                         sizeof(buf->buf))) < 0 &&
+             (errno == EINTR || errno == EAGAIN))
          ;
 
       if (len <= 0) {
          exec_list_push_tail(&brw->perfquery.free_sample_buffers, &buf->link);
 
-         if (len < 0) {
-            if (errno == EAGAIN)
-               return true;
-            else {
-               DBG("Error reading i915 perf samples: %m\n");
-               return false;
-            }
-         } else {
+         if (len < 0)
+            DBG("Error reading i915 perf samples: %m\n");
+         else
             DBG("Spurious EOF reading i915 perf samples\n");
-            return false;
-         }
+
+         return false;
       }
 
       buf->len = len;
       exec_list_push_tail(&brw->perfquery.sample_buffers, &buf->link);
+
+      /* Go through the reports and update the last timestamp. */
+      while (offset < buf->len) {
+         const struct drm_i915_perf_record_header *header =
+            (const struct drm_i915_perf_record_header *) &buf->buf[offset];
+         uint32_t *report = (uint32_t *) (header + 1);
+
+         if (header->type == DRM_I915_PERF_RECORD_SAMPLE)
+            last_timestamp = report[1];
+
+         offset += header->size;
+      }
    }
 
-   unreachable("not reached");
-   return false;
+   return true;
 }
 
 /**
@@ -709,10 +721,6 @@ accumulate_oa_reports(struct brw_context *brw,
 
    assert(o->Ready);
 
-   /* Collect the latest periodic OA reports from i915 perf */
-   if (!read_oa_samples(brw))
-      goto error;
-
    drm_intel_bo_map(obj->oa.bo, false);
    query_buffer = obj->oa.bo->virtual;
 
@@ -728,6 +736,11 @@ accumulate_oa_reports(struct brw_context *brw,
       goto error;
    }
 
+   /* Collect the latest periodic OA reports from i915 perf */
+   if (!read_oa_samples_until(brw, start[1], end[1]))
+      goto error;
+
+
    /* See if we have any periodic reports to accumulate too... */
 
    /* N.B. The oa.samples_head was set when the query began and
-- 
2.11.0



More information about the mesa-dev mailing list