[PATCH i-g-t v6 20/23] tests/core_hotunplug: Check health both before and after late close

Janusz Krzysztofik janusz.krzysztofik at linux.intel.com
Tue Sep 8 15:12:57 UTC 2020


In hot rebind / hot replug subtests, device health is now checked only
at the end of the subtest, after late close.  If something fails, we
may be not able to identify the failing phase of the subtest easily.

Run health checks also before late closing the device, right after hot
rebind / replug.  For still being able to perform late close while also
handling cleanup of potential device close misses in health checks, we
need to maintain two separate file descriptors in our private data
structure.

Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik at linux.intel.com>
---
 tests/core_hotunplug.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
index 591a6a1ce..91b3caeda 100644
--- a/tests/core_hotunplug.c
+++ b/tests/core_hotunplug.c
@@ -42,6 +42,7 @@ IGT_TEST_DESCRIPTION("Examine behavior of a driver on device hot unplug");
 struct hotunplug {
 	struct {
 		int drm;
+		int drm_hc;	/* for health check */
 		int sysfs_dev;
 		int sysfs_bus;
 		int sysfs_drv;
@@ -198,6 +199,7 @@ static void bus_rescan(struct hotunplug *priv, int timeout)
 static void cleanup(struct hotunplug *priv)
 {
 	priv->fd.drm = close_device(priv->fd.drm);
+	priv->fd.drm_hc = close_device(priv->fd.drm_hc);
 	priv->fd.sysfs_dev = close_sysfs(priv->fd.sysfs_dev);
 }
 
@@ -282,14 +284,14 @@ static int local_i915_recover(int i915)
 static void node_healthcheck(struct hotunplug *priv, unsigned flags)
 {
 	bool render = flags & FLAG_RENDER;
-	/* preserve error code potentially stored before in priv->fd.drm */
+	/* preserve error code potentially stored before in priv->fd.drm_hc */
 	int fd_drm;
 
 	priv->failure = render ? "Render device reopen failure!" :
 				 "DRM device reopen failure!";
 	fd_drm = local_drm_open_driver(render, "re", " for healthcheck");
-	if (priv->fd.drm == -1)	/* store for cleanup if no error to preserve */
-		priv->fd.drm = fd_drm;
+	if (priv->fd.drm_hc == -1)	/* store for cleanup if not dirty */
+		priv->fd.drm_hc = fd_drm;
 
 	if (is_i915_device(fd_drm)) {
 		/* don't report library failed asserts as healthcheck failure */
@@ -308,7 +310,7 @@ static void node_healthcheck(struct hotunplug *priv, unsigned flags)
 	fd_drm = close_device(fd_drm);
 	/* no reason to preserve previous close result on error */
 	if (fd_drm < -1)
-		priv->fd.drm = fd_drm;
+		priv->fd.drm_hc = fd_drm;
 
 	/* not only request igt_abort on failure, also fail the health check */
 	igt_fail_on_f(priv->failure, "%s\n", priv->failure);
@@ -329,7 +331,7 @@ static void recover(struct hotunplug *priv)
 
 	/* unbind the driver from a possibly hot rebound unhealthy device */
 	if (!faccessat(priv->fd.sysfs_drv, priv->dev_bus_addr, F_OK, 0) &&
-	    priv->fd.drm == -1 && priv->failure)
+	    priv->fd.drm == -1 && priv->fd.drm_hc == -1 && priv->failure)
 		driver_unbind(priv, "post ", 60);
 
 	if (faccessat(priv->fd.sysfs_bus, priv->dev_bus_addr, F_OK, 0))
@@ -348,6 +350,7 @@ static void post_healthcheck(struct hotunplug *priv)
 
 	cleanup(priv);
 	igt_require(priv->fd.drm == -1);
+	igt_require(priv->fd.drm_hc == -1);
 }
 
 static void set_filter_from_device(int fd)
@@ -370,6 +373,7 @@ static void set_filter_from_device(int fd)
 static void unbind_rebind(struct hotunplug *priv)
 {
 	igt_assert_eq(priv->fd.drm, -1);
+	igt_assert_eq(priv->fd.drm_hc, -1);
 
 	driver_unbind(priv, "", 0);
 
@@ -381,6 +385,7 @@ static void unbind_rebind(struct hotunplug *priv)
 static void unplug_rescan(struct hotunplug *priv)
 {
 	igt_assert_eq(priv->fd.drm, -1);
+	igt_assert_eq(priv->fd.drm_hc, -1);
 
 	device_unplug(priv, "", 0);
 
@@ -392,6 +397,7 @@ static void unplug_rescan(struct hotunplug *priv)
 static void hotunbind_rebind(struct hotunplug *priv)
 {
 	igt_assert_eq(priv->fd.drm, -1);
+	igt_assert_eq(priv->fd.drm_hc, -1);
 	priv->fd.drm = local_drm_open_driver(false, "", " for hotunbind");
 
 	driver_unbind(priv, "hot ", 0);
@@ -408,6 +414,7 @@ static void hotunbind_rebind(struct hotunplug *priv)
 static void hotunplug_rescan(struct hotunplug *priv)
 {
 	igt_assert_eq(priv->fd.drm, -1);
+	igt_assert_eq(priv->fd.drm_hc, -1);
 	priv->fd.drm = local_drm_open_driver(false, "", " for hotunplug");
 
 	device_unplug(priv, "hot ", 0);
@@ -424,12 +431,15 @@ static void hotunplug_rescan(struct hotunplug *priv)
 static void hotrebind_lateclose(struct hotunplug *priv)
 {
 	igt_assert_eq(priv->fd.drm, -1);
+	igt_assert_eq(priv->fd.drm_hc, -1);
 	priv->fd.drm = local_drm_open_driver(false, "", " for hotrebind");
 
 	driver_unbind(priv, "hot ", 60);
 
 	driver_bind(priv, 0);
 
+	healthcheck(priv, false);
+
 	igt_debug("late closing the unbound device instance\n");
 	priv->fd.drm = close_device(priv->fd.drm);
 	igt_assert_eq(priv->fd.drm, -1);
@@ -440,12 +450,15 @@ static void hotrebind_lateclose(struct hotunplug *priv)
 static void hotreplug_lateclose(struct hotunplug *priv)
 {
 	igt_assert_eq(priv->fd.drm, -1);
+	igt_assert_eq(priv->fd.drm_hc, -1);
 	priv->fd.drm = local_drm_open_driver(false, "", " for hotreplug");
 
 	device_unplug(priv, "hot ", 60);
 
 	bus_rescan(priv, 0);
 
+	healthcheck(priv, false);
+
 	igt_debug("late closing the removed device instance\n");
 	priv->fd.drm = close_device(priv->fd.drm);
 	igt_assert_eq(priv->fd.drm, -1);
-- 
2.21.1



More information about the Intel-gfx-trybot mailing list