[Intel-gfx] [PATCH i-g-t 07/11] tests/perf: make buffer-fill more reliable
Matthew Auld
matthew.william.auld at gmail.com
Thu Aug 10 16:10:56 UTC 2017
On 4 August 2017 at 12:20, Lionel Landwerlin
<lionel.g.landwerlin at intel.com> wrote:
> Filling rate of the buffer must discard context switch reports as they
> do not depend upon the periodicity, instead they're a factor on the
> amount of different applications concurrently running on the system.
>
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> ---
> tests/perf.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 104 insertions(+), 17 deletions(-)
>
> diff --git a/tests/perf.c b/tests/perf.c
> index f33ccffd..6c0af32d 100644
> --- a/tests/perf.c
> +++ b/tests/perf.c
> @@ -2749,22 +2749,30 @@ test_buffer_fill(void)
> .num_properties = sizeof(properties) / 16,
> .properties_ptr = to_user_pointer(properties),
> };
> + struct drm_i915_perf_record_header *header;
> int buf_size = 65536 * (256 + sizeof(struct drm_i915_perf_record_header));
> uint8_t *buf = malloc(buf_size);
> + int len;
> size_t oa_buf_size = 16 * 1024 * 1024;
> size_t report_size = oa_formats[test_oa_format].size;
> int n_full_oa_reports = oa_buf_size / report_size;
> uint64_t fill_duration = n_full_oa_reports * oa_period;
>
> + load_helper_init();
> + load_helper_run(HIGH);
> +
> igt_assert(fill_duration < 1000000000);
>
> stream_fd = __perf_open(drm_fd, ¶m);
>
> for (int i = 0; i < 5; i++) {
> - struct drm_i915_perf_record_header *header;
> bool overflow_seen;
> - int offset = 0;
> - int len;
> + uint32_t n_periodic_reports;
> + uint32_t first_timestamp = 0, last_timestamp = 0;
> + uint32_t last_periodic_report[64];
> + double tick_per_period;
> +
> + do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0);
>
> nanosleep(&(struct timespec){ .tv_sec = 0,
> .tv_nsec = fill_duration * 1.25 },
> @@ -2776,7 +2784,7 @@ test_buffer_fill(void)
> igt_assert_neq(len, -1);
>
> overflow_seen = false;
> - for (offset = 0; offset < len; offset += header->size) {
> + for (int offset = 0; offset < len; offset += header->size) {
> header = (void *)(buf + offset);
>
> if (header->type == DRM_I915_PERF_RECORD_OA_BUFFER_LOST)
> @@ -2785,32 +2793,111 @@ test_buffer_fill(void)
>
> igt_assert_eq(overflow_seen, true);
>
> + do_ioctl(stream_fd, I915_PERF_IOCTL_DISABLE, 0);
> +
> + igt_debug("fill_duration = %luns, oa_exponent = %u\n",
> + fill_duration, oa_exponent);
> +
> + do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0);
> +
> nanosleep(&(struct timespec){ .tv_sec = 0,
> - .tv_nsec = fill_duration / 2 },
> - NULL);
> + .tv_nsec = fill_duration / 2 },
> + NULL);
>
> - while ((len = read(stream_fd, buf, buf_size)) == -1 && errno == EINTR)
> - ;
> + n_periodic_reports = 0;
>
> - igt_assert_neq(len, -1);
> + /* Because of the race condition between notification of new
> + * reports and reports landing in memory, we need to rely on
> + * timestamps to figure whether we've read enough of them.
> + */
> + while (((last_timestamp - first_timestamp) * oa_exponent_to_ns(oa_exponent)) <
(last_timestamp - first_timestamp) * oa_period
> + (fill_duration / 2)) {
>
> - igt_assert(len > report_size * n_full_oa_reports * 0.45);
> - igt_assert(len < report_size * n_full_oa_reports * 0.55);
> + igt_debug("dts=%u elapsed=%lu duration=%lu\n",
> + last_timestamp - first_timestamp,
> + (last_timestamp - first_timestamp) * oa_exponent_to_ns(oa_exponent),
(last_timestamp - first_timestamp) * oa_period
Otherwise looks okay:
Tested-by: Matthew Auld <matthew.auld at intel.com> #bdw
Reviewed-by: Matthew Auld <matthew.auld at intel.com>
> + fill_duration / 2);
>
> - overflow_seen = false;
> - for (offset = 0; offset < len; offset += header->size) {
> - header = (void *)(buf + offset);
> + while ((len = read(stream_fd, buf, buf_size)) == -1 && errno == EINTR)
> + ;
>
> - if (header->type == DRM_I915_PERF_RECORD_OA_BUFFER_LOST)
> - overflow_seen = true;
> + igt_assert_neq(len, -1);
> +
> + for (int offset = 0; offset < len; offset += header->size) {
> + uint32_t *report;
> + double previous_tick_per_period;
> +
> + header = (void *) (buf + offset);
> + report = (void *) (header + 1);
> +
> + switch (header->type) {
> + case DRM_I915_PERF_RECORD_OA_REPORT_LOST:
> + igt_debug("report loss, trying again\n");
> + break;
> + case DRM_I915_PERF_RECORD_SAMPLE:
> + igt_debug(" > report ts=%u"
> + " ts_delta_last_periodic=%8u is_timer=%i ctx_id=%8x gpu_ticks=%u nb_periodic=%u\n",
> + report[1],
> + n_periodic_reports > 0 ? report[1] - last_periodic_report[1] : 0,
> + oa_report_is_periodic(oa_exponent, report),
> + oa_report_get_ctx_id(report),
> + n_periodic_reports > 0 ? report[3] - last_periodic_report[3] : 0,
> + n_periodic_reports);
> +
> + if (first_timestamp == 0)
> + first_timestamp = report[1];
> + last_timestamp = report[1];
> +
> + previous_tick_per_period = tick_per_period;
> +
> + if (n_periodic_reports > 1 &&
> + oa_report_is_periodic(oa_exponent, report)) {
> + tick_per_period =
> + oa_reports_tick_per_period(last_periodic_report,
> + report);
> +
> + if (!double_value_within(previous_tick_per_period,
> + tick_per_period, 5))
> + igt_debug("clock change!\n");
> +
> + memcpy(last_periodic_report, report,
> + sizeof(last_periodic_report));
> + }
> +
> + /* We want to measure only the periodic
> + * reports, ctx-switch might inflate the
> + * content of the buffer and skew or
> + * measurement.
> + */
> + n_periodic_reports +=
> + oa_report_is_periodic(oa_exponent, report);
> + break;
> + case DRM_I915_PERF_RECORD_OA_BUFFER_LOST:
> + igt_assert(!"unexpected overflow");
> + break;
> + }
> + }
> }
>
> - igt_assert_eq(overflow_seen, false);
> + do_ioctl(stream_fd, I915_PERF_IOCTL_DISABLE, 0);
> +
> + igt_debug("%f < %lu < %f\n",
> + report_size * n_full_oa_reports * 0.45,
> + n_periodic_reports * report_size,
> + report_size * n_full_oa_reports * 0.55);
> +
> + igt_assert(n_periodic_reports * report_size >
> + report_size * n_full_oa_reports * 0.45);
> + igt_assert(n_periodic_reports * report_size <
> + report_size * n_full_oa_reports * 0.55);
> }
>
> free(buf);
>
> __perf_close(stream_fd);
> +
> + load_helper_stop();
> + load_helper_deinit();
> }
>
> static void
> --
> 2.13.3
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list