[igt-dev] [PATCH 2/2] i915/perf: Sanity check reports in mapped OA buffer

Lionel Landwerlin lionel.g.landwerlin at intel.com
Tue Jul 21 06:21:44 UTC 2020


Looks good, just one nit and a test suggestion.

On 21/07/2020 04:57, Umesh Nerlige Ramappa wrote:
> For applications that need a faster way to access reports in the OA
> buffer, i915 now provides a way to map the OA buffer to privileged user
> space. Add a test to sanity check reports in the mapped OA buffer.
>
> Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa at intel.com>
> ---
>   include/drm-uapi/i915_drm.h |  32 +++++
>   tests/i915/perf.c           | 241 ++++++++++++++++++++++++++++++++++++
>   2 files changed, 273 insertions(+)
>
> diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
> index 2b55af13..f7523d55 100644
> --- a/include/drm-uapi/i915_drm.h
> +++ b/include/drm-uapi/i915_drm.h
> @@ -2048,6 +2048,38 @@ struct drm_i915_perf_open_param {
>    */
>   #define I915_PERF_IOCTL_CONFIG	_IO('i', 0x2)
>   
> +/**
> + * Returns OA buffer properties to be used with mmap.
> + *
> + * This ioctl is available in perf revision 6.
> + */
> +#define I915_PERF_IOCTL_GET_OA_BUFFER_INFO _IO('i', 0x3)
> +
> +/**
> + * OA buffer size and offset.
> + */
> +struct drm_i915_perf_oa_buffer_info {
> +	__u32 size;
> +	__u32 offset;
> +	__u64 reserved[4];
> +};
> +
> +/**
> + * Returns current position of OA buffer head and tail.
> + *
> + * This ioctl is available in perf revision 6.
> + */
> +#define I915_PERF_IOCTL_GET_OA_BUFFER_HEAD_TAIL _IO('i', 0x4)
> +
> +/**
> + * OA buffer head and tail.
> + */
> +struct drm_i915_perf_oa_buffer_head_tail {
> +	__u32 head;
> +	__u32 tail;
> +	__u64 reserved[4];
> +};

We should probably test head/tail values.

Open the stream with a fast enough exponent and verify they loop correctly?

> +
>   /**
>    * Common to all i915 perf records
>    */
> diff --git a/tests/i915/perf.c b/tests/i915/perf.c
> index eb38ea12..b7aa1596 100644
> --- a/tests/i915/perf.c
> +++ b/tests/i915/perf.c
> @@ -206,6 +206,7 @@ static struct intel_perf *intel_perf = NULL;
>   static struct intel_perf_metric_set *test_set = NULL;
>   static bool *undefined_a_counters;
>   static uint64_t oa_exp_1_millisec;
> +struct intel_mmio_data mmio_data;
>   
>   static igt_render_copyfunc_t render_copy = NULL;
>   static uint32_t (*read_report_ticks)(uint32_t *report,
> @@ -5011,6 +5012,220 @@ test_whitelisted_registers_userspace_config(void)
>   	i915_perf_remove_config(drm_fd, config_id);
>   }
>   
> +#define OA_BUFFER_DATA(tail, head, oa_buffer_size) \
> +	(((tail) - (head)) & ((oa_buffer_size) - 1))
> +
> +#ifndef MAP_FAILED
> +#define MAP_FAILED ((void *)-1)
> +#endif
> +
> +static uint32_t oa_status_reg(void)
> +{
> +	if (IS_HASWELL(devid))
> +		return intel_register_read(&mmio_data, 0x2346) & 0x7;
> +	else if (IS_GEN12(devid))
> +		return intel_register_read(&mmio_data, 0xdafc) & 0x7;
> +	else
> +		return intel_register_read(&mmio_data, 0x2b08) & 0xf;
> +}
> +
> +static void invalid_map_oa_buffer(void)
> +{
> +	struct drm_i915_perf_oa_buffer_info oa_buffer;
> +	void *oa_vaddr = NULL;
> +
> +	do_ioctl(stream_fd, I915_PERF_IOCTL_GET_OA_BUFFER_INFO, &oa_buffer);
> +
> +	igt_debug("size        = %d\n", oa_buffer.size);
> +	igt_debug("offset      = %x\n", oa_buffer.offset);
> +
> +	igt_assert_eq(oa_buffer.size & (oa_buffer.size - 1), 0);
> +
> +	/* try a couple invalid mmaps */
> +	/* bad offsets */
> +	oa_vaddr = mmap(0, oa_buffer.size, PROT_READ, MAP_PRIVATE, stream_fd, 0);
> +	igt_assert(oa_vaddr == MAP_FAILED);
> +
> +	oa_vaddr = mmap(0, oa_buffer.size, PROT_READ, MAP_PRIVATE, stream_fd, 8192);
> +	igt_assert(oa_vaddr == MAP_FAILED);
> +
> +	oa_vaddr = mmap(0, oa_buffer.size, PROT_READ, MAP_PRIVATE, stream_fd, 11);
> +	igt_assert(oa_vaddr == MAP_FAILED);
> +
> +	/* bad size */
> +	oa_vaddr = mmap(0, oa_buffer.size + 1, PROT_READ, MAP_PRIVATE, stream_fd, oa_buffer.offset);
> +	igt_assert(oa_vaddr == MAP_FAILED);
> +
> +	/* do the right thing */
> +	oa_vaddr = mmap(0, oa_buffer.size, PROT_READ, MAP_PRIVATE, stream_fd, oa_buffer.offset);
> +	igt_assert(oa_vaddr != NULL);

oa_vaddr != NULL && oa_vaddr != MAP_FAILED ;)


> +
> +	munmap(oa_vaddr, oa_buffer.size);
> +}
> +
> +static void *map_oa_buffer(uint32_t *size)
> +{

> ...

> +
>   static unsigned
>   read_i915_module_ref(void)
>   {
> @@ -5179,6 +5394,9 @@ igt_main
>   
>   		render_copy = igt_get_render_copyfunc(devid);
>   		igt_require_f(render_copy, "no render-copy function\n");
> +
> +		intel_register_access_init(&mmio_data, intel_get_pci_device(),
> +					   0, drm_fd);
>   	}
>   
>   	igt_subtest("non-system-wide-paranoid")
> @@ -5346,6 +5564,28 @@ igt_main
>   		test_triggered_oa_reports();
>   	}
>   
> +	igt_subtest_group {
> +		igt_fixture {
> +			igt_require(i915_perf_revision(drm_fd) >= 8);
> +		}
> +
> +		igt_describe("Verify mapping of oa buffer");
> +		igt_subtest("map-oa-buffer")
> +			test_mapped_oa_buffer(check_reports_from_mapped_buffer);
> +
> +		igt_describe("Verify invalid mappings of oa buffer");
> +		igt_subtest("invalid-map-oa-buffer")
> +			test_mapped_oa_buffer(invalid_map_oa_buffer);
> +
> +		igt_describe("Verify if non-privileged user can map oa buffer");
> +		igt_subtest("non-privileged-map-oa-buffer")
> +			test_mapped_oa_buffer(test_unprivileged_map_oa_buffer);
> +
> +		igt_describe("Close FD and access oa buffer");
> +		igt_subtest("close-fd-and-access-oa-buffer")
> +			close_fd_and_access_oa_buffer();

I think one additional test that would be helpful is to do the following :


for (i = 0; i < 256; i++) {

   int fd = perf_open();

   void *ptr = mmap(fd);

   close(fd);

}

16Mb * 256 = 4Gb

That way you verify that we're not leaking GGTT space when closing the 
perf fd.

You might want to tweak the noa_wait sysfs value before/after the loop.

This might also only work on !32bits machines with enough memory...


-Lionel


> +	}
> +
>   	igt_fixture {
>   		/* leave sysctl options in their default state... */
>   		write_u64_file("/proc/sys/dev/i915/oa_max_sample_rate", 100000);
> @@ -5354,6 +5594,7 @@ igt_main
>   		if (intel_perf)
>   			intel_perf_free(intel_perf);
>   
> +		intel_register_access_fini(&mmio_data);
>   		close(drm_fd);
>   	}
>   }




More information about the igt-dev mailing list