From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 479C510E02A for ; Tue, 14 Feb 2023 21:00:14 +0000 (UTC) From: Umesh Nerlige Ramappa To: igt-dev@lists.freedesktop.org Date: Tue, 14 Feb 2023 12:59:46 -0800 Message-Id: <20230214210007.2026033-10-umesh.nerlige.ramappa@intel.com> In-Reply-To: <20230214210007.2026033-1-umesh.nerlige.ramappa@intel.com> References: <20230214210007.2026033-1-umesh.nerlige.ramappa@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [igt-dev] [PATCH 09/30] i915/perf: Treat timestamp as 64 bit value List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lionel G Landwerlin Errors-To: igt-dev-bounces@lists.freedesktop.org Sender: "igt-dev" List-ID: New OA formats in MTL have 64 bit OA report header. Update the timestamp in the tests to be dafault 64 bit. Signed-off-by: Umesh Nerlige Ramappa --- tests/i915/perf.c | 156 +++++++++++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 63 deletions(-) diff --git a/tests/i915/perf.c b/tests/i915/perf.c index 4c7b4e49..c3c5663b 100644 --- a/tests/i915/perf.c +++ b/tests/i915/perf.c @@ -552,9 +552,28 @@ cs_timebase_scale(uint32_t u32_delta) } static uint64_t -timebase_scale(uint32_t u32_delta) +oa_timestamp(const uint32_t *report, enum drm_i915_oa_format format) { - return ((uint64_t)u32_delta * NSEC_PER_SEC) / intel_perf->devinfo.timestamp_frequency; + struct oa_format fmt = get_oa_format(format); + + return fmt.report_hdr_64bit ? *(uint64_t *)&report[2] : report[1]; +} + +static uint64_t +oa_timestamp_delta(const uint32_t *report1, + const uint32_t *report0, + enum drm_i915_oa_format format) +{ + uint32_t width = intel_graphics_ver(devid) >= IP_VER(12, 55) ? 56 : 32; + + return elapsed_delta(oa_timestamp(report1, format), + oa_timestamp(report0, format), width); +} + +static uint64_t +timebase_scale(uint64_t delta) +{ + return (delta * NSEC_PER_SEC) / intel_perf->devinfo.timestamp_frequency; } /* Returns: the largest OA exponent that will still result in a sampling period @@ -563,7 +582,7 @@ timebase_scale(uint32_t u32_delta) static int max_oa_exponent_for_period_lte(uint64_t period) { - /* NB: timebase_scale() takes a uint32_t and an exponent of 30 + /* NB: timebase_scale() takes a uint64_t and an exponent of 30 * would already represent a period of ~3 minutes so there's * really no need to consider higher exponents. */ @@ -712,12 +731,14 @@ hsw_sanity_check_render_basic_reports(const uint32_t *oa_report0, const uint32_t *oa_report1, enum drm_i915_oa_format fmt) { - uint32_t time_delta = timebase_scale(oa_report1[1] - oa_report0[1]); + uint64_t time_delta = timebase_scale(oa_timestamp_delta(oa_report1, + oa_report0, + fmt)); uint64_t clock_delta; uint64_t max_delta; struct oa_format format = get_oa_format(fmt); - igt_assert_neq(time_delta, 0); + igt_assert_neq_u64(time_delta, 0); /* As a special case we have to consider that on Haswell we * can't explicitly derive a clock delta for all OA report @@ -726,8 +747,7 @@ hsw_sanity_check_render_basic_reports(const uint32_t *oa_report0, if (format.n_c == 0) { /* Assume running at max freq for sake of * below sanity check on counters... */ - clock_delta = (gt_max_freq_mhz * - (uint64_t)time_delta) / 1000; + clock_delta = (gt_max_freq_mhz * time_delta) / 1000; } else { uint64_t freq; @@ -871,7 +891,8 @@ accumulate_reports(struct accumulator *accumulator, if (intel_gen(devid) >= 8) { /* timestamp */ - accumulate_uint32(4, start, end, deltas + idx++); + deltas[idx] += oa_timestamp_delta(end, start, accumulator->format); + idx++; /* clock cycles */ deltas[idx] += oa_tick_delta(end, start, accumulator->format); @@ -947,7 +968,9 @@ gen8_sanity_check_test_oa_reports(const uint32_t *oa_report0, enum drm_i915_oa_format fmt) { struct oa_format format = get_oa_format(fmt); - uint32_t time_delta = timebase_scale(oa_report1[1] - oa_report0[1]); + uint64_t time_delta = timebase_scale(oa_timestamp_delta(oa_report1, + oa_report0, + fmt)); uint64_t clock_delta = oa_tick_delta(oa_report1, oa_report0, fmt); uint64_t max_delta; uint64_t freq; @@ -1135,11 +1158,11 @@ static int i915_read_reports_until_timestamp(enum drm_i915_oa_format oa_format, uint8_t *buf, uint32_t max_size, - uint32_t start_timestamp, - uint32_t end_timestamp) + uint64_t start_timestamp, + uint64_t end_timestamp) { size_t format_size = get_oa_format(oa_format).size; - uint32_t last_seen_timestamp = start_timestamp; + uint64_t last_seen_timestamp = start_timestamp; int total_len = 0; while (last_seen_timestamp < end_timestamp) { @@ -1148,7 +1171,7 @@ i915_read_reports_until_timestamp(enum drm_i915_oa_format oa_format, /* Running out of space. */ if ((max_size - total_len) < format_size) { igt_warn("run out of space before reaching " - "end timestamp (%u/%u)\n", + "end timestamp (%"PRIu64"/%"PRIu64")\n", last_seen_timestamp, end_timestamp); return -1; } @@ -1177,7 +1200,7 @@ i915_read_reports_until_timestamp(enum drm_i915_oa_format oa_format, uint32_t *report = (uint32_t *) (header + 1); if (header->type == DRM_I915_PERF_RECORD_SAMPLE) - last_seen_timestamp = report[1]; + last_seen_timestamp = oa_timestamp(report, oa_format); offset += header->size; } @@ -1483,11 +1506,11 @@ read_2_oa_reports(int format_id, report = (const void *)(header + 1); dump_report(report, format_size / 4, "oa-formats"); - igt_debug("read report: reason = %x, timestamp = %x, exponent mask=%x\n", - report[0], report[1], exponent_mask); + igt_debug("read report: reason = %x, timestamp = %"PRIx64", exponent mask=%x\n", + report[0], oa_timestamp(report, format_id), exponent_mask); /* Don't expect zero for timestamps */ - igt_assert_neq(report[1], 0); + igt_assert_neq_u64(oa_timestamp(report, format_id), 0); if (timer_only) { if (!oa_report_is_periodic(exponent, report)) { @@ -1551,9 +1574,11 @@ static void print_reports(uint32_t *oa_report0, uint32_t *oa_report1, int fmt) { struct oa_format format = get_oa_format(fmt); + uint64_t ts0 = oa_timestamp(oa_report0, fmt); + uint64_t ts1 = oa_timestamp(oa_report1, fmt); - igt_debug("TIMESTAMP: 1st = %"PRIu32", 2nd = %"PRIu32", delta = %"PRIu32"\n", - oa_report0[1], oa_report1[1], oa_report1[1] - oa_report0[1]); + igt_debug("TIMESTAMP: 1st = %"PRIu64", 2nd = %"PRIu64", delta = %"PRIu64"\n", + ts0, ts1, ts1 - ts0); if (IS_HASWELL(devid) && format.n_c == 0) { igt_debug("CLOCK = N/A\n"); @@ -1658,7 +1683,7 @@ print_report(uint32_t *report, int fmt) { struct oa_format format = get_oa_format(fmt); - igt_debug("TIMESTAMP: %"PRIu32"\n", report[1]); + igt_debug("TIMESTAMP: %"PRIu64"\n", oa_timestamp(report, fmt)); if (IS_HASWELL(devid) && format.n_c == 0) { igt_debug("CLOCK = N/A\n"); @@ -1887,6 +1912,8 @@ static bool expected_report_timing_delta(uint32_t delta, uint32_t expected_delta static void test_oa_exponents(const struct intel_execution_engine2 *e) { + uint64_t fmt = test_set->perf_oa_format; + load_helper_init(); load_helper_run(HIGH); @@ -1901,7 +1928,7 @@ test_oa_exponents(const struct intel_execution_engine2 *e) /* OA unit configuration */ DRM_I915_PERF_PROP_OA_METRICS_SET, test_set->perf_oa_metrics_set, - DRM_I915_PERF_PROP_OA_FORMAT, test_set->perf_oa_format, + DRM_I915_PERF_PROP_OA_FORMAT, fmt, DRM_I915_PERF_PROP_OA_EXPONENT, exponent, DRM_I915_PERF_PROP_OA_ENGINE_CLASS, e->class, DRM_I915_PERF_PROP_OA_ENGINE_INSTANCE, e->instance, @@ -1914,7 +1941,7 @@ test_oa_exponents(const struct intel_execution_engine2 *e) .properties_ptr = to_user_pointer(properties), }; uint64_t expected_timestamp_delta = 2ULL << exponent; - size_t format_size = get_oa_format(test_set->perf_oa_format).size; + size_t format_size = get_oa_format(fmt).size; size_t sample_size = (sizeof(struct drm_i915_perf_record_header) + format_size); int max_reports = MAX_OA_BUF_SIZE / format_size; @@ -1978,15 +2005,16 @@ test_oa_exponents(const struct intel_execution_engine2 *e) __perf_close(stream_fd); - igt_debug("report%04i ts=%08x hw_id=0x%08x\n", 0, - timer_reports[0].report[1], + igt_debug("report%04i ts=%"PRIx64" hw_id=0x%08x\n", 0, + oa_timestamp(timer_reports[0].report, fmt), oa_report_get_ctx_id(timer_reports[0].report)); for (int i = 1; i < n_timer_reports; i++) { - uint32_t delta = - timer_reports[i].report[1] - timer_reports[i - 1].report[1]; + uint64_t delta = oa_timestamp_delta(timer_reports[i].report, + timer_reports[i - 1].report, + fmt); - igt_debug("report%04i ts=%08x hw_id=0x%08x delta=%u %s\n", i, - timer_reports[i].report[1], + igt_debug("report%04i ts=%"PRIx64" hw_id=0x%08x delta=%"PRIu64" %s\n", i, + oa_timestamp(timer_reports[i].report, fmt), oa_report_get_ctx_id(timer_reports[i].report), delta, expected_report_timing_delta(delta, expected_timestamp_delta) ? "" : "******"); @@ -2705,13 +2733,14 @@ test_buffer_fill(const struct intel_execution_engine2 *e) /* ~5 micro second period */ int oa_exponent = max_oa_exponent_for_period_lte(5000); uint64_t oa_period = oa_exponent_to_ns(oa_exponent); + uint64_t fmt = test_set->perf_oa_format; uint64_t properties[] = { /* Include OA reports in samples */ DRM_I915_PERF_PROP_SAMPLE_OA, true, /* OA unit configuration */ DRM_I915_PERF_PROP_OA_METRICS_SET, test_set->perf_oa_metrics_set, - DRM_I915_PERF_PROP_OA_FORMAT, test_set->perf_oa_format, + DRM_I915_PERF_PROP_OA_FORMAT, fmt, DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent, DRM_I915_PERF_PROP_OA_ENGINE_CLASS, e->class, DRM_I915_PERF_PROP_OA_ENGINE_INSTANCE, e->instance, @@ -2728,7 +2757,7 @@ test_buffer_fill(const struct intel_execution_engine2 *e) uint8_t *buf = malloc(buf_size); int len; size_t oa_buf_size = MAX_OA_BUF_SIZE; - size_t report_size = get_oa_format(test_set->perf_oa_format).size; + size_t report_size = get_oa_format(fmt).size; int n_full_oa_reports = oa_buf_size / report_size; uint64_t fill_duration = n_full_oa_reports * oa_period; @@ -2803,17 +2832,17 @@ test_buffer_fill(const struct intel_execution_engine2 *e) 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 nb_periodic=%u\n", - report[1], - n_periodic_reports > 0 ? report[1] - last_periodic_report[1] : 0, + igt_debug(" > report ts=%"PRIu64"" + " ts_delta_last_periodic=%"PRIu64" is_timer=%i ctx_id=%8x nb_periodic=%u\n", + oa_timestamp(report, fmt), + n_periodic_reports > 0 ? oa_timestamp_delta(report, last_periodic_report, fmt) : 0, oa_report_is_periodic(oa_exponent, report), oa_report_get_ctx_id(report), n_periodic_reports); if (first_timestamp == 0) - first_timestamp = report[1]; - last_timestamp = report[1]; + first_timestamp = oa_timestamp(report, fmt); + last_timestamp = oa_timestamp(report, fmt); if (((last_timestamp - first_timestamp) * oa_period) < (fill_duration / 2)) break; @@ -2940,13 +2969,14 @@ test_enable_disable(const struct intel_execution_engine2 *e) /* ~5 micro second period */ int oa_exponent = max_oa_exponent_for_period_lte(5000); uint64_t oa_period = oa_exponent_to_ns(oa_exponent); + uint64_t fmt = test_set->perf_oa_format; uint64_t properties[] = { /* Include OA reports in samples */ DRM_I915_PERF_PROP_SAMPLE_OA, true, /* OA unit configuration */ DRM_I915_PERF_PROP_OA_METRICS_SET, test_set->perf_oa_metrics_set, - DRM_I915_PERF_PROP_OA_FORMAT, test_set->perf_oa_format, + DRM_I915_PERF_PROP_OA_FORMAT, fmt, DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent, DRM_I915_PERF_PROP_OA_ENGINE_CLASS, e->class, DRM_I915_PERF_PROP_OA_ENGINE_INSTANCE, e->instance, @@ -2962,7 +2992,7 @@ test_enable_disable(const struct intel_execution_engine2 *e) int buf_size = 65536 * (256 + sizeof(struct drm_i915_perf_record_header)); uint8_t *buf = malloc(buf_size); size_t oa_buf_size = MAX_OA_BUF_SIZE; - size_t report_size = get_oa_format(test_set->perf_oa_format).size; + size_t report_size = get_oa_format(fmt).size; int n_full_oa_reports = oa_buf_size / report_size; uint64_t fill_duration = n_full_oa_reports * oa_period; @@ -2975,7 +3005,7 @@ test_enable_disable(const struct intel_execution_engine2 *e) int len; uint32_t n_periodic_reports; struct drm_i915_perf_record_header *header; - uint32_t first_timestamp = 0, last_timestamp = 0; + uint64_t first_timestamp = 0, last_timestamp = 0; uint32_t last_periodic_report[64]; /* Giving enough time for an overflow might help catch whether @@ -3022,15 +3052,15 @@ test_enable_disable(const struct intel_execution_engine2 *e) break; case DRM_I915_PERF_RECORD_SAMPLE: if (first_timestamp == 0) - first_timestamp = report[1]; - last_timestamp = report[1]; + first_timestamp = oa_timestamp(report, fmt); + last_timestamp = oa_timestamp(report, fmt); - igt_debug(" > report ts=%8x" - " ts_delta_last_periodic=%s%8u" + igt_debug(" > report ts=%"PRIx64"" + " ts_delta_last_periodic=%s%"PRIu64"" " is_timer=%i ctx_id=0x%8x\n", - report[1], + oa_timestamp(report, fmt), oa_report_is_periodic(oa_exponent, report) ? " " : "*", - n_periodic_reports > 0 ? (report[1] - last_periodic_report[1]) : 0, + n_periodic_reports > 0 ? oa_timestamp_delta(report, last_periodic_report, fmt) : 0, oa_report_is_periodic(oa_exponent, report), oa_report_get_ctx_id(report)); @@ -3060,7 +3090,7 @@ test_enable_disable(const struct intel_execution_engine2 *e) do_ioctl(stream_fd, I915_PERF_IOCTL_DISABLE, 0); - igt_debug("first ts = %u, last ts = %u\n", first_timestamp, last_timestamp); + igt_debug("first ts = %lu, last ts = %lu\n", first_timestamp, last_timestamp); igt_debug("%f < %zu < %f\n", report_size * n_full_oa_reports * 0.45, @@ -3366,7 +3396,7 @@ gen12_test_mi_rpc(const struct intel_execution_engine2 *e) * size amount of data was written. */ igt_assert_eq(report32[0], REPORT_ID); - igt_assert_neq(report32[1], 0); + igt_assert(oa_timestamp(report32, test_set->perf_oa_format)); igt_assert_neq(report32[format.b_off >> 2], 0x80808080); igt_assert_eq(report32[format_size_32], 0x80808080); @@ -3427,7 +3457,7 @@ test_mi_rpc(void) report32 = buf->ptr; dump_report(report32, 64, "mi-rpc"); igt_assert_eq(report32[0], 0xdeadbeef); /* report ID */ - igt_assert_neq(report32[1], 0); /* timestamp */ + igt_assert(oa_timestamp(report32, test_set->perf_oa_format)); /* timestamp */ igt_assert_neq(report32[63], 0x80808080); /* end of report */ igt_assert_eq(report32[64], 0x80808080); /* after 256 byte report */ @@ -4166,9 +4196,9 @@ static void gen12_single_ctx_helper(const struct intel_execution_engine2 *e) uint32_t context0_id, context1_id; uint32_t *report0_32, *report1_32, *report2_32, *report3_32; uint64_t timestamp0_64, timestamp1_64; - uint32_t delta_ts64, delta_oa32; + uint64_t delta_ts64, delta_oa32; uint64_t delta_ts64_ns, delta_oa32_ns; - uint32_t delta_delta; + uint64_t delta_delta; int width = 800; int height = 600; #define INVALID_CTX_ID 0xffffffff @@ -4323,14 +4353,14 @@ static void gen12_single_ctx_helper(const struct intel_execution_engine2 *e) */ report0_32 = dst_buf->ptr; igt_assert_eq(report0_32[0], 0xdeadbeef); - igt_assert_neq(report0_32[1], 0); + igt_assert(oa_timestamp(report0_32, fmt)); ctx0_id = report0_32[2]; igt_debug("MI_RPC(start) CTX ID: %u\n", ctx0_id); dump_report(report0_32, 64, "report0_32"); report1_32 = report0_32 + 64; igt_assert_eq(report1_32[0], 0xbeefbeef); - igt_assert_neq(report1_32[1], 0); + igt_assert(oa_timestamp(report1_32, fmt)); ctx1_id = report1_32[2]; igt_debug("CTX ID1: %u\n", ctx1_id); dump_report(report1_32, 64, "report1_32"); @@ -4338,7 +4368,7 @@ static void gen12_single_ctx_helper(const struct intel_execution_engine2 *e) /* Verify that counters in context1 are all zeroes */ report2_32 = report0_32 + 128; igt_assert_eq(report2_32[0], 0x00c0ffee); - igt_assert_neq(report2_32[1], 0); + igt_assert(oa_timestamp(report2_32, fmt)); dump_report(report2_32, 64, "report2_32"); igt_assert_eq(0, memcmp(&report2_32[4], (uint8_t *) dst_buf->ptr + 2048, @@ -4346,7 +4376,7 @@ static void gen12_single_ctx_helper(const struct intel_execution_engine2 *e) report3_32 = report0_32 + 192; igt_assert_eq(report3_32[0], 0x01c0ffee); - igt_assert_neq(report3_32[1], 0); + igt_assert(oa_timestamp(report3_32, fmt)); dump_report(report3_32, 64, "report3_32"); igt_assert_eq(0, memcmp(&report3_32[4], (uint8_t *) dst_buf->ptr + 2048, @@ -4360,8 +4390,8 @@ static void gen12_single_ctx_helper(const struct intel_execution_engine2 *e) accumulator.deltas[2 + 21], accumulator.deltas[2 + 26]); - igt_debug("oa_timestamp32 0 = %u\n", report0_32[1]); - igt_debug("oa_timestamp32 1 = %u\n", report1_32[1]); + igt_debug("oa_timestamp32 0 = %"PRIu64"\n", oa_timestamp(report0_32, fmt)); + igt_debug("oa_timestamp32 1 = %"PRIu64"\n", oa_timestamp(report1_32, fmt)); igt_debug("ctx_id 0 = %u\n", report0_32[2]); igt_debug("ctx_id 1 = %u\n", report1_32[2]); @@ -4376,23 +4406,23 @@ static void gen12_single_ctx_helper(const struct intel_execution_engine2 *e) igt_debug("ts_timestamp64 1 = %"PRIu64"\n", timestamp1_64); delta_ts64 = timestamp1_64 - timestamp0_64; - delta_oa32 = report1_32[1] - report0_32[1]; + delta_oa32 = oa_timestamp_delta(report1_32, report0_32, fmt); /* Sanity check that we can pass the delta to timebase_scale */ - igt_assert(delta_ts64 < UINT32_MAX); delta_oa32_ns = timebase_scale(delta_oa32); delta_ts64_ns = cs_timebase_scale(delta_ts64); - igt_debug("oa32 delta = %u, = %uns\n", - delta_oa32, (unsigned)delta_oa32_ns); - igt_debug("ts64 delta = %u, = %uns\n", - delta_ts64, (unsigned)delta_ts64_ns); + igt_debug("oa32 delta = %"PRIu64", = %"PRIu64"ns\n", + delta_oa32, delta_oa32_ns); + igt_debug("ts64 delta = %"PRIu64", = %"PRIu64"ns\n", + delta_ts64, delta_ts64_ns); delta_delta = delta_ts64_ns > delta_oa32_ns ? (delta_ts64_ns - delta_oa32_ns) : (delta_oa32_ns - delta_ts64_ns); if (delta_delta > 500) { - igt_debug("delta_delta exceeds margin, skipping..\n"); + igt_debug("delta_delta = %"PRIu64". exceeds margin, skipping..\n", + delta_delta); exit(EAGAIN); } -- 2.36.1