[igt-dev] [PATCH i-g-t 04/10] tests/perf: add tests to new OA reconfiguration execbuf extension

Lionel Landwerlin
2019-07-25T10:30:57Z

This is just basic validation of the input.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
tests/perf.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+)

diff --git a/tests/perf.c b/tests/perf.c
index 3bbc898a..1152ab73 100644
--- a/tests/perf.c
+++ b/tests/perf.c
@@ -4051,6 +4051,19 @@ static bool has_i915_perf_disable_preemption_support(int fd)
return perf_version >= 2;
}

+static bool has_i915_exec_perf(int fd)
+{
+ struct drm_i915_getparam gp;
+ int perf_config = 0;
+
+ memset(&gp, 0, sizeof(gp));
+ gp.param = I915_PARAM_HAS_EXEC_PERF_CONFIG;
+ gp.value = &perf_config;
+ igt_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+
+ return perf_config != 0;
+}
+
static uint32_t *
fill_relocation(uint32_t *batch,
struct drm_i915_gem_relocation_entry *reloc,
@@ -4493,6 +4506,124 @@ test_invalid_disabled_preemption(void)
do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
}

+/* Test that requesting OA reconfiguration through execubffer fails if
+ * the parameters are invalid.
+ */
+static void
+test_exec_perf_invalid(void)
+{
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_perf perf_config;
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.flags = I915_EXEC_EXT;
+ execbuf.cliprects_ptr = to_user_pointer(&perf_config);
+ execbuf.num_cliprects = 0;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(drm_fd, 4096);
+ gem_write(drm_fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+ /* Invalid perf fd */
+ memset(&perf_config, 0, sizeof(perf_config));
+ perf_config.base.name = DRM_I915_GEM_EXECBUFFER_EXT_PERF;
+ perf_config.perf_fd = -1;
+ perf_config.oa_config = test_metric_set_id;
+ igt_assert_eq(__gem_execbuf(drm_fd, &execbuf), -EINVAL);
+
+ {
+ 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_metric_set_id,
+ DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
+ DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
+ };
+ struct drm_i915_perf_open_param param = {
+ .flags = I915_PERF_FLAG_FD_CLOEXEC |
+ I915_PERF_FLAG_FD_NONBLOCK,
+ .num_properties = sizeof(properties) / 16,
+ .properties_ptr = to_user_pointer(properties),
+ };
+
+ stream_fd = __perf_open(drm_fd, &param, false);
+ }
+
+ /* Invalid perf fd */
+ memset(&perf_config, 0, sizeof(perf_config));
+ perf_config.base.name = DRM_I915_GEM_EXECBUFFER_EXT_PERF;
+ perf_config.perf_fd = stream_fd + 1;
+ perf_config.oa_config = test_metric_set_id;
+ igt_assert_eq(__gem_execbuf(drm_fd, &execbuf), -EINVAL);
+
+ /* Invalid OA config */
+ memset(&perf_config, 0, sizeof(perf_config));
+ perf_config.base.name = DRM_I915_GEM_EXECBUFFER_EXT_PERF;
+ perf_config.perf_fd = stream_fd;
+ perf_config.oa_config = UINT64_MAX;
+ igt_assert_eq(__gem_execbuf(drm_fd, &execbuf), -EINVAL);
+
+ gem_close(drm_fd, obj.handle);
+ __perf_close(stream_fd);
+}
+
+static void
+test_exec_perf(void)
+{
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_perf perf_config;
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.flags = I915_EXEC_EXT;
+ execbuf.cliprects_ptr = to_user_pointer(&perf_config);
+ execbuf.num_cliprects = 0;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(drm_fd, 4096);
+ gem_write(drm_fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+ {
+ 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_metric_set_id,
+ DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
+ DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
+ };
+ struct drm_i915_perf_open_param param = {
+ .flags = I915_PERF_FLAG_FD_CLOEXEC |
+ I915_PERF_FLAG_FD_NONBLOCK,
+ .num_properties = sizeof(properties) / 16,
+ .properties_ptr = to_user_pointer(properties),
+ };
+
+ stream_fd = __perf_open(drm_fd, &param, false);
+ }
+
+ memset(&perf_config, 0, sizeof(perf_config));
+ perf_config.base.name = DRM_I915_GEM_EXECBUFFER_EXT_PERF;
+ perf_config.perf_fd = stream_fd;
+ perf_config.oa_config = test_metric_set_id;
+ gem_execbuf(drm_fd, &execbuf);
+
+ gem_wait(drm_fd, obj.handle, NULL);
+
+ gem_close(drm_fd, obj.handle);
+ __perf_close(stream_fd);
+}
+
static unsigned
read_i915_module_ref(void)
{
@@ -4746,6 +4877,18 @@ igt_main
test_invalid_disabled_preemption();
}

+ igt_subtest_group {
+ igt_fixture {
+ igt_require(has_i915_exec_perf(drm_fd));
+ }
+
+ igt_subtest("exec-perf-invalid")
+ test_exec_perf_invalid();
+
+ igt_subtest("exec-perf")
+ test_exec_perf();
+ }
+
igt_fixture {
/* leave sysctl options in their default state... */
write_u64_file("/proc/sys/dev/i915/oa_max_sample_rate", 100000);