[PATCH i-g-t v2 3/4] tests/intel/xe_oa: Add a test for tail address wrap
Dixit, Ashutosh
ashutosh.dixit at intel.com
Wed Aug 27 18:38:15 UTC 2025
On Tue, 26 Aug 2025 15:43:00 -0700, Umesh Nerlige Ramappa wrote:
>
> Add a test to verify that the HW wraps to start of the OA buffer when a
> report does not fit in the remaining space in the buffer.
>
> v2:
> - Make test more robust
>
> Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa at intel.com>
> ---
> tests/intel/xe_oa.c | 97 +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 97 insertions(+)
>
> diff --git a/tests/intel/xe_oa.c b/tests/intel/xe_oa.c
> index d10ef00d6abc..24442e4b83c6 100644
> --- a/tests/intel/xe_oa.c
> +++ b/tests/intel/xe_oa.c
> @@ -4537,6 +4537,95 @@ static void closed_fd_and_unmapped_access(const struct drm_xe_engine_class_insta
> try_invalid_access(vaddr);
> }
>
> +static void read_reports(int fd, uint8_t *buf, size_t size)
> +{
> + int len, total = 0;
> +
> + while (total < size) {
> + len = read(fd, &buf[total], size - total);
> + if (len == -1 && (errno == EIO || errno == EINTR))
> + continue;
> +
> + igt_assert(len);
> + total += len;
> + }
> +}
> +
> +/**
> + * SUBTEST: tail-address-wrap
> + * Description: Test tail address wrap on odd format sizes. Ensure that the
> + * format size is not a power of 2. This means that the last report will not be
> + * broken down across the OA buffer end. Instead it will be written to the
> + * beginning of the OA buffer. We will check the end of the buffer to ensure it
> + * has zeroes in it.
> + */
> +static void
> +test_tail_address_wrap(const struct drm_xe_engine_class_instance *hwe, size_t oa_buffer_size)
> +{
> + struct intel_xe_perf_metric_set *test_set = metric_set(hwe);
> + uint64_t exponent = max_oa_exponent_for_period_lte(20000);
> + uint64_t buffer_size = oa_buffer_size ?: buffer_fill_size;
We are providing oa_buffer_size in the caller, so maybe can just use
oa_buffer_size? But otherwise ok to leave as is too.
> + uint64_t fmt = test_set->perf_oa_format;
> + uint64_t properties[] = {
> + DRM_XE_OA_PROPERTY_OA_UNIT_ID, 0,
> + DRM_XE_OA_PROPERTY_SAMPLE_OA, true,
> + DRM_XE_OA_PROPERTY_OA_METRIC_SET, test_set->perf_oa_metrics_set,
> + DRM_XE_OA_PROPERTY_OA_FORMAT, __ff(fmt),
> + DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT, exponent,
> + DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE, hwe->engine_instance,
> + DRM_XE_OA_PROPERTY_OA_BUFFER_SIZE, buffer_size,
> + DRM_XE_OA_PROPERTY_OA_DISABLED, true,
> + };
> + struct intel_xe_oa_open_prop param = {
> + .num_properties = ARRAY_SIZE(properties) / 2,
> + .properties_ptr = to_user_pointer(properties),
> + };
> + uint32_t fmt_size = get_oa_format(fmt).size;
> + uint32_t fit_reports = buffer_size / fmt_size;
> + uint32_t extra_reports = 10;
> + uint32_t total_reports = fit_reports + extra_reports;
> + uint32_t total_size = total_reports * fmt_size;
> + uint8_t *buf = malloc(total_size);
> +
> + uint32_t wrap_offset = (fit_reports * fmt_size) >> 2;
> + uint32_t end_offset = buffer_size >> 2;
> + uint32_t *zero_area, *buffer_end, *buffer_start;
You can just use u32, instead of the longer uint32_t, for these...
> + int i;
> +
> + /* Ensure report does not fit */
This comment needs to be more specific, or just drop it.
> + igt_require(wrap_offset < end_offset);
> +
> + stream_fd = __perf_open(drm_fd, ¶m, false);
> +
> + /* Read fit_reports + extra_reports */
> + do_ioctl(stream_fd, DRM_XE_OBSERVATION_IOCTL_ENABLE, 0);
> + read_reports(stream_fd, buf, total_size);
> + do_ioctl(stream_fd, DRM_XE_OBSERVATION_IOCTL_DISABLE, 0);
> +
> + /* Quick check for valid reports */
> + for (i = 0; i < total_reports; i++) {
> + uint32_t *report = (uint32_t *)&buf[i * fmt_size];
> +
> + igt_assert(report_reason(report) && oa_timestamp(report, fmt));
> + }
> +
> + /* mmap the buffer and check that the end of the buffer has zeroes */
> + buffer_start = mmap(0, buffer_size, PROT_READ, MAP_PRIVATE, stream_fd, 0);
> + igt_assert(buffer_start);
> +
> + zero_area = buffer_start + wrap_offset;
> + buffer_end = buffer_start + end_offset;
> +
> + /* Ensure HW did not write to this area */
> + while (zero_area < buffer_end)
> + igt_assert_eq(*zero_area++, 0);
> +
> + munmap(buffer_start, buffer_size);
> +
> + __perf_close(stream_fd);
> + free(buf);
> +}
> +
> /**
> * SUBTEST: map-oa-buffer
> * Description: Verify mapping of oa buffer
> @@ -5095,6 +5184,14 @@ igt_main
> closed_fd_and_unmapped_access(hwe);
> }
>
> + igt_subtest_with_dynamic("tail-address-wrap") {
> + long k = random() % num_buf_sizes;
> +
> + igt_require(oau->capabilities & DRM_XE_OA_CAPS_OA_BUFFER_SIZE);
> + __for_one_hwe_in_oag_w_arg(hwe, buf_sizes[k].name)
> + test_tail_address_wrap(hwe, buf_sizes[k].size);
> + }
> +
> igt_subtest_group {
> igt_fixture {
> perf_init_whitelist();
Otherwise, this is also:
Reviewed-by: Ashutosh Dixit <ashutosh.dixit at intel.com>
More information about the igt-dev
mailing list