This test uses debugfs entry to set next_seqno close
to a wrapping point and then creates a load with gem_stress
to induce the wrap.

Signed-off-by: Mika Kuoppala <[email protected]>
---
 tests/Makefile.am      |    1 +
 tests/gem_seqno_wrap.c |  248 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 249 insertions(+)
 create mode 100644 tests/gem_seqno_wrap.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6e6bd7e..cfa0cee 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -44,6 +44,7 @@ TESTS_progs = \
        gem_linear_blits \
        gem_vmap_blits \
        gem_threaded_access_tiled \
+       gem_seqno_wrap \
        gem_tiled_blits \
        gem_tiled_fence_blits \
        gem_largeobject \
diff --git a/tests/gem_seqno_wrap.c b/tests/gem_seqno_wrap.c
new file mode 100644
index 0000000..b7135ad
--- /dev/null
+++ b/tests/gem_seqno_wrap.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Mika Kuoppala <[email protected]>
+ */
+
+/*
+ * This test runs gem_stress test multiple times while setting the
+ * next_seqno close to wrapping point. Driver can only handle INT_MAX-1
+ * increments to seqno.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <limits.h>
+
+#include "drmtest.h"
+#include "i915_drm.h"
+#include "intel_bufmgr.h"
+
+#define NUM_WRAPS 3
+
+static int verbose = 0;
+
+static int run_gem_stress(int times)
+{
+       int pid;
+       int r = -1;
+       int status = 0;
+
+       pid = fork();
+       if (pid == 0) {
+               char *argv[3];
+               char cmd[32];
+               char opt1[32];
+               char path[PATH_MAX];
+               char full_path[PATH_MAX];
+
+               strncpy(cmd, "gem_stress", sizeof(cmd));
+               argv[0] = cmd;
+               argv[1] = opt1;
+               argv[2] = NULL;
+
+               assert(snprintf(opt1, sizeof(opt1), "-o%d", times) > 0);
+
+               if (getcwd(path, PATH_MAX) == NULL)
+                       perror("getcwd");
+
+               assert(snprintf(full_path, PATH_MAX, "%s/%s", path, argv[0]) > 
0);
+
+               if (!verbose) {
+                       close(STDOUT_FILENO);
+                       close(STDERR_FILENO);
+               }
+
+               r = execv(full_path, argv);
+               if (r == -1)
+                       perror("execv failed");
+       } else {
+               int waitcount = 20;
+
+               while(waitcount-- > 0) {
+                       r = waitpid(pid, &status, WNOHANG);
+                       if (r == pid) {
+                               if(WIFEXITED(status)) {
+                                       if (WEXITSTATUS(status))
+                                               fprintf(stderr, "child returned 
with %d\n", WEXITSTATUS(status));
+                                       return WEXITSTATUS(status);
+                               }
+                       } else if (r != 0) {
+                               perror("waitpid");
+                               return -errno;
+                       }
+
+                       sleep(1);
+               }
+
+               kill(pid, SIGKILL);
+               return -ETIMEDOUT;
+       }
+
+       return r;
+}
+
+static const char *debug_fs_entry = "/sys/kernel/debug/dri/0/i915_next_seqno";
+
+static int read_seqno(uint32_t *seqno)
+{
+       int fh;
+       char buf[32];
+       int r;
+       char *p;
+       unsigned long int tmp;
+
+       fh = open(debug_fs_entry, O_RDWR);
+       if (fh == -1) {
+               perror("open");
+               fprintf(stderr, "no %s found, too old kernel?\n", 
debug_fs_entry);
+               return -errno;
+       }
+
+       r = read(fh, buf, sizeof(buf) - 1);
+       if (r < 0) {
+               perror("read");
+               close(fh);
+               return -errno;
+       }
+
+       close(fh);
+       buf[r] = 0;
+
+       p = strstr(buf, "0x");
+       if (!p)
+               p = buf;
+
+       tmp = strtoul(p, NULL, 0);
+       if (tmp == ULONG_MAX) {
+               perror("strtoul");
+               return -errno;
+       }
+
+       *seqno = tmp;
+
+       return 0;
+}
+
+static int write_seqno(uint32_t seqno)
+{
+       int fh;
+       char buf[32];
+       int r;
+
+       fh = open(debug_fs_entry, O_RDWR);
+       if (fh == -1) {
+               perror("open");
+               return -errno;
+       }
+
+       assert(snprintf(buf, sizeof(buf), "0x%x", seqno) > 0);
+
+       r = write(fh, buf, strnlen(buf, sizeof(buf)));
+       if (r < 0)
+               return r;
+
+       assert(r == strnlen(buf, sizeof(buf)));
+
+       close(fh);
+
+       return 0;
+}
+
+static int run_once(void)
+{
+       int r;
+       uint32_t seqno = 0;
+       uint32_t seqno_after = 0;
+       uint32_t incr;
+
+       r = read_seqno(&seqno);
+       assert(r == 0);
+
+       incr = (UINT32_MAX >> 1) - 0x1000;
+       if (seqno + incr < seqno)
+               seqno = UINT32_MAX - 0x1000;
+       else
+               seqno += incr;
+
+       seqno++;
+
+       r = write_seqno(seqno);
+       if (r < 0) {
+               fprintf(stderr, "write_seqno returned %d\n", r);
+               return r;
+       }
+
+       // XXX we lose drm auth/master if we are too hasty to reopen /dev/dri 
wtf?!
+       // usleep(200*1000);
+       r = run_gem_stress(1);
+       if (r != 0) {
+               fprintf(stderr, "run_gem_stress returned %d\n", r);
+               return -1;
+       }
+
+       r = read_seqno(&seqno_after);
+       assert(r == 0);
+
+       if (seqno > seqno_after)
+               return 1;
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+
+       int wraps = 0;
+       int wr;
+       int r;
+
+       if (argc > 1)
+               wr = atoi(argv[1]);
+       else
+               wr = NUM_WRAPS;
+
+       while(wraps < wr) {
+               r = run_once();
+               if (r < 0) {
+                       if (verbose) fprintf(stderr, "run once returned %d\n", 
r);
+                       return r;
+               }
+
+               wraps += r;
+       }
+
+       if (wraps == wr) {
+               if (verbose)
+                       printf("done %d wraps successfully\n", wraps);
+
+               return 0;
+       }
+
+       return -1;
+}
-- 
1.7.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to