On 03/04/17 21:04, Robert Bragg wrote:


On Mar 30, 2017 16:16, "Lionel Landwerlin" <lionel.g.landwer...@intel.com <mailto:lionel.g.landwer...@intel.com>> wrote:

    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.


The expectation is that since we have received the second MI_REPORT_PERF_COUNT report that implies any periodic/automatic reports that the could possibly relate to a query must have been written to the OABUFFER. Since we read() as much as is available from i915 perf when we come to finish processing a query then we shouldn't miss anything.

We shouldn't synchronously wait in a busy loop until we've found a report that has a timestamp >= our end MI_RPC because that could be a really significant amount of time (e.g. 50+ milliseconds on HSW). NB. the periodic samples are just to account for counter overflow. On Gen8+ the loop would likely block until the next context switch happens.

Right, so if we don't get all the reports until the second MI_REPORT_PERF_COUNT, we might be dealing with a kernel issue.

I'm still suspicious of the code in mesa. I think in some cases (in particular with many applications running) it might loop forever.

Also the igt tests using roughly the same loop while (read() && errno != EINTR) are pretty reliable at not finding all the reports we need from to the stream.
So I would expect the same thing from mesa.


Was this proposal based on a code inspection or did you maybe hit a problem correctly measuring something?

Maybe if based on inspection we can find somewhere to put a comment to clarify the assumptions above?

Br,
- Robert


    Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com
    <mailto:lionel.g.landwer...@intel.com>>
    Cc: Robert Bragg <rob...@sixbynine.org <mailto:rob...@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 <http://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



_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to