Thread (16 messages) 16 messages, 5 authors, 2021-10-26

[igt-dev] [PATCH v2] tests/kms_flip: Discard any stale event at each retry

From: Mark Yacoub <hidden>
Date: 2021-09-24 18:39:34
Subsystem: the rest · Maintainer: Linus Torvalds

From: Mark Yacoub <redacted>

[Why]
On slower devices, non blocking do_page_flip followed by wait_for_events
does not finish fast enough to send an event to be consumed by wait_for_events.
Instead, wait_for_events ends up finding an unconsumed event from a
previous do_page_flip (i.e. a skipped preceding subtest) and signals
that the userspace is ready to do another do_page_flip while the first
one hasn't finished yet, resulting in an EBUSY.

[How]
At the beginning of every test running on crtc set, check for any stale
events and consume them so the kernel has no pending events.

Fixes: flip-vs-suspend and flip-vs-suspend-interruptible.
Tested on ChromeOS Volteer(i915-TGL) and Trogdor(msm)

Changes since v1:
1. Update the discard_any_stale_events timeout
2. Correct a debug message
3. use C-style comments

Signed-off-by: Mark Yacoub <redacted>
---
 tests/kms_flip.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index b4836a44..73a8e636 100755
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -1265,6 +1265,26 @@ static bool needs_retry_after_link_reset(struct udev_monitor *mon)
 	return hotplug_detected;
 }
 
+static void discard_any_stale_events() {
+	fd_set fds;
+	FD_ZERO(&fds);
+	FD_SET(drm_fd, &fds);
+	struct timeval timeout = { .tv_sec = 0, .tv_usec = 20000 };
+	int ret = select(drm_fd + 1, &fds, NULL, NULL, &timeout);
+
+	if (ret > 0) {
+		drmEventContext evctx;
+		memset(&evctx, 0, sizeof evctx);
+		evctx.version = 2;
+		igt_info("Stale Event found - Discarding now\n");
+		drmHandleEvent(drm_fd, &evctx);
+	}
+	else {
+		igt_debug("No stale events found\n");
+	}
+}
+
+
 static void __run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
 				   int crtc_count, int duration_ms)
 {
@@ -1315,6 +1335,9 @@ static void __run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
 		kmstest_dump_mode(&o->kmode[i]);
 
 retry:
+	/* Discard any pending event that hasn't been consumed from a previous retry or subtest. */
+	discard_any_stale_events();
+
 	memset(&o->vblank_state, 0, sizeof(o->vblank_state));
 	memset(&o->flip_state, 0, sizeof(o->flip_state));
 	o->flip_state.name = "flip";
-- 
2.33.0.685.g46640cef36-goog
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help