All of lore.kernel.org
 help / color / mirror / Atom feed
From: ville.syrjala@linux.intel.com
To: intel-gfx@lists.freedesktop.org
Subject: [i-g-t][PATCH 2/2] kms_flip: Add flip-vs-modeset-vs-hang test
Date: Wed, 30 Jan 2013 14:52:24 +0200	[thread overview]
Message-ID: <1359550344-14761-3-git-send-email-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <1359550344-14761-1-git-send-email-ville.syrjala@linux.intel.com>

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The flip-vs-modeset-vs-hang test will:
1. simulate a GPU hang
2. exec a nop batch
3. schedule a page flip
4. perform a modeset operation

With the current buggy kernel driver, the modeset operation will
hang indefinitely waiting for the flip to complete. Since the
rings are stopped, that will never happen. The current GPU reset
code doesn't play well with page flips either, so a GPU reset
won't fix things.

Once the kernel driver is fixed, the eventual GPU reset will
save the day.

The nop batch buffer is required only because the kernel can't
currently detect GPU hangs, unless there is at least one user
submitted request pending.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 tests/kms_flip.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 2 deletions(-)

diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index 97bd145..c2a29ae 100644
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -26,6 +26,7 @@
 #include <assert.h>
 #include <cairo.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <math.h>
 #include <stdint.h>
 #include <unistd.h>
@@ -55,6 +56,7 @@
 #define TEST_VBLANK_EXPIRED_SEQ	(1 << 11)
 #define TEST_FB_RECREATE	(1 << 12)
 #define TEST_RMFB		(1 << 13)
+#define TEST_HANG		(1 << 14)
 
 #define EVENT_FLIP		(1 << 0)
 #define EVENT_VBLANK		(1 << 1)
@@ -493,6 +495,75 @@ static void recreate_fb(struct test_output *o)
 	o->fb_info[o->current_fb_id].fb_id = new_fb_id;
 }
 
+static int exec_nop(int fd, uint32_t handle)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 gem_exec[1];
+	uint32_t b[2] = {MI_BATCH_BUFFER_END};
+	int r;
+
+	gem_write(fd, handle, 0, b, sizeof(b));
+
+	gem_exec[0].handle = handle;
+	gem_exec[0].relocation_count = 0;
+	gem_exec[0].relocs_ptr = 0;
+	gem_exec[0].alignment = 0;
+	gem_exec[0].offset = 0;
+	gem_exec[0].flags = 0;
+	gem_exec[0].rsvd1 = 0;
+	gem_exec[0].rsvd2 = 0;
+
+	execbuf.buffers_ptr = (uintptr_t)gem_exec;
+	execbuf.buffer_count = 1;
+	execbuf.batch_start_offset = 0;
+	execbuf.batch_len = 8;
+	execbuf.cliprects_ptr = 0;
+	execbuf.num_cliprects = 0;
+	execbuf.DR1 = 0;
+	execbuf.DR4 = 0;
+	execbuf.flags =  I915_EXEC_RENDER;
+	i915_execbuffer2_set_context_id(execbuf, 0);
+	execbuf.rsvd2 = 0;
+
+	r = drmIoctl(fd,
+			DRM_IOCTL_I915_GEM_EXECBUFFER2,
+			&execbuf);
+	if (r)
+		fprintf(stderr, "failed to exec: %s\n",
+			strerror(errno));
+	return r;
+}
+
+static void hang_gpu(struct test_output *o)
+{
+	static const char dfs_base[] = "/sys/kernel/debug/dri";
+	static const char dfs_entry[] = "i915_ring_stop";
+	static const char data[] = "0xf";
+	char fname[FILENAME_MAX];
+	int card_index = drm_get_card(0);
+	int fd;
+	ssize_t r;
+
+	assert(card_index != -1);
+
+	snprintf(fname, FILENAME_MAX, "%s/%i/%s",
+		 dfs_base, card_index, dfs_entry);
+
+	fd = open(fname, O_WRONLY);
+	if (fd < 0) {
+		fprintf(stderr, "failed to open '%s': %s\n",
+			fname, strerror(errno));
+		return;
+	}
+
+	r = write(fd, data, sizeof data);
+	if (r < 0)
+		fprintf(stderr, "failed to write '%s': %s\n",
+			fname, strerror(errno));
+
+	close(fd);
+}
+
 /* Return mask of completed events. */
 static unsigned int run_test_step(struct test_output *o)
 {
@@ -504,6 +575,7 @@ static unsigned int run_test_step(struct test_output *o)
 	bool do_vblank;
 	struct vblank_reply vbl_reply;
 	unsigned int target_seq;
+	uint32_t handle;
 
 	target_seq = o->vblank_state.seq_step;
 	if (o->flags & TEST_VBLANK_ABSOLUTE)
@@ -566,8 +638,14 @@ static unsigned int run_test_step(struct test_output *o)
 
 	printf("."); fflush(stdout);
 
+	if (do_flip && (o->flags & TEST_HANG)) {
+		handle = gem_create(drm_fd, 4096);
+		hang_gpu(o);
+		exec_nop(drm_fd, handle);
+	}
+
 	if (do_flip)
-		do_or_die(do_page_flip(o, new_fb_id, true));
+		do_or_die(do_page_flip(o, new_fb_id, !(o->flags & TEST_HANG)));
 
 	if (do_vblank) {
 		do_or_die(do_wait_for_vblank(o, o->pipe, target_seq,
@@ -623,6 +701,11 @@ static unsigned int run_test_step(struct test_output *o)
 	if (do_flip && (o->flags & TEST_EINVAL))
 		assert(do_page_flip(o, new_fb_id, true) == expected_einval);
 
+	if (do_flip && (o->flags & TEST_HANG)) {
+		gem_sync(drm_fd, handle);
+		gem_close(drm_fd, handle);
+	}
+
 	return completed_events;
 }
 
@@ -922,7 +1005,7 @@ static void run_test_on_crtc(struct test_output *o, int crtc, int duration)
 
 	ellapsed = event_loop(o, duration);
 
-	if (o->flags & TEST_FLIP)
+	if (o->flags & TEST_FLIP && !(o->flags & TEST_HANG))
 		check_final_state(o, &o->flip_state, ellapsed);
 	if (o->flags & TEST_VBLANK)
 		check_final_state(o, &o->vblank_state, ellapsed);
@@ -1025,6 +1108,7 @@ int main(int argc, char **argv)
 					"flip-vs-wf_vblank" },
 		{ 15, TEST_FLIP | TEST_VBLANK | TEST_VBLANK_BLOCK |
 			TEST_CHECK_TS, "flip-vs-blocking-wf-vblank" },
+		{ 15, TEST_FLIP | TEST_MODESET | TEST_HANG , "flip-vs-modeset-vs-hang" },
 	};
 	int i;
 
-- 
1.7.12.4

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

  parent reply	other threads:[~2013-01-30 12:52 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-30 12:52 [i-g-t][PATCH 0/2] Test for page flip hangs ville.syrjala
2013-01-30 12:52 ` [i-g-t][PATCH 1/2] kms_flip: Make flip events optional ville.syrjala
2013-01-30 12:52 ` ville.syrjala [this message]
2013-01-30 15:06 ` [i-g-t][PATCH 0/2] Test for page flip hangs Daniel Vetter
2013-01-30 15:06 ` Daniel Vetter

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=1359550344-14761-3-git-send-email-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@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.