public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
* [igt-dev] [RFC i-g-t] igt/kms_cursor_legacy: Add single atomic 2x flip vs cursor tests
@ 2018-10-12  0:46 sunpeng.li
  2018-10-12  1:48 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
  2018-10-12  5:55 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  0 siblings, 2 replies; 3+ messages in thread
From: sunpeng.li @ 2018-10-12  0:46 UTC (permalink / raw)
  To: igt-dev

From: Leo Li <sunpeng.li@amd.com>

This test executes flips on both CRTCs by using a single atomic commit,
while running cursor updates in parallel.

It tests the problem as described by this DRM patch:
https://patchwork.freedesktop.org/patch/256297/

This is a rough test that I c-and-p'd together with existing code,
just to showcase the issue. The 2x-nonblocking-modeset-vs-cursor-atomic
test might have been sufficient, but amdgpu currently doesn't like
non-blocking modesets. I can't try it on i915 either, since the issue is
being masked by commit_hw_done() being done after wait_for_flip_done().

It's currently quite flakey. On my system, it usually causes the
protection fault on second run, regardless of the test duration. I'm not
yet sure how to write something that can test this reliably.

It also isn't verifying the vblank counts. Interestingly, it seems to
reproduce less when I do verify them. So for the sake of showcasing
the problem, I left it out.

Needless to say, lots of wrong things being done here. Any input on how
to structure this test and make it more reliable will be much
appreciated :)

Signed-off-by: Leo Li <sunpeng.li@amd.com>
---
 tests/kms_cursor_legacy.c | 97 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/tests/kms_cursor_legacy.c b/tests/kms_cursor_legacy.c
index 79df79a3..64d6545d 100644
--- a/tests/kms_cursor_legacy.c
+++ b/tests/kms_cursor_legacy.c
@@ -266,6 +266,27 @@ static void flip_nonblocking(igt_display_t *display, enum pipe pipe_id, bool ato
 	igt_reset_timeout();
 }
 
+static void flip_two_pipes_nonblocking(igt_display_t *display,
+				      enum pipe pipe1_id, enum pipe pipe2_id,
+				      struct igt_fb *fb1, struct igt_fb *fb2,
+				      void *data)
+{
+	igt_pipe_t *pipe1 = &display->pipes[pipe1_id];
+	igt_pipe_t *pipe2 = &display->pipes[pipe2_id];
+	igt_plane_t *primary1 = igt_pipe_get_plane_type(pipe1, DRM_PLANE_TYPE_PRIMARY);
+	igt_plane_t *primary2 = igt_pipe_get_plane_type(pipe2, DRM_PLANE_TYPE_PRIMARY);
+	int ret;
+
+	igt_set_timeout(1, "Scheduling page flip\n");
+	igt_plane_set_fb(primary1, fb1);
+	igt_plane_set_fb(primary2, fb2);
+	do {
+		ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, data);
+	} while (ret == -EBUSY);
+	igt_assert(!ret);
+	igt_reset_timeout();
+}
+
 enum flip_test {
 	flip_test_legacy = 0,
 	flip_test_varying_size,
@@ -1022,6 +1043,76 @@ done:
 	igt_remove_fb(display->drm_fd, &cursor_fb);
 }
 
+static void two_screens_single_atomic_flip_vs_cursor(igt_display_t *display,
+						     int nloops)
+{
+	struct drm_mode_cursor arg1[2], arg2[2];
+	struct igt_fb fb_info, fb2_info, cursor_fb;
+	enum pipe pipe = find_connected_pipe(display, false);
+	enum pipe pipe2 = find_connected_pipe(display, true);
+	igt_output_t *output, *output2;
+	volatile unsigned long *shared;
+	struct drm_event_vblank vbl;
+
+	shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+	igt_assert(shared != MAP_FAILED);
+
+	igt_require(display->is_atomic);
+
+	igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
+	igt_require((output2 = set_fb_on_crtc(display, pipe2, &fb2_info)));
+
+	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, arg1, &cursor_fb);
+
+	arg1[1].x = arg1[1].y = 192;
+
+	set_cursor_on_pipe(display, pipe2, &cursor_fb);
+	populate_cursor_args(display, pipe2, arg2, &cursor_fb);
+
+	arg2[1].x = arg2[1].y = 192;
+
+
+	igt_display_commit2(display, COMMIT_ATOMIC);
+
+	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]]);
+	}
+
+	flip_two_pipes_nonblocking(display, pipe, pipe2, &fb_info, &fb2_info, NULL);
+
+	while (nloops) {
+		shared[1] = nloops & 1;
+
+		igt_set_timeout(1, "Stuck page flip");
+		igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
+		igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
+		igt_reset_timeout();
+
+		/* Do not requeue on the last 2 events. */
+		if (nloops <= 1) {
+			nloops--;
+			continue;
+		}
+
+		flip_two_pipes_nonblocking(display, pipe, pipe2, &fb_info, &fb2_info, NULL);
+		nloops--;
+
+	}
+
+	shared[0] = 1;
+	igt_waitchildren();
+
+	igt_remove_fb(display->drm_fd, &fb_info);
+	igt_remove_fb(display->drm_fd, &fb2_info);
+	igt_remove_fb(display->drm_fd, &cursor_fb);
+}
+
 static void cursor_vs_flip(igt_display_t *display, enum flip_test mode, int nloops)
 {
 	struct drm_mode_cursor arg[2];
@@ -1445,6 +1536,12 @@ igt_main
 	igt_subtest("2x-long-cursor-vs-flip-atomic")
 		two_screens_cursor_vs_flip(&display, 50, true);
 
+	igt_subtest("2x-mirrored-flip-vs-cursor-atomic")
+		two_screens_single_atomic_flip_vs_cursor(&display, 8);
+
+	igt_subtest("2x-long-mirrored-flip-vs-cursor-atomic")
+		two_screens_single_atomic_flip_vs_cursor(&display, 150);
+
 	igt_subtest("flip-vs-cursor-crc-legacy")
 		flip_vs_cursor_crc(&display, false);
 
-- 
2.17.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-10-12  5:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-12  0:46 [igt-dev] [RFC i-g-t] igt/kms_cursor_legacy: Add single atomic 2x flip vs cursor tests sunpeng.li
2018-10-12  1:48 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
2018-10-12  5:55 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox