[igt-dev] [PATCH i-g-t 1/2] tests/kms_flip: Check for link reset during TS calibration as well
Imre Deak
imre.deak at intel.com
Tue Jun 30 16:03:43 UTC 2020
The timestamp calibration can fail when using certain monitors with a
behavior described in
commit 60e8be7ccc72086a88d2eff3bcd02495fad5fa46
Author: Imre Deak <imre.deak at intel.com>
Date: Mon May 11 22:08:53 2020 +0300
tests/kms_flip: Retry test in case of a DP/HDMI link reset
As in the above commit, retry the calibration once if a hotplug was
detected during the calibration.
Signed-off-by: Imre Deak <imre.deak at intel.com>
---
tests/kms_flip.c | 75 +++++++++++++++++++++++++++++++++---------------
1 file changed, 52 insertions(+), 23 deletions(-)
diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index 3a7314ad..86c5e871 100755
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -1115,7 +1115,7 @@ static void free_test_output(struct test_output *o)
}
}
-static void calibrate_ts(struct test_output *o, int crtc_idx)
+static bool calibrate_ts(struct test_output *o, int crtc_idx)
{
#define CALIBRATE_TS_STEPS 16
drmVBlank wait;
@@ -1125,6 +1125,7 @@ static void calibrate_ts(struct test_output *o, int crtc_idx)
double expected;
double mean;
double stddev;
+ bool failed = false;
int n;
memset(&wait, 0, sizeof(wait));
@@ -1176,7 +1177,18 @@ static void calibrate_ts(struct test_output *o, int crtc_idx)
igt_assert_eq(errno, EINTR);
}
igt_assert(read(drm_fd, &ev, sizeof(ev)) == sizeof(ev));
- igt_assert_eq(ev.sequence, last_seq + 1);
+
+ if (failed)
+ continue;
+
+ if (ev.sequence != last_seq + 1) {
+ igt_debug("Unexpected frame sequence %d vs. expected %d\n",
+ ev.sequence, last_seq + 1);
+ failed = true;
+
+ /* Continue to flush all the events queued up */
+ continue;
+ }
now = ev.tv_sec;
now *= 1000000;
@@ -1188,6 +1200,9 @@ static void calibrate_ts(struct test_output *o, int crtc_idx)
last_seq = ev.sequence;
}
+ if (failed)
+ return false;
+
expected = mode_frame_time(o);
mean = igt_stats_get_mean(&stats);
@@ -1207,6 +1222,30 @@ static void calibrate_ts(struct test_output *o, int crtc_idx)
}
o->vblank_interval = mean;
+
+ return true;
+}
+
+/*
+ * Some monitors with odd behavior signal a bad link after waking from a power
+ * saving state and the subsequent (successful) modeset. This will result in a
+ * link-retraining (DP) or async modeset (HDMI), which in turn makes the test
+ * miss vblank/flip events and fail. Work around this by retrying the test
+ * once in case of such a link reset event, which the driver signals with a
+ * hotplug event.
+ */
+static bool needs_retry_after_link_reset(struct udev_monitor *mon)
+{
+ bool hotplug_detected;
+
+ igt_suspend_signal_helper();
+ hotplug_detected = igt_hotplug_detected(mon, 3);
+ igt_resume_signal_helper();
+
+ if (hotplug_detected)
+ igt_debug("Retrying after a hotplug event\n");
+
+ return hotplug_detected;
}
static void __run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
@@ -1259,6 +1298,9 @@ static void __run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
kmstest_dump_mode(&o->kmode[i]);
retry:
+ memset(&o->vblank_state, 0, sizeof(o->vblank_state));
+ memset(&o->flip_state, 0, sizeof(o->flip_state));
+
kmstest_unset_all_crtcs(drm_fd, resources);
igt_flush_uevents(mon);
@@ -1282,8 +1324,13 @@ retry:
}
/* quiescent the hw a bit so ensure we don't miss a single frame */
- if (o->flags & TEST_CHECK_TS)
- calibrate_ts(o, crtc_idxs[0]);
+ if (o->flags & TEST_CHECK_TS && !calibrate_ts(o, crtc_idxs[0])) {
+ igt_assert(!retried && needs_retry_after_link_reset(mon));
+
+ retried = true;
+
+ goto retry;
+ }
if (o->flags & TEST_BO_TOOBIG) {
int err = do_page_flip(o, o->fb_ids[1], true);
@@ -1316,28 +1363,10 @@ retry:
if (o->flags & TEST_VBLANK)
state_ok &= check_final_state(o, &o->vblank_state, elapsed);
- /*
- * Some monitors with odd behavior signal a bad link after waking from
- * a power saving state and the subsequent (successful) modeset. This
- * will result in a link-retraining (DP) or async modeset (HDMI),
- * which in turn makes the test miss vblank/flip events and fail.
- * Work around this by retrying the test once in case of such a link
- * reset event, which the driver signals with a hotplug event.
- */
if (!state_ok) {
- bool hotplug_detected;
+ igt_assert(!retried && needs_retry_after_link_reset(mon));
- igt_suspend_signal_helper();
- if (!retried)
- hotplug_detected = igt_hotplug_detected(mon, 3);
- igt_resume_signal_helper();
-
- igt_assert(!retried && hotplug_detected);
-
- igt_debug("Retrying after a hotplug event\n");
retried = true;
- memset(&o->vblank_state, 0, sizeof(o->vblank_state));
- memset(&o->flip_state, 0, sizeof(o->flip_state));
goto retry;
}
--
2.20.1
More information about the igt-dev
mailing list