All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH i-g-t] tests/kms_cursor_legacy: Rework the 2x tests.
Date: Thu, 16 Nov 2017 13:45:14 +0100	[thread overview]
Message-ID: <20171116124514.4617-1-maarten.lankhorst@linux.intel.com> (raw)

Instead of strictly measuring vblanks, we try to see if a page flip
is queued on the next vblank if we run legacy cursor updates to the
pipe and another pipe in the background.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101634
---
 tests/kms_cursor_legacy.c | 90 ++++++++++++++++++++++++++++-------------------
 1 file changed, 54 insertions(+), 36 deletions(-)

diff --git a/tests/kms_cursor_legacy.c b/tests/kms_cursor_legacy.c
index 5720dbef90d3..b8b15b609d7f 100644
--- a/tests/kms_cursor_legacy.c
+++ b/tests/kms_cursor_legacy.c
@@ -884,14 +884,23 @@ cleanup:
 
 static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool modeset, bool atomic)
 {
-	struct drm_mode_cursor arg[2], arg2[2];
-	struct drm_event_vblank vbl;
+	struct drm_mode_cursor arg1[2], arg2[2];
 	struct igt_fb fb_info, fb2_info, cursor_fb;
-	unsigned vblank_start;
 	enum pipe pipe = find_connected_pipe(display, false);
 	enum pipe pipe2 = find_connected_pipe(display, true);
 	igt_output_t *output, *output2;
 	bool skip_test = false;
+	volatile unsigned long *shared;
+
+	if (modeset) {
+		uint64_t val;
+
+		igt_fail_on(!atomic);
+		igt_assert(drmGetCap(display->drm_fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &val) == 0);
+	}
+
+	shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+	igt_assert(shared != MAP_FAILED);
 
 	igt_fail_on(modeset && !atomic);
 
@@ -903,9 +912,9 @@ static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool
 
 	igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
 	set_cursor_on_pipe(display, pipe, &cursor_fb);
-	populate_cursor_args(display, pipe, arg, &cursor_fb);
+	populate_cursor_args(display, pipe, arg1, &cursor_fb);
 
-	arg[1].x = arg[1].y = 192;
+	arg1[1].x = arg1[1].y = 192;
 
 	set_cursor_on_pipe(display, pipe2, &cursor_fb);
 	populate_cursor_args(display, pipe2, arg2, &cursor_fb);
@@ -917,29 +926,29 @@ static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool
 
 	igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
 
-	vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
-	igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
-	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
-	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg2[0]);
-	igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
+	igt_fork(child, 2) {
+		struct drm_mode_cursor *arg = child ? arg2 : arg1;
+
+		while (!shared[0])
+			do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR,
+				 &arg[!shared[1]]);
+	}
 
 	while (nloops--) {
-		/* Start with a synchronous query to align with the vblank */
-		vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
-		do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
+		unsigned vblank_start =
+			get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
+
+		shared[1] = nloops & 1;
+
+		if (!modeset) {
+			flip_nonblocking(display, pipe, atomic, &fb_info);
+		} else {
+			unsigned flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
+			flags |= DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
 
-		if (!modeset)
-			flip_nonblocking(display, pipe, false, &fb_info);
-		else {
 			/*
-			 * There are 2 design issues that prevent us from doing
-			 * the test we would like here:
-			 *
-			 * - drm_event_vblank doesn't set crtc_id, so if we
-			 *   use events we don't know which pipe fired the event,
-			 *   no way to distinguish.
-			 * - Doing a modeset may add unrelated pipes, and fail with
-			 *   -EBUSY if a page flip is queued on one of those.
+			 * Doing a modeset may add unrelated pipes, and fail with
+			 * -EBUSY if a page flip is queued on one of those.
 			 *
 			 * Work around it by not setting an event, but doing a synchronous
 			 * commit to wait for completion, and queue the page flip and modeset
@@ -948,26 +957,32 @@ static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool
 
 			igt_plane_set_fb(igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY), &fb_info);
 			igt_output_set_pipe(output2, (nloops & 1) ? PIPE_NONE : pipe2);
-			igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK, NULL);
+			igt_display_commit_atomic(display, flags, NULL);
 		}
 
-		igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
-
-		do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
 		if (!modeset) {
-			do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg2[nloops & 1]);
-			do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
-			do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg2[nloops & 1]);
-
-			igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
+			struct drm_event_vblank vbl;
 
 			igt_set_timeout(1, "Stuck page flip");
+
 			igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
-			igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
-			igt_reset_timeout();
+			igt_assert(vbl.crtc_id == display->pipes[pipe].crtc_id);
+			igt_assert(vbl.sequence == vblank_start + 1);
 		} else {
-			do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg2[nloops & 1]);
+			struct drm_event_vblank vbl, vbl2;
+
+			igt_set_timeout(35, "Stuck nonblocking modeset");
+
+			igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
+			igt_ignore_warn(read(display->drm_fd, &vbl2, sizeof(vbl2)));
+
+			igt_assert(vbl.crtc_id != vbl2.crtc_id);
+			igt_assert(vbl.crtc_id == display->pipes[pipe].crtc_id ||
+				   vbl.crtc_id == display->pipes[pipe2].crtc_id);
+			igt_assert(vbl2.crtc_id == display->pipes[pipe].crtc_id ||
+				   vbl2.crtc_id == display->pipes[pipe2].crtc_id);
 		}
+		igt_reset_timeout();
 
 		if (modeset) {
 			/* wait for pending modeset and page flip to complete, to prevent -EBUSY */
@@ -977,6 +992,9 @@ static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool
 		}
 	}
 
+	shared[0] = 1;
+	igt_waitchildren();
+
 cleanup:
 	do_cleanup_display(display);
 	igt_remove_fb(display->drm_fd, &fb_info);
-- 
2.15.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

             reply	other threads:[~2017-11-16 12:45 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-16 12:45 Maarten Lankhorst [this message]
2017-11-16 13:03 ` ✓ Fi.CI.BAT: success for tests/kms_cursor_legacy: Rework the 2x tests Patchwork
2017-11-16 13:41 ` ✗ Fi.CI.IGT: warning " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171116124514.4617-1-maarten.lankhorst@linux.intel.com \
    --to=maarten.lankhorst@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.