@@ -433,6 +433,13 @@ static void set_filter_from_device(int fd)
igt_assert_eq(igt_device_filter_add(filter), 1);
}
+static int local_gem_close(int fd, uint32_t handle)
+{
+ struct drm_gem_close close_bo = { .handle = handle, };
+
+ return igt_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo) ? -errno : 0;
+}
+
/* Subtests */
static void unbind_rebind(struct hotunplug *priv)
@@ -655,6 +662,60 @@ static void vm_hotunplug_lateclose(struct hotunplug *priv)
igt_assert_eq(priv->fd.drm, -1);
}
+static void gem_hotunbind_lateclose(struct hotunplug *priv)
+{
+ uint32_t handle;
+
+ igt_require(priv->fd.drm = -1);
+ priv->fd.drm = local_drm_open_driver(false, "pre-", " for prerequisites check");
+
+ igt_require_intel(priv->fd.drm);
+ igt_require_gem(priv->fd.drm);
+ priv->fd.drm = close_device(priv->fd.drm, "", "pre-checked ");
+
+ pre_check(priv);
+
+ priv->fd.drm = local_drm_open_driver(false, "", " for hot unbind");
+
+ local_debug("%s\n", "creating a GEM user object");
+ handle = gem_create(priv->fd.drm, 4096);
+
+ driver_unbind(priv, "hot", 0);
+
+ local_debug("%s\n", "trying to late remove the object");
+ igt_assert_eq(local_gem_close(priv->fd.drm, handle), -ENODEV);
+
+ priv->fd.drm = close_device(priv->fd.drm, "late ", "unbound ");
+ igt_assert_eq(priv->fd.drm, -1);
+}
+
+static void gem_hotunplug_lateclose(struct hotunplug *priv)
+{
+ uint32_t handle;
+
+ igt_require(priv->fd.drm = -1);
+ priv->fd.drm = local_drm_open_driver(false, "pre-", " for prerequisites check");
+
+ igt_require_intel(priv->fd.drm);
+ igt_require_gem(priv->fd.drm);
+ priv->fd.drm = close_device(priv->fd.drm, "", "pre-checked ");
+
+ pre_check(priv);
+
+ priv->fd.drm = local_drm_open_driver(false, "", " for hot unplug");
+
+ local_debug("%s\n", "creating a GEM user object");
+ handle = gem_create(priv->fd.drm, 4096);
+
+ device_unplug(priv, "hot", 0);
+
+ local_debug("%s\n", "trying to late remove the object");
+ igt_assert_eq(local_gem_close(priv->fd.drm, handle), -ENODEV);
+
+ priv->fd.drm = close_device(priv->fd.drm, "late ", "removed ");
+ igt_assert_eq(priv->fd.drm, -1);
+}
+
/* Main */
igt_main
@@ -840,6 +901,30 @@ igt_main
recover(&priv);
}
+ igt_fixture
+ post_healthcheck(&priv);
+
+ igt_subtest_group {
+ igt_describe("Check if the driver can be cleanly unbound from a device with a still open GEM object, then released");
+ igt_subtest("gem-hotunbind-lateclose")
+ gem_hotunbind_lateclose(&priv);
+
+ igt_fixture
+ recover(&priv);
+ }
+
+ igt_fixture
+ post_healthcheck(&priv);
+
+ igt_subtest_group {
+ igt_describe("Check if a device with a still open GEM object can be cleanly unplugged, then released");
+ igt_subtest("gem-hotunplug-lateclose")
+ gem_hotunplug_lateclose(&priv);
+
+ igt_fixture
+ recover(&priv);
+ }
+
igt_fixture {
post_healthcheck(&priv);
GEM objects belonging to user file descriptors still open on device hotunbind / hotunplug may exhibit still more driver issues. Add subtests that implements these scenarios. Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com> --- tests/core_hotunplug.c | 85 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+)