The test just aims to execute batches on alternating rings with a write
target such that every batch must be executed after the previous
completes. This stresses the inter-ring synchronisation, which is
interrupt driven if the gpu does not support semaphores, and so is a
good stress tests for detecting "missed interrupt syndrome". Make that
detection explicit.

Signed-off-by: Chris Wilson <[email protected]>
---
 tests/gem_ring_sync_loop.c | 134 ++++++++++++++++++++++++---------------------
 1 file changed, 72 insertions(+), 62 deletions(-)

diff --git a/tests/gem_ring_sync_loop.c b/tests/gem_ring_sync_loop.c
index 452ccd8..721cce9 100644
--- a/tests/gem_ring_sync_loop.c
+++ b/tests/gem_ring_sync_loop.c
@@ -26,23 +26,8 @@
  */
 
 #include "igt.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include "drm.h"
-#include "intel_bufmgr.h"
-#include "i830_reg.h"
-
-IGT_TEST_DESCRIPTION("Basic check of ring<->ring sync using a dummy reloc.");
-
-static drm_intel_bufmgr *bufmgr;
-struct intel_batchbuffer *batch;
-static drm_intel_bo *target_buffer;
+
+IGT_TEST_DESCRIPTION("Basic check of ring<->ring write synchronisation.");
 
 /*
  * Testcase: Basic check of ring<->ring sync using a dummy reloc
@@ -50,70 +35,95 @@ static drm_intel_bo *target_buffer;
  * Extremely efficient at catching missed irqs with semaphores=0 ...
  */
 
-#define MI_COND_BATCH_BUFFER_END       (0x36<<23 | 1)
-#define MI_DO_COMPARE                  (1<<21)
+static int __gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *eb)
+{
+       int err = 0;
+       if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, eb))
+               err = -errno;
+       return err;
+}
 
 static void
-store_dword_loop(int fd)
+sync_loop(int fd)
 {
-       int i;
+       const uint32_t bbe = MI_BATCH_BUFFER_END;
        int num_rings = gem_get_num_rings(fd);
+       struct drm_i915_gem_execbuffer2 execbuf;
+       struct drm_i915_gem_exec_object2 object[2];
+       struct drm_i915_gem_relocation_entry reloc[1];
+       int i;
+
+       memset(object, 0, sizeof(object));
+       object[0].handle = gem_create(fd, 4096);
+       object[0].flags = EXEC_OBJECT_WRITE;
+       object[1].handle = gem_create(fd, 4096);
+       gem_write(fd, object[1].handle, 0, &bbe, sizeof(bbe));
+
+       memset(&execbuf, 0, sizeof(execbuf));
+       execbuf.buffers_ptr = (uintptr_t)object;
+       execbuf.buffer_count = 2;
+
+       /* Check if we have no-reloc support first */
+       if (__gem_execbuf(fd, &execbuf)) {
+               object[0].flags = 0;
+               object[1].relocs_ptr = (uintptr_t)reloc;
+               object[1].relocation_count = 1;
+
+               /* Add a dummy relocation to mark the object as writing */
+               memset(reloc, 0, sizeof(reloc));
+               reloc->offset = 1000;
+               reloc->target_handle = object[0].handle;
+               reloc->read_domains = I915_GEM_DOMAIN_RENDER;
+               reloc->write_domain = I915_GEM_DOMAIN_RENDER;
+
+               gem_execbuf(fd, &execbuf);
+       }
 
        srandom(0xdeadbeef);
 
        for (i = 0; i < SLOW_QUICK(0x100000, 10); i++) {
-               int ring = random() % num_rings + 1;
-
-               if (ring == I915_EXEC_RENDER) {
-                       BEGIN_BATCH(4, 1);
-                       OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE);
-                       OUT_BATCH(0xffffffff); /* compare dword */
-                       OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
-                                       I915_GEM_DOMAIN_RENDER, 0);
-                       OUT_BATCH(MI_NOOP);
-                       ADVANCE_BATCH();
-               } else {
-                       BEGIN_BATCH(4, 1);
-                       OUT_BATCH(MI_FLUSH_DW | 1);
-                       OUT_BATCH(0); /* reserved */
-                       OUT_RELOC(target_buffer, I915_GEM_DOMAIN_RENDER,
-                                       I915_GEM_DOMAIN_RENDER, 0);
-                       OUT_BATCH(MI_NOOP | (1<<22) | (0xf));
-                       ADVANCE_BATCH();
-               }
-               intel_batchbuffer_flush_on_ring(batch, ring);
+               execbuf.flags = random() % num_rings + 1;
+               gem_execbuf(fd, &execbuf);
        }
 
-       drm_intel_bo_map(target_buffer, 0);
-       // map to force waiting on rendering
-       drm_intel_bo_unmap(target_buffer);
+       gem_sync(fd, object[1].handle);
+       gem_close(fd, object[1].handle);
+       gem_close(fd, object[0].handle);
 }
 
-igt_simple_main
+static unsigned intel_detect_and_clear_missed_irq(int fd)
 {
-       int fd;
-       int devid;
-
-       fd = drm_open_driver(DRIVER_INTEL);
-       devid = intel_get_drm_devid(fd);
-       gem_require_ring(fd, I915_EXEC_BLT);
+       unsigned missed = 0;
+       FILE *file;
 
+       gem_quiescent_gpu(fd);
 
-       bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
-       igt_assert(bufmgr);
-       drm_intel_bufmgr_gem_enable_reuse(bufmgr);
+       file = igt_debugfs_fopen("i915_ring_missed_irq", "r");
+       if (file) {
+               igt_assert(fscanf(file, "%x", &missed) == 1);
+               fclose(file);
+       }
+       if (missed) {
+               file = igt_debugfs_fopen("i915_ring_missed_irq", "w");
+               if (file) {
+                       fwrite("0\n", 1, 2, file);
+                       fclose(file);
+               }
+       }
 
-       batch = intel_batchbuffer_alloc(bufmgr, devid);
-       igt_assert(batch);
+       return missed;
+}
 
-       target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
-       igt_assert(target_buffer);
+igt_simple_main
+{
+       int fd;
 
-       store_dword_loop(fd);
+       fd = drm_open_driver(DRIVER_INTEL);
+       igt_require(gem_get_num_rings(fd) > 1);
+       intel_detect_and_clear_missed_irq(fd); /* clear before we begin */
 
-       drm_intel_bo_unreference(target_buffer);
-       intel_batchbuffer_free(batch);
-       drm_intel_bufmgr_destroy(bufmgr);
+       sync_loop(fd);
 
+       igt_assert_eq(intel_detect_and_clear_missed_irq(fd), 0);
        close(fd);
 }
-- 
2.7.0.rc3

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

Reply via email to