On Tue, Oct 14, 2014 at 12:28:39PM +0100, Chris Wilson wrote: > After setting up the copy operations, add a hanging batch. This should > mean that we complete the copy and the compare then races against the > GEM reset. Hopefully, this will catch driver bugs where the target > object is no longer accessible after the hang. > > Note: hang injection is disabled until the required kernel interface is > completed. But there are useful additional tests here... > > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> I really like the nastiness this affords us. But some detail work still missing, see below. > --- > lib/Makefile.sources | 2 + > lib/igt_gt.c | 113 ++++++++++++++++++ > lib/igt_gt.h | 35 ++++++ > lib/ioctl_wrappers.c | 25 ++++ > lib/ioctl_wrappers.h | 12 ++ > tests/gem_concurrent_blit.c | 273 +++++++++++++++++++++++++++++++++----------- > 6 files changed, 395 insertions(+), 65 deletions(-) > create mode 100644 lib/igt_gt.c > create mode 100644 lib/igt_gt.h > > diff --git a/lib/Makefile.sources b/lib/Makefile.sources > index eee145f..680819a 100644 > --- a/lib/Makefile.sources > +++ b/lib/Makefile.sources > @@ -10,6 +10,8 @@ libintel_tools_la_SOURCES = \ > igt_debugfs.h \ > igt_aux.c \ > igt_aux.h \ > + igt_gt.c \ > + igt_gt.h \ > instdone.c \ > instdone.h \ > intel_batchbuffer.c \ > diff --git a/lib/igt_gt.c b/lib/igt_gt.c > new file mode 100644 > index 0000000..5e2bebd > --- /dev/null > +++ b/lib/igt_gt.c > @@ -0,0 +1,113 @@ > +/* > + * Copyright © 2014 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. > + */ > + > +#include <string.h> > + > +#include "igt_core.h" > +#include "igt_gt.h" > +#include "igt_debugfs.h" > +#include "ioctl_wrappers.h" > +#include "intel_reg.h" > + > +#define CONTEXT_PARAM_UPSTREAM 0 > + > +int igt_can_hang_ring(int fd, int gen, int ring) Bikeshed: The usual approach is to just have a void igt_require_foo which already wraps the igt_require. Folds away a bit of complexity. Also, gtkdoc for all this seems to be missing. And we need some low-level ioctl params checks for the new context param ioctls (e.g. invalid params, invalid size and all that stuff). Thanks, Daniel > +{ > + if (!CONTEXT_PARAM_UPSTREAM) > + return 0; > + > + if (!gem_context_has_param(fd, LOCAL_CONTEXT_PARAM_BAN_PERIOD)) > + return 0; > + > + if (gen < 6) /* safe resets */ > + return 0; > + > + return 1; > +} > + > +struct igt_hang_ring igt_hang_ring(int fd, int gen, int ring) > +{ > + struct drm_i915_gem_relocation_entry reloc; > + struct drm_i915_gem_execbuffer2 execbuf; > + struct drm_i915_gem_exec_object2 exec; > + struct local_i915_gem_context_param param; > + uint32_t b[8]; > + unsigned ban; > + unsigned len; > + > + param.context = 0; > + param.size = 0; > + param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD; > + param.value = 0; > + gem_context_get_param(fd, ¶m); > + ban = param.value; > + > + param.value = 0; > + igt_require(gem_context_set_param(fd, ¶m) == 0); > + > + memset(&reloc, 0, sizeof(reloc)); > + memset(&exec, 0, sizeof(exec)); > + memset(&execbuf, 0, sizeof(execbuf)); > + > + exec.handle = gem_create(fd, 4096); > + exec.relocation_count = 1; > + exec.relocs_ptr = (uintptr_t)&reloc; > + > + len = 2; > + if (gen >= 8) > + len++; > + b[0] = MI_BATCH_BUFFER_START | (len - 2); > + b[len] = MI_BATCH_BUFFER_END; > + b[len+1] = MI_NOOP; > + gem_write(fd, exec.handle, 0, b, sizeof(b)); > + > + reloc.offset = 4; > + reloc.target_handle = exec.handle; > + reloc.read_domains = I915_GEM_DOMAIN_COMMAND; > + > + execbuf.buffers_ptr = (uintptr_t)&exec; > + execbuf.buffer_count = 1; > + execbuf.batch_len = sizeof(b); > + execbuf.flags = ring; > + gem_execbuf(fd, &execbuf); > + > + return (struct igt_hang_ring){ exec.handle, ban }; > +} > + > +void igt_post_hang_ring(int fd, struct igt_hang_ring arg) > +{ > + struct local_i915_gem_context_param param; > + > + if (arg.handle == 0) > + return; > + > + gem_set_domain(fd, arg.handle, > + I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); > + gem_close(fd, arg.handle); > + > + param.context = 0; > + param.size = 0; > + param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD; > + param.value = arg.ban; > + gem_context_set_param(fd, ¶m); > +} > diff --git a/lib/igt_gt.h b/lib/igt_gt.h > new file mode 100644 > index 0000000..19bbcef > --- /dev/null > +++ b/lib/igt_gt.h > @@ -0,0 +1,35 @@ > +/* > + * Copyright © 2014 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. > + */ > + > +#ifndef IGT_GT_H > +#define IGT_GT_H > + > +int igt_can_hang_ring(int fd, int gen, int ring); > + > +struct igt_hang_ring { > + unsigned handle; > + unsigned ban; > +} igt_hang_ring(int fd, int gen, int ring); > +void igt_post_hang_ring(int fd, struct igt_hang_ring data); > + > +#endif /* IGT_GT_H */ > diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c > index ab1a82e..70f582e 100644 > --- a/lib/ioctl_wrappers.c > +++ b/lib/ioctl_wrappers.c > @@ -959,3 +959,28 @@ off_t prime_get_size(int dma_buf_fd) > return ret; > } > > +int gem_context_get_param(int fd, struct local_i915_gem_context_param *p) > +{ > +#define LOCAL_I915_GEM_CONTEXT_GETPARAM 0x34 > +#define LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_CONTEXT_GETPARAM, struct local_i915_gem_context_param) > + return drmIoctl(fd, LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM, p); > +} > + > +int gem_context_set_param(int fd, struct local_i915_gem_context_param *p) > +{ > +#define LOCAL_I915_GEM_CONTEXT_SETPARAM 0x35 > +#define LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_CONTEXT_SETPARAM, struct local_i915_gem_context_param) > + return drmIoctl(fd, LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM, p); > +} > + > +int gem_context_has_param(int fd, uint64_t param) > +{ > + struct local_i915_gem_context_param p; > + > + p.context = 0; > + p.param = param; > + p.value = 0; > + p.size = 0; > + > + return gem_context_get_param(fd, &p) == 0; > +} > diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h > index b1deedf..7f798dd 100644 > --- a/lib/ioctl_wrappers.h > +++ b/lib/ioctl_wrappers.h > @@ -99,4 +99,16 @@ int prime_handle_to_fd(int fd, uint32_t handle); > uint32_t prime_fd_to_handle(int fd, int dma_buf_fd); > off_t prime_get_size(int dma_buf_fd); > > +struct local_i915_gem_context_param { > + uint32_t context; > + uint32_t size; > + uint64_t param; > +#define LOCAL_CONTEXT_PARAM_BAN_PERIOD 0x1 > + uint64_t value; > +}; > + > +int gem_context_has_param(int fd, uint64_t param); > +int gem_context_get_param(int fd, struct local_i915_gem_context_param *p); > +int gem_context_set_param(int fd, struct local_i915_gem_context_param *p); > + > #endif /* IOCTL_WRAPPERS_H */ > diff --git a/tests/gem_concurrent_blit.c b/tests/gem_concurrent_blit.c > index 7d8d628..f9ea779 100644 > --- a/tests/gem_concurrent_blit.c > +++ b/tests/gem_concurrent_blit.c > @@ -49,11 +49,13 @@ > > #include "ioctl_wrappers.h" > #include "drmtest.h" > +#include "igt_aux.h" > +#include "igt_core.h" > +#include "igt_gt.h" > #include "intel_bufmgr.h" > #include "intel_batchbuffer.h" > #include "intel_io.h" > #include "intel_chipset.h" > -#include "igt_aux.h" > > int fd, devid, gen; > struct intel_batchbuffer *batch; > @@ -299,6 +301,7 @@ const int width = 512, height = 512; > igt_render_copyfunc_t rendercopy; > > typedef void (*do_copy)(drm_intel_bo *dst, drm_intel_bo *src); > +typedef struct igt_hang_ring (*do_hang)(void); > > static void render_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) > { > @@ -332,11 +335,57 @@ static void blt_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) > width, height, 32); > } > > +static void cpu_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) > +{ > + int size = 4*width*height; > + void *from = gem_mmap__cpu(fd, src->handle, size, PROT_READ); > + void *to = gem_mmap__cpu(fd, dst->handle, size, PROT_WRITE); > + gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_CPU, 0); > + gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); > + memcpy(to, from, size); > + munmap(to, size); > + munmap(from, size); > +} > + > +static void gtt_copy_bo(drm_intel_bo *dst, drm_intel_bo *src) > +{ > + int size = 4*width*height; > + void *from = gem_mmap__gtt(fd, src->handle, size, PROT_READ); > + void *to = gem_mmap__gtt(fd, dst->handle, size, PROT_WRITE); > + gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_GTT, 0); > + gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); > + memcpy(to, from, size); > + munmap(to, size); > + munmap(from, size); > +} > + > +static struct igt_hang_ring no_hang(void) > +{ > + return (struct igt_hang_ring){0, 0}; > +} > + > +static struct igt_hang_ring bcs_hang(void) > +{ > + return igt_hang_ring(fd, gen, I915_EXEC_BLT); > +} > + > +static struct igt_hang_ring rcs_hang(void) > +{ > + return igt_hang_ring(fd, gen, I915_EXEC_RENDER); > +} > + > +static void hang_require(void) > +{ > + igt_require(igt_can_hang_ring(fd, gen, -1)); > +} > + > static void do_overwrite_source(struct access_mode *mode, > drm_intel_bo **src, drm_intel_bo **dst, > drm_intel_bo *dummy, > - do_copy do_copy_func) > + do_copy do_copy_func, > + do_hang do_hang_func) > { > + struct igt_hang_ring hang; > int i; > > gem_quiescent_gpu(fd); > @@ -346,17 +395,63 @@ static void do_overwrite_source(struct access_mode *mode, > } > for (i = 0; i < num_buffers; i++) > do_copy_func(dst[i], src[i]); > + hang = do_hang_func(); > for (i = num_buffers; i--; ) > mode->set_bo(src[i], 0xdeadbeef, width, height); > for (i = 0; i < num_buffers; i++) > mode->cmp_bo(dst[i], i, width, height, dummy); > + igt_post_hang_ring(fd, hang); > +} > + > +static void do_overwrite_source__rev(struct access_mode *mode, > + drm_intel_bo **src, drm_intel_bo **dst, > + drm_intel_bo *dummy, > + do_copy do_copy_func, > + do_hang do_hang_func) > +{ > + struct igt_hang_ring hang; > + int i; > + > + gem_quiescent_gpu(fd); > + for (i = 0; i < num_buffers; i++) { > + mode->set_bo(src[i], i, width, height); > + mode->set_bo(dst[i], ~i, width, height); > + } > + for (i = 0; i < num_buffers; i++) > + do_copy_func(dst[i], src[i]); > + hang = do_hang_func(); > + for (i = 0; i < num_buffers; i++) > + mode->set_bo(src[i], 0xdeadbeef, width, height); > + for (i = num_buffers; i--; ) > + mode->cmp_bo(dst[i], i, width, height, dummy); > + igt_post_hang_ring(fd, hang); > +} > + > +static void do_overwrite_source__one(struct access_mode *mode, > + drm_intel_bo **src, drm_intel_bo **dst, > + drm_intel_bo *dummy, > + do_copy do_copy_func, > + do_hang do_hang_func) > +{ > + struct igt_hang_ring hang; > + > + gem_quiescent_gpu(fd); > + mode->set_bo(src[0], 0, width, height); > + mode->set_bo(dst[0], ~0, width, height); > + do_copy_func(dst[0], src[0]); > + hang = do_hang_func(); > + mode->set_bo(src[0], 0xdeadbeef, width, height); > + mode->cmp_bo(dst[0], 0, width, height, dummy); > + igt_post_hang_ring(fd, hang); > } > > static void do_early_read(struct access_mode *mode, > drm_intel_bo **src, drm_intel_bo **dst, > drm_intel_bo *dummy, > - do_copy do_copy_func) > + do_copy do_copy_func, > + do_hang do_hang_func) > { > + struct igt_hang_ring hang; > int i; > > gem_quiescent_gpu(fd); > @@ -364,15 +459,19 @@ static void do_early_read(struct access_mode *mode, > mode->set_bo(src[i], 0xdeadbeef, width, height); > for (i = 0; i < num_buffers; i++) > do_copy_func(dst[i], src[i]); > + hang = do_hang_func(); > for (i = num_buffers; i--; ) > mode->cmp_bo(dst[i], 0xdeadbeef, width, height, dummy); > + igt_post_hang_ring(fd, hang); > } > > static void do_gpu_read_after_write(struct access_mode *mode, > drm_intel_bo **src, drm_intel_bo **dst, > drm_intel_bo *dummy, > - do_copy do_copy_func) > + do_copy do_copy_func, > + do_hang do_hang_func) > { > + struct igt_hang_ring hang; > int i; > > gem_quiescent_gpu(fd); > @@ -382,47 +481,54 @@ static void do_gpu_read_after_write(struct access_mode *mode, > do_copy_func(dst[i], src[i]); > for (i = num_buffers; i--; ) > do_copy_func(dummy, dst[i]); > + hang = do_hang_func(); > for (i = num_buffers; i--; ) > mode->cmp_bo(dst[i], 0xabcdabcd, width, height, dummy); > + igt_post_hang_ring(fd, hang); > } > > typedef void (*do_test)(struct access_mode *mode, > drm_intel_bo **src, drm_intel_bo **dst, > drm_intel_bo *dummy, > - do_copy do_copy_func); > + do_copy do_copy_func, > + do_hang do_hang_func); > > typedef void (*run_wrap)(struct access_mode *mode, > drm_intel_bo **src, drm_intel_bo **dst, > drm_intel_bo *dummy, > do_test do_test_func, > - do_copy do_copy_func); > + do_copy do_copy_func, > + do_hang do_hang_func); > > static void run_single(struct access_mode *mode, > drm_intel_bo **src, drm_intel_bo **dst, > drm_intel_bo *dummy, > do_test do_test_func, > - do_copy do_copy_func) > + do_copy do_copy_func, > + do_hang do_hang_func) > { > - do_test_func(mode, src, dst, dummy, do_copy_func); > + do_test_func(mode, src, dst, dummy, do_copy_func, do_hang_func); > } > > static void run_interruptible(struct access_mode *mode, > drm_intel_bo **src, drm_intel_bo **dst, > drm_intel_bo *dummy, > do_test do_test_func, > - do_copy do_copy_func) > + do_copy do_copy_func, > + do_hang do_hang_func) > { > int loop; > > for (loop = 0; loop < 10; loop++) > - do_test_func(mode, src, dst, dummy, do_copy_func); > + do_test_func(mode, src, dst, dummy, do_copy_func, do_hang_func); > } > > static void run_forked(struct access_mode *mode, > drm_intel_bo **src, drm_intel_bo **dst, > drm_intel_bo *dummy, > do_test do_test_func, > - do_copy do_copy_func) > + do_copy do_copy_func, > + do_hang do_hang_func) > { > const int old_num_buffers = num_buffers; > drm_intel_bufmgr *bufmgr; > @@ -432,6 +538,7 @@ static void run_forked(struct access_mode *mode, > > igt_fork(child, 16) { > /* recreate process local variables */ > + fd = drm_open_any(); > bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); > drm_intel_bufmgr_gem_enable_reuse(bufmgr); > batch = intel_batchbuffer_alloc(bufmgr, devid); > @@ -441,7 +548,8 @@ static void run_forked(struct access_mode *mode, > } > dummy = mode->create_bo(bufmgr, width, height); > for (int loop = 0; loop < 10; loop++) > - do_test_func(mode, src, dst, dummy, do_copy_func); > + do_test_func(mode, src, dst, dummy, > + do_copy_func, do_hang_func); > /* as we borrow the fd, we need to reap our bo */ > for (int i = 0; i < num_buffers; i++) { > drm_intel_bo_unreference(src[i]); > @@ -450,6 +558,7 @@ static void run_forked(struct access_mode *mode, > drm_intel_bo_unreference(dummy); > intel_batchbuffer_free(batch); > drm_intel_bufmgr_destroy(bufmgr); > + close(fd); > } > > igt_waitchildren(); > @@ -457,51 +566,110 @@ static void run_forked(struct access_mode *mode, > num_buffers = old_num_buffers; > } > > -static void bcs_require(void) > +static void no_require(void) > { > } > > -static void rcs_require(void) > +static void rcs_copy_require(void) > { > igt_require(rendercopy); > } > > static void > run_basic_modes(struct access_mode *mode, > - drm_intel_bo **src, drm_intel_bo **dst, > - drm_intel_bo *dummy, const char *suffix, > + const char *suffix, > run_wrap run_wrap_func) > { > - struct { > + const struct { > const char *prefix; > do_copy copy; > void (*require)(void); > } pipelines[] = { > - { "bcs", blt_copy_bo, bcs_require }, > - { "rcs", render_copy_bo, rcs_require }, > + { "cpu", cpu_copy_bo, no_require }, > + { "gtt", gtt_copy_bo, no_require }, > + { "bcs", blt_copy_bo, no_require }, > + { "rcs", render_copy_bo, rcs_copy_require }, > { NULL, NULL } > }, *p; > + const struct { > + const char *suffix; > + do_hang hang; > + void (*require)(void); > + } hangs[] = { > + { "", no_hang, no_require }, > + { "-hang(bcs)", bcs_hang, hang_require }, > + { "-hang(rcs)", rcs_hang, hang_require }, > + { NULL, NULL }, > + }, *h; > + drm_intel_bo *src[MAX_NUM_BUFFERS], *dst[MAX_NUM_BUFFERS], *dummy = NULL; > + drm_intel_bufmgr *bufmgr; > > - for (p = pipelines; p->prefix; p++) { > - /* try to overwrite the source values */ > - igt_subtest_f("%s-%s-overwrite-source%s", mode->name, p->prefix, suffix) { > - p->require(); > - run_wrap_func(mode, src, dst, dummy, > - do_overwrite_source, p->copy); > - } > > - /* try to read the results before the copy completes */ > - igt_subtest_f("%s-%s-early-read%s", mode->name, p->prefix, suffix) { > - p->require(); > - run_wrap_func(mode, src, dst, dummy, > - do_early_read, p->copy); > - } > + for (h = hangs; h->suffix; h++) { > + for (p = pipelines; p->prefix; p++) { > + igt_fixture { > + bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); > + drm_intel_bufmgr_gem_enable_reuse(bufmgr); > + batch = intel_batchbuffer_alloc(bufmgr, devid); > > - /* and finally try to trick the kernel into loosing the pending write */ > - igt_subtest_f("%s-%s-gpu-read-after-write%s", mode->name, p->prefix, suffix) { > - p->require(); > - run_wrap_func(mode, src, dst, dummy, > - do_gpu_read_after_write, p->copy); > + for (int i = 0; i < num_buffers; i++) { > + src[i] = mode->create_bo(bufmgr, width, height); > + dst[i] = mode->create_bo(bufmgr, width, height); > + } > + dummy = mode->create_bo(bufmgr, width, height); > + } > + > + /* try to overwrite the source values */ > + igt_subtest_f("%s-%s-overwrite-source-one%s%s", mode->name, p->prefix, suffix, h->suffix) { > + h->require(); > + p->require(); > + run_wrap_func(mode, src, dst, dummy, > + do_overwrite_source__one, > + p->copy, h->hang); > + } > + > + igt_subtest_f("%s-%s-overwrite-source%s%s", mode->name, p->prefix, suffix, h->suffix) { > + h->require(); > + p->require(); > + run_wrap_func(mode, src, dst, dummy, > + do_overwrite_source, > + p->copy, h->hang); > + } > + igt_subtest_f("%s-%s-overwrite-source-rev%s%s", mode->name, p->prefix, suffix, h->suffix) { > + h->require(); > + p->require(); > + run_wrap_func(mode, src, dst, dummy, > + do_overwrite_source__rev, > + p->copy, h->hang); > + } > + > + /* try to read the results before the copy completes */ > + igt_subtest_f("%s-%s-early-read%s%s", mode->name, p->prefix, suffix, h->suffix) { > + h->require(); > + p->require(); > + run_wrap_func(mode, src, dst, dummy, > + do_early_read, > + p->copy, h->hang); > + } > + > + /* and finally try to trick the kernel into loosing the pending write */ > + igt_subtest_f("%s-%s-gpu-read-after-write%s%s", mode->name, p->prefix, suffix, h->suffix) { > + h->require(); > + p->require(); > + run_wrap_func(mode, src, dst, dummy, > + do_gpu_read_after_write, > + p->copy, h->hang); > + } > + > + igt_fixture { > + for (int i = 0; i < num_buffers; i++) { > + drm_intel_bo_unreference(src[i]); > + drm_intel_bo_unreference(dst[i]); > + } > + drm_intel_bo_unreference(dummy); > + intel_batchbuffer_free(batch); > + drm_intel_bufmgr_destroy(bufmgr); > + } > } > } > } > @@ -509,39 +677,14 @@ run_basic_modes(struct access_mode *mode, > static void > run_modes(struct access_mode *mode) > { > - drm_intel_bo *src[MAX_NUM_BUFFERS], *dst[MAX_NUM_BUFFERS], *dummy = NULL; > - drm_intel_bufmgr *bufmgr; > - > - igt_fixture { > - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); > - drm_intel_bufmgr_gem_enable_reuse(bufmgr); > - batch = intel_batchbuffer_alloc(bufmgr, devid); > - > - for (int i = 0; i < num_buffers; i++) { > - src[i] = mode->create_bo(bufmgr, width, height); > - dst[i] = mode->create_bo(bufmgr, width, height); > - } > - dummy = mode->create_bo(bufmgr, width, height); > - } > - > - run_basic_modes(mode, src, dst, dummy, "", run_single); > + run_basic_modes(mode, "", run_single); > > igt_fork_signal_helper(); > - run_basic_modes(mode, src, dst, dummy, "-interruptible", run_interruptible); > + run_basic_modes(mode, "-interruptible", run_interruptible); > igt_stop_signal_helper(); > > - igt_fixture { > - for (int i = 0; i < num_buffers; i++) { > - drm_intel_bo_unreference(src[i]); > - drm_intel_bo_unreference(dst[i]); > - } > - drm_intel_bo_unreference(dummy); > - intel_batchbuffer_free(batch); > - drm_intel_bufmgr_destroy(bufmgr); > - } > - > igt_fork_signal_helper(); > - run_basic_modes(mode, src, dst, dummy, "-forked", run_forked); > + run_basic_modes(mode, "-forked", run_forked); > igt_stop_signal_helper(); > } > > -- > 2.1.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx