summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanusz Krzysztofik <janusz.krzysztofik@linux.intel.com>2020-09-08 17:06:58 +0200
committerJanusz Krzysztofik <janusz.krzysztofik@linux.intel.com>2020-09-14 20:50:27 +0200
commitfee1ccb45d3127ccb8b2a7838b811a18fae617d9 (patch)
tree04e308c82726821f417821d1926727af8d017682
parent4d89e7e2a67f75ea82c1c9c703e08d8ccda2add7 (diff)
tests/core_hotunplug: Check health both before and after late close
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 device file descriptors in our private data structure. Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com> Reviewed-by: MichaƂ Winiarski <michal.winiarski@intel.com>
-rw-r--r--tests/core_hotunplug.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
index 436517ce..ac106d96 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;
@@ -200,7 +201,9 @@ static void bus_rescan(struct hotunplug *priv, int timeout)
static void cleanup(struct hotunplug *priv)
{
- priv->fd.drm = close_device(priv->fd.drm, "post ", "failed ");
+ priv->fd.drm = close_device(priv->fd.drm, "post ", "exercised ");
+ priv->fd.drm_hc = close_device(priv->fd.drm_hc, "post ",
+ "health checked ");
priv->fd.sysfs_dev = close_sysfs(priv->fd.sysfs_dev);
}
@@ -286,14 +289,14 @@ static void node_healthcheck(struct hotunplug *priv, unsigned flags)
{
bool render = flags & FLAG_RENDER;
/* preserve potentially dirty device status stored in priv->fd.drm */
- bool closed = priv->fd.drm == -1;
+ bool closed = priv->fd.drm_hc == -1;
int fd_drm;
priv->failure = render ? "Render device reopen failure!" :
"DRM device reopen failure!";
fd_drm = local_drm_open_driver(render, "re", " for health check");
if (closed) /* store fd for cleanup if not dirty */
- priv->fd.drm = fd_drm;
+ priv->fd.drm_hc = fd_drm;
if (is_i915_device(fd_drm)) {
/* don't report library failed asserts as healthcheck failure */
@@ -311,7 +314,7 @@ static void node_healthcheck(struct hotunplug *priv, unsigned flags)
fd_drm = close_device(fd_drm, "", "health checked ");
if (closed || fd_drm < -1) /* update status for post_healthcheck */
- priv->fd.drm = fd_drm;
+ priv->fd.drm_hc = fd_drm;
}
static void healthcheck(struct hotunplug *priv, bool recover)
@@ -334,7 +337,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))
@@ -353,6 +356,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)
@@ -375,6 +379,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);
@@ -386,6 +391,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);
@@ -397,6 +403,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 hot unbind");
driver_unbind(priv, "hot ", 0);
@@ -412,6 +419,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 hot unplug");
device_unplug(priv, "hot ", 0);
@@ -427,12 +435,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 hot rebind");
driver_unbind(priv, "hot ", 60);
driver_bind(priv, 0);
+ healthcheck(priv, false);
+
priv->fd.drm = close_device(priv->fd.drm, "late ", "unbound ");
igt_assert_eq(priv->fd.drm, -1);
@@ -442,12 +453,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 hot replug");
device_unplug(priv, "hot ", 60);
bus_rescan(priv, 0);
+ healthcheck(priv, false);
+
priv->fd.drm = close_device(priv->fd.drm, "late ", "removed ");
igt_assert_eq(priv->fd.drm, -1);
@@ -459,7 +473,7 @@ static void hotreplug_lateclose(struct hotunplug *priv)
igt_main
{
struct hotunplug priv = {
- .fd = { .drm = -1, .sysfs_dev = -1, },
+ .fd = { .drm = -1, .drm_hc = -1, .sysfs_dev = -1, },
.failure = NULL,
};