tests/kms_flip: don't leak gpu hang state
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Sat, 6 Apr 2013 16:29:37 +0000 (18:29 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sat, 6 Apr 2013 16:30:19 +0000 (18:30 +0200)
We need to clear out the error_state. While at it also make sure that
the hang was indeed detected.

Whoever writes the next test to race against gpu hangs should probably
extract these two functions into the drmtest library. Which just one
user that's not really worth it right now.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
tests/kms_flip.c

index 596d07a..39f0043 100644 (file)
@@ -552,6 +552,62 @@ static int exec_nop(int fd, uint32_t handle)
        return r;
 }
 
+static void eat_error_state(struct test_output *o)
+{
+       static const char dfs_base[] = "/sys/kernel/debug/dri";
+       static const char dfs_entry_error[] = "i915_error_state";
+       static const char dfs_entry_stop[] = "i915_ring_stop";
+       static const char data[] = "";
+       static char tmp[128];
+       char fname[FILENAME_MAX];
+       int card_index = drm_get_card(0);
+       int fd;
+       ssize_t r;
+
+       assert(card_index != -1);
+
+       /* clear the error state */
+       snprintf(fname, FILENAME_MAX, "%s/%i/%s",
+                dfs_base, card_index, dfs_entry_error);
+
+       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);
+
+       /* and check whether stop_rings is not reset, i.e. the hang has indeed
+        * happened */
+       snprintf(fname, FILENAME_MAX, "%s/%i/%s",
+                dfs_base, card_index, dfs_entry_stop);
+
+       fd = open(fname, O_RDONLY);
+       if (fd < 0) {
+               fprintf(stderr, "failed to open '%s': %s\n",
+                       fname, strerror(errno));
+               return;
+       }
+
+       r = read(fd, tmp, sizeof tmp);
+       if (r < 0)
+               fprintf(stderr, "failed to read '%s': %s\n",
+                       fname, strerror(errno));
+
+       if (atoi(tmp) != 0) {
+               fprintf(stderr, "no gpu hang detected, stop_rings is still %s\n", tmp);
+               exit(20);
+       }
+
+       close(fd);
+}
+
 static void hang_gpu(struct test_output *o)
 {
        static const char dfs_base[] = "/sys/kernel/debug/dri";
@@ -728,6 +784,7 @@ static unsigned int run_test_step(struct test_output *o)
        if (do_flip && (o->flags & TEST_HANG)) {
                gem_sync(drm_fd, handle);
                gem_close(drm_fd, handle);
+               eat_error_state(o);
        }
 
        return completed_events;