lib/dummyload: Add pollable spin batch
PATCH 1/3 lib/dummyload: Add pollable spin batch
From: Tvrtko Ursulin <[email protected]>
Pollable spin batch exports a spin->running pointer which can be checked by dereferencing it to see if the spinner is actually executing on the GPU.
This is useful for tests which want to make sure they do not proceed with their next step whilst the spinner is potentially only being processed by the driver and not actually executing.
Pollable spinner can be created with igt_spin_batch_new_poll or __igt_spin_batch_new_poll, after which a loop similar to:
while (!*(volatile bool *)spin->running) ;
Can be used to wait until the spinner start execution.
--- lib/igt_dummyload.c | 192 ++++++++++++++++++++++++++++++++++++++++----------- lib/igt_dummyload.h | 11 +++ lib/igt_gt.c | 2 +- lib/ioctl_wrappers.c | 2 +- lib/ioctl_wrappers.h | 1 + 5 files changed, 167 insertions(+), 41 deletions(-)
lib/igt_dummyload.c +153 -39
@@ -74,35 +74,48 @@ fill_reloc(struct drm_i915_gem_relocation_entry *reloc, reloc->write_domain = write_domains; } -static int emit_recursive_batch (igt_spin_t *spin, -int fd,uint32_t ctx,unsigned engine, -uint32_t dep,bool out_fence) +#define OUT_FENCE (1 << 0) +#define POLL_RUN (1 << 1) + +static int +emit_recursive_batch (igt_spin_t *spin,int fd,uint32_t ctx,unsigned engine, +uint32_t dep,unsigned int flags) {#define SCRATCH 0#define BATCH 1const int gen =intel_gen (intel_get_drm_devid (fd)); -struct drm_i915_gem_exec_object2 obj[2 ]; -struct drm_i915_gem_relocation_entry relocs[2 ]; -struct drm_i915_gem_execbuffer2 execbuf; +struct drm_i915_gem_relocation_entry relocs[2 ], *r; +struct drm_i915_gem_execbuffer2 *execbuf; +struct drm_i915_gem_exec_object2 *obj;unsigned int engines[16 ];unsigned int nengine;int fence_fd =-1 ; -uint32_t *batch; +uint32_t *batch, *batch_start;int i; nengine =0 ;if (engine ==ALL_ENGINES ) { -for_each_engine (fd, engine) -if (engine) +for_each_engine (fd, engine) { +if (engine) { +if (flags &POLL_RUN ) +igt_require (!(flags &POLL_RUN ) || +gem_can_store_dword (fd, engine)); + engines[nengine++] = engine; + } + } }else {gem_require_ring (fd, engine); +igt_require (!(flags &POLL_RUN ) || +gem_can_store_dword (fd, engine)); engines[nengine++] = engine; }igt_require (nengine); -memset (&execbuf,0 ,sizeof (execbuf)); -memset (obj,0 ,sizeof (obj)); +memset (&spin->execbuf,0 ,sizeof (spin->execbuf)); + execbuf = &spin->execbuf; +memset (spin->obj,0 ,sizeof (spin->obj)); + obj = spin->obj;memset (relocs,0 ,sizeof (relocs)); obj[BATCH ].handle =gem_create (fd,BATCH_SIZE );
@@ -113,19 +126,66 @@ static int emit_recursive_batch(igt_spin_t *spin, BATCH_SIZE, PROT_WRITE);gem_set_domain (fd, obj[BATCH ].handle,I915_GEM_DOMAIN_GTT ,I915_GEM_DOMAIN_GTT ); - execbuf.buffer_count++; + execbuf->buffer_count++; + batch_start = batch;if (dep) { +igt_assert (!(flags &POLL_RUN )); +/* dummy write to dependency */ obj[SCRATCH ].handle = dep;fill_reloc (&relocs[obj[BATCH ].relocation_count++], dep,1020 ,I915_GEM_DOMAIN_RENDER ,I915_GEM_DOMAIN_RENDER ); - execbuf.buffer_count++; + execbuf->buffer_count++; + }else if (flags &POLL_RUN ) { +unsigned int offset; + +igt_assert (!dep); + +if (gen ==4 || gen ==5 ) + execbuf->flags |=I915_EXEC_SECURE ; + + spin->poll_handle =gem_create (fd,4096 ); + +if (__gem_set_caching (fd, spin->poll_handle, +I915_CACHING_CACHED ) ==0 ) + spin->running =__gem_mmap__cpu (fd, spin->poll_handle, +0 ,4096 , +PROT_READ |PROT_WRITE ); +else + spin->running =__gem_mmap__wc (fd, spin->poll_handle, +0 ,4096 , +PROT_READ |PROT_WRITE ); +igt_assert (spin->running); +igt_assert_eq (*spin->running,0 ); + + *batch++ =MI_STORE_DWORD_IMM | (gen <6 ?1 <<22 :0 ); + +if (gen >=8 ) { + offset =1 ; + *batch++ =0 ; + *batch++ =0 ; + }else if (gen >=4 ) { + offset =2 ; + *batch++ =0 ; + *batch++ =0 ; + }else { + offset =1 ; + batch[-1 ]--; + *batch++ =0 ; + } + + *batch++ =1 ; + + obj[SCRATCH ].handle = spin->poll_handle; +fill_reloc (&relocs[obj[BATCH ].relocation_count++], + spin->poll_handle, offset,0 ,0 ); + execbuf->buffer_count++; } - spin->batch = batch; + spin->batch = batch = batch_start +64 /sizeof (*batch); spin->handle = obj[BATCH ].handle;/* Allow ourselves to be preempted */
@@ -145,40 +205,42 @@ static int emit_recursive_batch(igt_spin_t *spin, batch +=1000 ;/* recurse */ -fill_reloc (&relocs[obj[BATCH ].relocation_count], - obj[BATCH ].handle, (batch - spin->batch) +1 , -I915_GEM_DOMAIN_COMMAND ,0 ); + r = &relocs[obj[BATCH ].relocation_count++]; + r->target_handle = obj[BATCH ].handle; + r->offset = (batch +1 - batch_start) *sizeof (*batch); + r->read_domains =I915_GEM_DOMAIN_COMMAND ; + r->delta =64 ;if (gen >=8 ) { *batch++ =MI_BATCH_BUFFER_START |1 <<8 |1 ; - *batch++ =0 ; + *batch++ = r->delta; *batch++ =0 ; }else if (gen >=6 ) { *batch++ =MI_BATCH_BUFFER_START |1 <<8 ; - *batch++ =0 ; + *batch++ = r->delta; }else { *batch++ =MI_BATCH_BUFFER_START |2 <<6 ; - *batch =0 ; -if (gen <4 ) { - *batch |=1 ; - relocs[obj[BATCH ].relocation_count].delta =1 ; - } +if (gen <4 ) + r->delta |=1 ; + *batch = r->delta; batch++; } - obj[BATCH ].relocation_count++; obj[BATCH ].relocs_ptr =to_user_pointer (relocs); - execbuf.buffers_ptr =to_user_pointer (obj + (2 - execbuf.buffer_count)); - execbuf.rsvd1 = ctx; + execbuf->buffers_ptr =to_user_pointer (obj + + (2 - execbuf->buffer_count)); + execbuf->rsvd1 = ctx; -if (out_fence) - execbuf.flags |=I915_EXEC_FENCE_OUT ; +if (flags &OUT_FENCE ) + execbuf->flags |=I915_EXEC_FENCE_OUT ;for (i =0 ; i < nengine; i++) { - execbuf.flags &= ~ENGINE_MASK ; - execbuf.flags |= engines[i]; -gem_execbuf_wr (fd, &execbuf); -if (out_fence) { -int _fd = execbuf.rsvd2 >>32 ; + execbuf->flags &= ~ENGINE_MASK ; + execbuf->flags |= engines[i]; + +gem_execbuf_wr (fd, execbuf); + +if (flags &OUT_FENCE ) { +int _fd = execbuf->rsvd2 >>32 ;igt_assert (_fd >=0 );if (fence_fd ==-1 ) {
@@ -194,12 +256,20 @@ static int emit_recursive_batch(igt_spin_t *spin, } } +/* Make it easier for callers to resubmit. */ + + obj[BATCH ].relocation_count =0 ; + obj[BATCH ].relocs_ptr =0 ; + + obj[SCRATCH ].flags =EXEC_OBJECT_PINNED ; + obj[BATCH ].flags =EXEC_OBJECT_PINNED ; +return fence_fd; }static igt_spin_t *___igt_spin_batch_new (int fd,uint32_t ctx,unsigned engine,uint32_t dep, -int out_fence) +unsigned int flags) {igt_spin_t *spin;
@@ -207,7 +277,7 @@ ___igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep,igt_assert (spin); spin->out_fence =emit_recursive_batch (spin, fd, ctx, engine, dep, - out_fence); + flags);pthread_mutex_lock (&list_lock);igt_list_add (&spin->link, &spin_list);
@@ -219,7 +289,7 @@ ___igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep,igt_spin_t *__igt_spin_batch_new (int fd,uint32_t ctx,unsigned engine,uint32_t dep) { -return ___igt_spin_batch_new (fd, ctx, engine, dep, false); +return ___igt_spin_batch_new (fd, ctx, engine, dep,0 ); }/**
@@ -253,7 +323,7 @@ igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep)igt_spin_t *__igt_spin_batch_new_fence (int fd,uint32_t ctx,unsigned engine) { -return ___igt_spin_batch_new (fd, ctx, engine,0 , true); +return ___igt_spin_batch_new (fd, ctx, engine,0 ,OUT_FENCE ); }/**
@@ -286,6 +356,42 @@ igt_spin_batch_new_fence(int fd, uint32_t ctx, unsigned engine)return spin; } +igt_spin_t * +__igt_spin_batch_new_poll (int fd,uint32_t ctx,unsigned engine) +{ +return ___igt_spin_batch_new (fd, ctx, engine,0 ,POLL_RUN ); +} + +/** +* igt_spin_batch_new_poll: +* @fd: open i915 drm file descriptor +* @engine: Ring to execute batch OR'd with execbuf flags. If value is less +* than 0, execute on all available rings. +* +* Start a recursive batch on a ring. Immediately returns a #igt_spin_t that +* contains the batch's handle that can be waited upon. The returned structure +* must be passed to igt_spin_batch_free() for post-processing. +* +* igt_spin_t->running will containt a pointer which target will change from +* zero to one once the spinner actually starts executing on the GPU. +* +* Returns: +* Structure with helper internal state for igt_spin_batch_free(). +*/ +igt_spin_t * +igt_spin_batch_new_poll (int fd,uint32_t ctx,unsigned engine) +{ +igt_spin_t *spin; + +igt_require_gem (fd); +igt_require (gem_mmap__has_wc (fd)); + + spin =__igt_spin_batch_new_poll (fd, ctx, engine); +igt_assert (gem_bo_busy (fd, spin->handle)); + +return spin; +} +static void notify (union sigval arg) {igt_spin_t *spin = arg.sival_ptr;
@@ -340,6 +446,8 @@ void igt_spin_batch_end(igt_spin_t *spin)if (!spin)return ; +igt_assert (*spin->batch ==MI_ARB_CHK || + *spin->batch ==MI_BATCH_BUFFER_END ); *spin->batch =MI_BATCH_BUFFER_END ;__sync_synchronize (); }
@@ -365,7 +473,13 @@ void igt_spin_batch_free(int fd, igt_spin_t *spin)timer_delete (spin->timer);igt_spin_batch_end (spin); -gem_munmap (spin->batch,BATCH_SIZE ); +gem_munmap ((void *)((unsigned long )spin->batch & (~4095UL )), +BATCH_SIZE ); + +if (spin->running) { +gem_munmap (spin->running,4096 ); +gem_close (fd, spin->poll_handle); + }gem_close (fd, spin->handle);
lib/igt_dummyload.h +11 -0
@@ -36,6 +36,10 @@ typedef struct igt_spin {struct igt_list link;uint32_t *batch;int out_fence; +struct drm_i915_gem_exec_object2 obj[2 ]; +struct drm_i915_gem_execbuffer2 execbuf; +uint32_t poll_handle; +bool *running; } igt_spin_t; igt_spin_t *__igt_spin_batch_new(int fd,
@@ -55,6 +59,13 @@ igt_spin_t *igt_spin_batch_new_fence(int fd,uint32_t ctx, unsigned engine); +igt_spin_t *__igt_spin_batch_new_poll (int fd, +uint32_t ctx, +unsigned engine); +igt_spin_t *igt_spin_batch_new_poll (int fd, +uint32_t ctx, +unsigned engine); +void igt_spin_batch_set_timeout (igt_spin_t *spin,int64_t ns);void igt_spin_batch_end (igt_spin_t *spin);void igt_spin_batch_free (int fd,igt_spin_t *spin);
lib/igt_gt.c +1 -1
@@ -609,7 +609,7 @@ bool gem_can_store_dword(int fd, unsigned int engine)if (gen ==3 && (info->is_grantsdale || info->is_alviso))return false;/* only supports physical addresses */ -if (gen ==6 && (engine & ~(3 <<13 )) ==I915_EXEC_BSD ) +if (gen ==6 && ((engine &0x3f ) ==I915_EXEC_BSD ))return false;/* kills the machine! */ if (info->is_broadwater)
lib/ioctl_wrappers.c +1 -1
@@ -198,7 +198,7 @@ void gem_set_tiling(int fd, uint32_t handle, uint32_t tiling, uint32_t stride)igt_assert (__gem_set_tiling (fd, handle, tiling, stride) ==0 ); } -static int __gem_set_caching (int fd,uint32_t handle,uint32_t caching) +int __gem_set_caching (int fd,uint32_t handle,uint32_t caching) {struct drm_i915_gem_caching arg;int err;
lib/ioctl_wrappers.h +1 -0
@@ -61,6 +61,7 @@ bool gem_get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzlevoid gem_set_tiling (int fd,uint32_t handle,uint32_t tiling,uint32_t stride);int __gem_set_tiling (int fd,uint32_t handle,uint32_t tiling,uint32_t stride); +int __gem_set_caching (int fd,uint32_t handle,uint32_t caching);void gem_set_caching (int fd,uint32_t handle,uint32_t caching);uint32_t gem_get_caching (int fd,uint32_t handle);uint32_t gem_flink (int fd,uint32_t handle);
Signature · 6 lines
2.14.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 2/3 tests/gem_eio: Speed up test execution
From: Tvrtko Ursulin <[email protected]>
If we stop relying on regular GPU hangs to be detected, but trigger them manually as soon as we know our batch of interest is actually executing on the GPU, we can dramatically speed up various subtests.
This is enabled by the pollable spin batch added in the previous patch.
---
Note that the 'wait' subtest is mysteriously hanging for me in the no-op batch send by gem_test_engines, but only on RCS engine. TBD while I am getting some CI results.
--- lib.tar | Bin 0 -> 102400 bytes tests/gem_eio.c | 97 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 lib.tar
lib.tar new file binary +0 -0
tests/gem_eio.c +70 -27
201 lines not on this page · raw message
Signature · 6 lines
2.14.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH v2 2/3 tests/gem_eio: Speed up test execution
From: Tvrtko Ursulin <[email protected]>
If we stop relying on regular GPU hangs to be detected, but trigger them manually as soon as we know our batch of interest is actually executing on the GPU, we can dramatically speed up various subtests.
This is enabled by the pollable spin batch added in the previous patch.
---
Note that the 'wait' subtest is mysteriously hanging for me in the no-op batch send by gem_test_engines, but only on RCS engine. TBD while I am getting some CI results.
--- tests/gem_eio.c | 97 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 27 deletions(-)
tests/gem_eio.c +70 -27
@@ -71,26 +71,23 @@ static void trigger_reset(int fd)gem_quiescent_gpu (fd); } -static void wedge_gpu (int fd) +static void manual_hang (int drm_fd) { -/* First idle the GPU then disable GPU resets before injecting a hang */ -gem_quiescent_gpu (fd); - -igt_require (i915_reset_control (false)); +int dir =igt_debugfs_dir (drm_fd); -igt_debug ("Wedging GPU by injecting hang\n" ); -igt_post_hang_ring (fd,igt_hang_ring (fd,I915_EXEC_DEFAULT )); +igt_sysfs_set (dir,"i915_wedged" ,"-1" ); -igt_assert (i915_reset_control (true)); +close (dir); } -static void wedgeme (int drm_fd) +static void wedge_gpu (int fd) { -int dir =igt_debugfs_dir (drm_fd); - -igt_sysfs_set (dir,"i915_wedged" ,"-1" ); +/* First idle the GPU then disable GPU resets before injecting a hang */ +gem_quiescent_gpu (fd); -close (dir); +igt_require (i915_reset_control (false)); +manual_hang (fd); +igt_assert (i915_reset_control (true)); }static int __gem_throttle (int fd)
@@ -149,29 +146,66 @@ static int __gem_wait(int fd, uint32_t handle, int64_t timeout)return err; } +static igt_spin_t *__spin_poll (int fd,uint32_t ctx,unsigned long flags) +{ +if (gem_can_store_dword (fd, flags)) +return __igt_spin_batch_new_poll (fd, ctx, flags); +else +return __igt_spin_batch_new (fd, ctx, flags,0 ); +} + +static void __spin_wait (int fd,igt_spin_t *spin) +{ +if (spin->running) { +while (!*((volatile bool *)spin->running)) + ; + }else { +igt_debug ("__spin_wait - usleep mode\n" ); +usleep (500e3 );/* Better than nothing! */ + } +} + +/* +* Wedge the GPU when we know our batch is running. +*/ +static void wedge_after_running (int fd,igt_spin_t *spin) +{ +__spin_wait (fd, spin); +manual_hang (fd); +} +static void test_wait (int fd) { -igt_hang_t hang; +struct timespec ts = { }; +igt_spin_t *hang;igt_require_gem (fd); +igt_nsec_elapsed (&ts); +/* If the request we wait on completes due to a hang (even for * that request), the user expects the return value to 0 (success). */ - hang =igt_hang_ring (fd,I915_EXEC_DEFAULT ); -igt_assert_eq (__gem_wait (fd, hang.handle,-1 ),0 ); -igt_post_hang_ring (fd, hang); +igt_require (i915_reset_control (true)); + hang =__spin_poll (fd,0 ,I915_EXEC_DEFAULT ); +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, hang->handle,-1 ),0 ); +igt_spin_batch_free (fd, hang);/* If the GPU is wedged during the wait, again we expect the return * value to be 0 (success). */ igt_require (i915_reset_control (false)); - hang =igt_hang_ring (fd,I915_EXEC_DEFAULT ); -igt_assert_eq (__gem_wait (fd, hang.handle,-1 ),0 ); -igt_post_hang_ring (fd, hang); + hang =__spin_poll (fd,0 ,I915_EXEC_DEFAULT ); +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, hang->handle,-1 ),0 ); +igt_spin_batch_free (fd, hang);igt_require (i915_reset_control (true));trigger_reset (fd); + +/* HACK for CI */ +igt_assert (igt_nsec_elapsed (&ts) <5e9 ); }static void test_suspend (int fd,int state)
@@ -181,7 +215,7 @@ static void test_suspend(int fd, int state)/* Check we can suspend when the driver is already wedged */ igt_require (i915_reset_control (false)); -wedgeme (fd); +manual_hang (fd);igt_system_suspend_autoresume (state,SUSPEND_TEST_DEVICES );
@@ -209,11 +243,10 @@ static void test_inflight(int fd)int fence[64 ];/* conservative estimate of ring size */ gem_quiescent_gpu (fd); -igt_debug ("Starting %s on engine '%s'\n" , __func__, e__->name);igt_require (i915_reset_control (false)); - hang =__igt_spin_batch_new (fd,0 , engine,0 ); + hang =__spin_poll (fd,0 , engine); obj[0 ].handle = hang->handle;memset (&execbuf,0 ,sizeof (execbuf));
@@ -227,6 +260,8 @@ static void test_inflight(int fd)igt_assert (fence[n] !=-1 ); } +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, obj[1 ].handle,-1 ),0 );for (unsigned int n =0 ; n <ARRAY_SIZE (fence); n++) {igt_assert_eq (sync_fence_status (fence[n]), -EIO );
@@ -256,7 +291,7 @@ static void test_inflight_suspend(int fd) obj[1 ].handle =gem_create (fd,4096 );gem_write (fd, obj[1 ].handle,0 , &bbe,sizeof (bbe)); - hang =__igt_spin_batch_new (fd,0 ,0 ,0 ); + hang =__spin_poll (fd,0 ,0 ); obj[0 ].handle = hang->handle;memset (&execbuf,0 ,sizeof (execbuf));
@@ -273,6 +308,8 @@ static void test_inflight_suspend(int fd)igt_set_autoresume_delay (30 );igt_system_suspend_autoresume (SUSPEND_STATE_MEM ,SUSPEND_TEST_NONE ); +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, obj[1 ].handle,-1 ),0 );for (unsigned int n =0 ; n <ARRAY_SIZE (fence); n++) {igt_assert_eq (sync_fence_status (fence[n]), -EIO );
@@ -330,7 +367,7 @@ static void test_inflight_contexts(int fd)igt_debug ("Starting %s on engine '%s'\n" , __func__, e__->name);igt_require (i915_reset_control (false)); - hang =__igt_spin_batch_new (fd,0 , engine,0 ); + hang =__spin_poll (fd, ctx[0 ], engine); obj[0 ].handle = hang->handle;memset (&execbuf,0 ,sizeof (execbuf));
@@ -345,6 +382,8 @@ static void test_inflight_contexts(int fd)igt_assert (fence[n] !=-1 ); } +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, obj[1 ].handle,-1 ),0 );for (unsigned int n =0 ; n <ARRAY_SIZE (fence); n++) {igt_assert_eq (sync_fence_status (fence[n]), -EIO );
@@ -375,7 +414,7 @@ static void test_inflight_external(int fd) fence =igt_cork_plug (&cork, fd);igt_require (i915_reset_control (false)); - hang =__igt_spin_batch_new (fd,0 ,0 ,0 ); + hang =__spin_poll (fd,0 ,0 );memset (&obj,0 ,sizeof (obj)); obj.handle =gem_create (fd,4096 );
@@ -393,6 +432,8 @@ static void test_inflight_external(int fd) fence = execbuf.rsvd2 >>32 ;igt_assert (fence !=-1 ); +wedge_after_running (fd, hang); +gem_sync (fd, hang->handle);/* wedged, with an unready batch */ igt_assert (!gem_bo_busy (fd, hang->handle));igt_assert (gem_bo_busy (fd, obj.handle));
@@ -420,7 +461,7 @@ static void test_inflight_internal(int fd)igt_require (gem_has_exec_fence (fd));igt_require (i915_reset_control (false)); - hang =__igt_spin_batch_new (fd,0 ,0 ,0 ); + hang =__spin_poll (fd,0 ,0 );memset (obj,0 ,sizeof (obj)); obj[0 ].handle = hang->handle;
@@ -441,6 +482,8 @@ static void test_inflight_internal(int fd) nfence++; } +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, obj[1 ].handle,-1 ),0 );while (nfence--) {igt_assert_eq (sync_fence_status (fences[nfence]), -EIO );
Signature · 6 lines
2.14.1 _______________________________________________ igt-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/igt-dev
Re: [igt-dev] [PATCH i-g-t 2/3] tests/gem_eio: Speed up test execution
In reply to Tvrtko UrsulinQuoting Tvrtko Ursulin (2018-03-22 11:17:11)
lib.tar
Quoted 27 lines
From: Tvrtko Ursulin <[email protected]>
If we stop relying on regular GPU hangs to be detected, but trigger them manually as soon as we know our batch of interest is actually executing on the GPU, we can dramatically speed up various subtests.
This is enabled by the pollable spin batch added in the previous patch.
Signed-off-by Tvrtko Ursulin <[email protected]>Suggested-by Chris Wilson <[email protected]>Cc Antonio Argenziano <[email protected]>---
Note that the 'wait' subtest is mysteriously hanging for me in the no-op batch send bygem_test_engines, but only on RCS engine. TBD while I am getting some CI results.--- lib.tar | Bin 0 -> 102400 bytes tests/gem_eio.c | 97 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 lib.tarlib.tar new file binary +0
-0
Looks correct.
Quoted 14 lines
tests/gem_eio.c +1
-4@@ -71,26 +71,23 @@ static void trigger_reset(int fd)gem_quiescent_gpu (fd); } -static void wedge_gpu (int fd) +static void manual_hang (int drm_fd) { -/* First idle the GPU then disable GPU resets before injecting a hang */ -gem_quiescent_gpu (fd); -
tests/gem_eio.c static void trigger_reset(int fd) · line 81
Quoted 10 lines
tests/gem_eio.c +3
-4-igt_require (i915_reset_control (false)); +int dir =igt_debugfs_dir (drm_fd); -igt_debug ("Wedging GPU by injecting hang\n" ); -igt_post_hang_ring (fd,igt_hang_ring (fd,I915_EXEC_DEFAULT )); +igt_sysfs_set (dir,"i915_wedged" ,"-1" ); -igt_assert (i915_reset_control (true)); +close (dir); }
Ok.
Quoted 4 lines
tests/gem_eio.c +1
-2-static void wedgeme (int drm_fd) +static void wedge_gpu (int fd) { -int dir =igt_debugfs_dir (drm_fd);
tests/gem_eio.c static void trigger_reset(int fd) · line 91
Quoted 10 lines
tests/gem_eio.c +5
-3- -igt_sysfs_set (dir,"i915_wedged" ,"-1" ); +/* First idle the GPU then disable GPU resets before injecting a hang */ +gem_quiescent_gpu (fd); -close (dir); +igt_require (i915_reset_control (false)); +manual_hang (fd); +igt_assert (i915_reset_control (true)); }
Ok.
Quoted 59 lines
tests/gem_eio.c +37
-4static int __gem_throttle (int fd)@@ -149,29 +146,66 @@ static int __gem_wait(int fd, uint32_t handle, int64_t timeout)return err; } +static igt_spin_t *__spin_poll (int fd,uint32_t ctx,unsigned long flags) +{ +if (gem_can_store_dword (fd, flags)) +return __igt_spin_batch_new_poll (fd, ctx, flags); +else +return __igt_spin_batch_new (fd, ctx, flags,0 ); +} + +static void __spin_wait (int fd,igt_spin_t *spin) +{ +if (spin->running) { +while (!*((volatile bool *)spin->running)) + ; + }else { +igt_debug ("__spin_wait - usleep mode\n" ); +usleep (500e3 );/* Better than nothing! */ + } +} + +/* +* Wedge the GPU when we know our batch is running. +*/ +static void wedge_after_running (int fd,igt_spin_t *spin) +{ +__spin_wait (fd, spin); +manual_hang (fd); +} +static void test_wait (int fd) { -igt_hang_t hang; +struct timespec ts = { }; +igt_spin_t *hang;igt_require_gem (fd); +igt_nsec_elapsed (&ts); +/* If the request we wait on completes due to a hang (even for * that request), the user expects the return value to 0 (success). */ - hang =igt_hang_ring (fd,I915_EXEC_DEFAULT ); -igt_assert_eq (__gem_wait (fd, hang.handle,-1 ),0 ); -igt_post_hang_ring (fd, hang); +igt_require (i915_reset_control (true)); + hang =__spin_poll (fd,0 ,I915_EXEC_DEFAULT ); +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, hang->handle,-1 ),0 ); +igt_spin_batch_free (fd, hang);/* If the GPU is wedged during the wait, again we expect the return * value to be 0 (success).
tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 204
Quoted 10 lines
tests/gem_eio.c +4
-3*/ igt_require (i915_reset_control (false)); - hang =igt_hang_ring (fd,I915_EXEC_DEFAULT ); -igt_assert_eq (__gem_wait (fd, hang.handle,-1 ),0 ); -igt_post_hang_ring (fd, hang); + hang =__spin_poll (fd,0 ,I915_EXEC_DEFAULT ); +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, hang->handle,-1 ),0 ); +igt_spin_batch_free (fd, hang);igt_require (i915_reset_control (true));
Hmm. These are not equivalent to the original test. The tests requires hangcheck to kick in while the test is blocked on igt_wait. To do a fast equivalent, we need to kick off a timer. (Here we are just asking if a wait on an already completed request doesn't block, not how we handle the reset in the middle of a wait. Seems a reasonable addition though.)
I think that's a general pattern worth repeating for the rest of tests:
don't immediately inject the hang, but leave it a few milliseconds to allow us to block on the subsequent wait. I would even repeat the tests a few times with different timeouts; 0, 1us, 10ms (thinking of the different phases for i915_request_wait).
tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 208
Quoted 4 lines
tests/gem_eio.c +3
-0trigger_reset (fd); + +/* HACK for CI */ +igt_assert (igt_nsec_elapsed (&ts) <5e9 );
igt_seconds_elapsed() the approximation is worth the readability.
In this case you might like to try igt_set_timeout(), as I think each subtest and exithandlers are in place to make them robust against premature failures.
-Chris
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Re: [igt-dev] [PATCH i-g-t 2/3] tests/gem_eio: Speed up test execution
Quoted 22 lines · Chris Wilson
Quoting Tvrtko Ursulin (2018-03-22 11:17:11)
Quoted 21 lines
From: Tvrtko Ursulin <[email protected]>
If we stop relying on regular GPU hangs to be detected, but trigger them manually as soon as we know our batch of interest is actually executing on the GPU, we can dramatically speed up various subtests.
This is enabled by the pollable spin batch added in the previous patch.
Signed-off-by Tvrtko Ursulin <[email protected]>Suggested-by Chris Wilson <[email protected]>Cc Antonio Argenziano <[email protected]>---
Note that the 'wait' subtest is mysteriously hanging for me in the no-op batch send bygem_test_engines, but only on RCS engine. TBD while I am getting some CI results.--- lib.tar | Bin 0 -> 102400 bytes tests/gem_eio.c | 97 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 70 insertions(+), 27 deletions(-)create mode 100644 lib.tar
Quoted 8 lines
lib.tar
Quoted 6 lines
lib.tar new file binary +0
-0Looks correct.
Just backing up in the cloud. :))
Quoted 36 lines
Quoted 14 lines
tests/gem_eio.c +1
-4@@ -71,26 +71,23 @@ static void trigger_reset(int fd)gem_quiescent_gpu (fd); } -static void wedge_gpu (int fd) +static void manual_hang (int drm_fd) { -/* First idle the GPU then disable GPU resets before injecting a hang */ -gem_quiescent_gpu (fd); -tests/gem_eio.c static void trigger_reset(int fd) · line 81
Quoted 10 lines
tests/gem_eio.c +3
-4-igt_require (i915_reset_control (false)); +int dir =igt_debugfs_dir (drm_fd); -igt_debug ("Wedging GPU by injecting hang\n" ); -igt_post_hang_ring (fd,igt_hang_ring (fd,I915_EXEC_DEFAULT )); +igt_sysfs_set (dir,"i915_wedged" ,"-1" ); -igt_assert (i915_reset_control (true)); +close (dir); }Ok.
Quoted 9 lines
tests/gem_eio.c +3
-4-static void wedgeme (int drm_fd) +static void wedge_gpu (int fd) { -int dir =igt_debugfs_dir (drm_fd); - -igt_sysfs_set (dir,"i915_wedged" ,"-1" ); +/* First idle the GPU then disable GPU resets before injecting a hang */ +gem_quiescent_gpu (fd);
Quoted 7 lines
tests/gem_eio.c static void trigger_reset(int fd) · line 91
Quoted 5 lines
tests/gem_eio.c +3
-1-close (dir); +igt_require (i915_reset_control (false)); +manual_hang (fd); +igt_assert (i915_reset_control (true)); }Ok.
Well done reading that awful diff!
Quoted 77 lines
Quoted 59 lines
tests/gem_eio.c +37
-4static int __gem_throttle (int fd)@@ -149,29 +146,66 @@ static int __gem_wait(int fd, uint32_t handle, int64_t timeout)return err; } +static igt_spin_t *__spin_poll (int fd,uint32_t ctx,unsigned long flags) +{ +if (gem_can_store_dword (fd, flags)) +return __igt_spin_batch_new_poll (fd, ctx, flags); +else +return __igt_spin_batch_new (fd, ctx, flags,0 ); +} + +static void __spin_wait (int fd,igt_spin_t *spin) +{ +if (spin->running) { +while (!*((volatile bool *)spin->running)) + ; + }else { +igt_debug ("__spin_wait - usleep mode\n" ); +usleep (500e3 );/* Better than nothing! */ + } +} + +/* +* Wedge the GPU when we know our batch is running. +*/ +static void wedge_after_running (int fd,igt_spin_t *spin) +{ +__spin_wait (fd, spin); +manual_hang (fd); +} +static void test_wait (int fd) { -igt_hang_t hang; +struct timespec ts = { }; +igt_spin_t *hang;igt_require_gem (fd); +igt_nsec_elapsed (&ts); +/* If the request we wait on completes due to a hang (even for * that request), the user expects the return value to 0 (success). */ - hang =igt_hang_ring (fd,I915_EXEC_DEFAULT ); -igt_assert_eq (__gem_wait (fd, hang.handle,-1 ),0 ); -igt_post_hang_ring (fd, hang); +igt_require (i915_reset_control (true)); + hang =__spin_poll (fd,0 ,I915_EXEC_DEFAULT ); +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, hang->handle,-1 ),0 ); +igt_spin_batch_free (fd, hang);/* If the GPU is wedged during the wait, again we expect the return * value to be 0 (success). tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 204
Quoted 10 lines
tests/gem_eio.c +4
-3*/ igt_require (i915_reset_control (false)); - hang =igt_hang_ring (fd,I915_EXEC_DEFAULT ); -igt_assert_eq (__gem_wait (fd, hang.handle,-1 ),0 ); -igt_post_hang_ring (fd, hang); + hang =__spin_poll (fd,0 ,I915_EXEC_DEFAULT ); +wedge_after_running (fd, hang); +igt_assert_eq (__gem_wait (fd, hang->handle,-1 ),0 ); +igt_spin_batch_free (fd, hang);igt_require (i915_reset_control (true));Hmm. These are not equivalent to the original test. The tests requires hangcheck to kick in while the test is blocked on
igt_wait. To do a fast equivalent, we need to kick off a timer. (Here we are just asking if a wait on an already completed request doesn't block, not how we handle the reset in the middle of a wait. Seems a reasonable addition though.)
Quoted 5 lines
I think that's a general pattern worth repeating for the rest of tests:
don't immediately inject the hang, but leave it a few milliseconds to allow us to block on the subsequent wait. I would even repeat the tests a few times with different timeouts; 0, 1us, 10ms (thinking of the different phases fori915_request_wait).
True, it's not the same.
Makes sense to test with different timeouts. Will do.
Quoted 11 lines
tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 208
Quoted 5 lines
tests/gem_eio.c +3
-0trigger_reset (fd); + +/* HACK for CI */ +igt_assert (igt_nsec_elapsed (&ts) <5e9 );
igt_seconds_elapsed()the approximation is worth the readability.In this case you might like to try
igt_set_timeout(), as I think each subtest and exithandlers are in place to make them robust against premature failures.
Well this was just to see that will happen on the shards here. As mentioned in the commit I get that yet unexplained GPU hang at subtest exit here. So the assert above is just to notice if the same happens on shards.
Regards,
Tvrtko
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Re: [igt-dev] [PATCH i-g-t 2/3] tests/gem_eio: Speed up test execution
Quoting Tvrtko Ursulin (2018-03-22 12:36:58)
Quoted 11 lines · Chris Wilson
Quoted 9 lines
Quoting Tvrtko Ursulin (2018-03-22 11:17:11)
tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 208
Quoted 4 lines
trigger_reset(fd);tests/gem_eio.c +3
-0+ +/* HACK for CI */ +igt_assert (igt_nsec_elapsed (&ts) <5e9 );
igt_seconds_elapsed()the approximation is worth the readability.
Quoted 8 lines
Quoted 3 lines
In this case you might like to try
igt_set_timeout(), as I think each subtest and exithandlers are in place to make them robust against premature failures.Well this was just to see that will happen on the shards here. As mentioned in the commit I get that yet unexplained GPU hang at subtest exit here. So the assert above is just to notice if the same happens on shards.
And I was thinking it was a reasonable enhancement :) Probably more so for igt/gem_wait itself to ask that if we reset the request we are waiting upon it completes in a timely manner. (We don't care about wedged handling there, just reset handling.)
-Chris
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 2/3] tests/gem_eio: Speed up test execution
Quoted 21 lines · Chris Wilson
Quoting Tvrtko Ursulin (2018-03-22 12:36:58)
Quoted 11 lines · Chris Wilson
Quoted 9 lines
Quoting Tvrtko Ursulin (2018-03-22 11:17:11)
tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 208
Quoted 4 lines
trigger_reset(fd);tests/gem_eio.c +3
-0+ +/* HACK for CI */ +igt_assert (igt_nsec_elapsed (&ts) <5e9 );
igt_seconds_elapsed()the approximation is worth the readability.Quoted 8 lines
Quoted 3 lines
In this case you might like to try
igt_set_timeout(), as I think each subtest and exithandlers are in place to make them robust against premature failures.Well this was just to see that will happen on the shards here. As mentioned in the commit I get that yet unexplained GPU hang at subtest exit here. So the assert above is just to notice if the same happens on shards.
Quoted 4 lines
And I was thinking it was a reasonable enhancement :) Probably more so for igt/gem_wait itself to ask that if we reset the request we are waiting upon it completes in a timely manner. (We don't care about wedged handling there, just reset handling.)
How about checking for reset when we do gem_test_engine(), which seems to not fail on reset, (crudely https://paste.debian.net/1016059/)?
Antonio
Quoted 6 lines
-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 2/3] tests/gem_eio: Speed up test execution
Quoting Antonio Argenziano (2018-03-22 17:32:46)
Quoted 24 lines · Chris Wilson
Quoted 21 lines
Quoting Tvrtko Ursulin (2018-03-22 12:36:58)
Quoted 19 lines · Chris Wilson
Quoted 7 lines
Quoting Tvrtko Ursulin (2018-03-22 11:17:11)
tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 208
Quoted 4 lines
trigger_reset(fd);tests/gem_eio.c +3
-0+ +/* HACK for CI */ +igt_assert (igt_nsec_elapsed (&ts) <5e9 );Quoted 5 lines
igt_seconds_elapsed()the approximation is worth the readability.In this case you might like to try
igt_set_timeout(), as I think each subtest and exithandlers are in place to make them robust against premature failures.Well this was just to see that will happen on the shards here. As mentioned in the commit I get that yet unexplained GPU hang at subtest exit here. So the assert above is just to notice if the same happens on shards.
Quoted 7 lines
Quoted 4 lines
And I was thinking it was a reasonable enhancement :) Probably more so for igt/gem_wait itself to ask that if we reset the request we are waiting upon it completes in a timely manner. (We don't care about wedged handling there, just reset handling.)
How about checking for reset when we do
gem_test_engine(), which seems to not fail on reset, (crudely https://paste.debian.net/1016059/)?
I was thinking that the timeout would be good around the test as a whole, because it is now meant to be uberfast.
-Chris
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Re: [Intel-gfx] [igt-dev] [PATCH i-g-t 2/3] tests/gem_eio: Speed up test execution
Quoted 30 lines · Chris Wilson
Quoting Antonio Argenziano (2018-03-22 17:32:46)
Quoted 29 lines · Chris Wilson
Quoted 25 lines
Quoting Tvrtko Ursulin (2018-03-22 12:36:58)
Quoted 11 lines · Chris Wilson
Quoted 9 lines
Quoting Tvrtko Ursulin (2018-03-22 11:17:11)
tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 208
Quoted 4 lines
trigger_reset(fd);tests/gem_eio.c +3
-0+ +/* HACK for CI */ +igt_assert (igt_nsec_elapsed (&ts) <5e9 );
igt_seconds_elapsed()the approximation is worth the readability.Quoted 8 lines
Quoted 3 lines
In this case you might like to try
igt_set_timeout(), as I think each subtest and exithandlers are in place to make them robust against premature failures.Well this was just to see that will happen on the shards here. As mentioned in the commit I get that yet unexplained GPU hang at subtest exit here. So the assert above is just to notice if the same happens on shards.
And I was thinking it was a reasonable enhancement :) Probably more so for igt/gem_wait itself to ask that if we reset the request we are waiting upon it completes in a timely manner. (We don't care about wedged handling there, just reset handling.)
Quoted 5 lines
Quoted 2 lines
How about checking for reset when we do
gem_test_engine(), which seems to not fail on reset, (crudely https://paste.debian.net/1016059/)?I was thinking that the timeout would be good around the test as a whole, because it is now meant to be uberfast.
Makes sense.
Thanks,
Antonio
Quoted 2 lines
-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 2/3] tests/gem_eio: Speed up test execution
In reply to Chris WilsonQuoted 30 lines · Chris Wilson
Quoting Antonio Argenziano (2018-03-22 17:32:46)
Quoted 29 lines · Chris Wilson
Quoted 25 lines
Quoting Tvrtko Ursulin (2018-03-22 12:36:58)
Quoted 11 lines · Chris Wilson
Quoted 9 lines
Quoting Tvrtko Ursulin (2018-03-22 11:17:11)
tests/gem_eio.c static int __gem_wait(int fd, uint32_t handle, int64_t timeout) · line 208
Quoted 4 lines
trigger_reset(fd);tests/gem_eio.c +3
-0+ +/* HACK for CI */ +igt_assert (igt_nsec_elapsed (&ts) <5e9 );
igt_seconds_elapsed()the approximation is worth the readability.Quoted 8 lines
Quoted 3 lines
In this case you might like to try
igt_set_timeout(), as I think each subtest and exithandlers are in place to make them robust against premature failures.Well this was just to see that will happen on the shards here. As mentioned in the commit I get that yet unexplained GPU hang at subtest exit here. So the assert above is just to notice if the same happens on shards.
And I was thinking it was a reasonable enhancement :) Probably more so for igt/gem_wait itself to ask that if we reset the request we are waiting upon it completes in a timely manner. (We don't care about wedged handling there, just reset handling.)
Quoted 5 lines
Quoted 2 lines
How about checking for reset when we do
gem_test_engine(), which seems to not fail on reset, (crudely https://paste.debian.net/1016059/)?I was thinking that the timeout would be good around the test as a whole, because it is now meant to be uberfast.
Whole subtests with igt_set_timeout, or alternatively I was thinking to just time the trigger_reset helper. Since other bits are covered by short timeout gem_wait now, I think tigger_reset is the only one which I need to additionally cover. If we stick with signals for delayed hangs, that also might be simpler than to find a different signal than SIGALARM for it (so it doesn't clash with igt_set_timeout).
Regards,
Tvrtko
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
PATCH 3/3 tests/perf_pmu: Improve accuracy by waiting on spinner to start
In reply to Tvrtko UrsulinFrom: Tvrtko Ursulin <[email protected]>
More than one test assumes that the spinner is running pretty much immediately after we have create or submitted it.
In actuality there is a variable delay, especially on execlists platforms, between submission and spin batch starting to run on the hardware.
To enable tests which care about this level of timing to account for this, we add a new spin batch constructor which provides an output field which can be polled to determine when the batch actually started running.
This is implemented via MI_STOREDW_IMM from the spin batch, writing into memory mapped page shared with userspace.
Using this facility from perf_pmu, where applicable, should improve very occasional test fails across the set and platforms.
v2:
Chris Wilson:
* Use caching mapping if available.
* Handle old gens better.
* Use gem_can_store_dword.
* Cache exec obj array in spin_batch_t for easier resubmit.
v3:
* Forgot I915_EXEC_NO_RELOC. (Chris Wilson)
v4:
* Mask out all non-engine flags in gem_can_store_dword.
* Added some debug logging.
v5:
* Fix relocs and batch munmap. (Chris)
* Added assert idle spinner batch looks as expected.
v6:
* Skip accuracy tests when !gem_can_store_dword.
v7:
* Fix batch recursion reloc address.
v8:
Chris Wilson:
* Pull up gem_can_store_dword check before we start submitting.
* Build spinner batch in a way we can skip store dword when not needed so we can run on SandyBridge.
v9:
* Fix wait on spinner.
* More tweaks to accuracy test.
v10:
* Dropped accuracy subtest changes due problems with RT thread and tasklet submission.
--- tests/perf_pmu.c | 151 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 48 deletions(-)
tests/perf_pmu.c +103 -48
@@ -170,6 +170,56 @@ static unsigned int e2ring(int gem_fd, const struct intel_execution_engine2 *e)#define FLAG_LONG (16)#define FLAG_HANG (32) +static igt_spin_t *__spin_poll (int fd,uint32_t ctx,unsigned long flags) +{ +if (gem_can_store_dword (fd, flags)) +return __igt_spin_batch_new_poll (fd, ctx, flags); +else +return __igt_spin_batch_new (fd, ctx, flags,0 ); +} + +static unsigned long __spin_wait (int fd,igt_spin_t *spin) +{ +struct timespec start = { }; + +igt_nsec_elapsed (&start); + +if (spin->running) { +unsigned long timeout =0 ; + +while (!*((volatile bool *)spin->running)) { +unsigned long t =igt_nsec_elapsed (&start); + +if ((t - timeout) >250e6 ) { + timeout = t; +igt_warn ("Spinner not running after %.2fms\n" , + (double )t /1e6 ); + } + } + }else { +igt_debug ("__spin_wait - usleep mode\n" ); +usleep (500e3 );/* Better than nothing! */ + } + +return igt_nsec_elapsed (&start); +} + +static igt_spin_t *__spin_sync (int fd,uint32_t ctx,unsigned long flags) +{ +igt_spin_t *spin =__spin_poll (fd, ctx, flags); + +__spin_wait (fd, spin); + +return spin; +} + +static igt_spin_t *spin_sync (int fd,uint32_t ctx,unsigned long flags) +{ +igt_require_gem (fd); + +return __spin_sync (fd, ctx, flags); +} +static void end_spin (int fd,igt_spin_t *spin,unsigned int flags) {if (!spin)
@@ -180,8 +230,25 @@ static void end_spin(int fd, igt_spin_t *spin, unsigned int flags)if (flags &FLAG_SYNC )gem_sync (fd, spin->handle); -if (flags &TEST_TRAILING_IDLE ) -usleep (batch_duration_ns /5000 ); +if (flags &TEST_TRAILING_IDLE ) { +unsigned long t, timeout =0 ; +struct timespec start = { }; + +igt_nsec_elapsed (&start); + +do { + t =igt_nsec_elapsed (&start); + +if (gem_bo_busy (fd, spin->handle) && + (t - timeout) >10e6 ) { + timeout = t; +igt_warn ("Spinner not idle after %.2fms\n" , + (double )t /1e6 ); + } + +usleep (1e3 ); + }while (t < batch_duration_ns /5 ); + } } static void
@@ -195,7 +262,7 @@ single(int gem_fd, const struct intel_execution_engine2 *e, unsigned int flags) fd =open_pmu (I915_PMU_ENGINE_BUSY (e->class, e->instance));if (flags &TEST_BUSY ) - spin =igt_spin_batch_new (gem_fd,0 ,e2ring (gem_fd, e),0 ); + spin =spin_sync (gem_fd,0 ,e2ring (gem_fd, e));else spin =NULL ;
@@ -251,13 +318,7 @@ busy_start(int gem_fd, const struct intel_execution_engine2 *e)*/ sleep (2 ); - spin =__igt_spin_batch_new (gem_fd,0 ,e2ring (gem_fd, e),0 ); - -/* -* Sleep for a bit after making the engine busy to make sure the PMU -* gets enabled when the batch is already running. -*/ -usleep (500e3 ); + spin =__spin_sync (gem_fd,0 ,e2ring (gem_fd, e)); fd =open_pmu (I915_PMU_ENGINE_BUSY (e->class, e->instance));
@@ -300,7 +361,7 @@ busy_double_start(int gem_fd, const struct intel_execution_engine2 *e)* re-submission in execlists mode. Make sure busyness is correctly * reported with the engine busy, and after the engine went idle. */ - spin[0 ] =__igt_spin_batch_new (gem_fd,0 ,e2ring (gem_fd, e),0 ); + spin[0 ] =__spin_sync (gem_fd,0 ,e2ring (gem_fd, e));usleep (500e3 ); spin[1 ] =__igt_spin_batch_new (gem_fd, ctx,e2ring (gem_fd, e),0 );
@@ -386,7 +447,7 @@ busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,igt_assert_eq (i, num_engines); - spin =igt_spin_batch_new (gem_fd,0 ,e2ring (gem_fd, e),0 ); + spin =spin_sync (gem_fd,0 ,e2ring (gem_fd, e));pmu_read_multi (fd[0 ], num_engines, tval[0 ]); slept =measured_usleep (batch_duration_ns /1000 );if (flags &TEST_TRAILING_IDLE )
@@ -412,15 +473,15 @@ busy_check_all(int gem_fd, const struct intel_execution_engine2 *e, }static void -__submit_spin_batch (int gem_fd, -struct drm_i915_gem_exec_object2 *obj, -const struct intel_execution_engine2 *e) +__submit_spin_batch (int gem_fd,igt_spin_t *spin, +const struct intel_execution_engine2 *e, +int offset) { -struct drm_i915_gem_execbuffer2 eb = { - .buffer_count =1 , - .buffers_ptr =to_user_pointer (obj), - .flags =e2ring (gem_fd, e), - }; +struct drm_i915_gem_execbuffer2 eb = spin->execbuf; + + eb.flags &= ~(0x3f |I915_EXEC_BSD_MASK ); + eb.flags |=e2ring (gem_fd, e) |I915_EXEC_NO_RELOC ; + eb.batch_start_offset += offset;gem_execbuf (gem_fd, &eb); }
@@ -429,7 +490,6 @@ static void most_busy_check_all(int gem_fd, const struct intel_execution_engine2 *e, const unsigned int num_engines, unsigned int flags) { - struct drm_i915_gem_exec_object2 obj = {}; const struct intel_execution_engine2 *e_;uint64_t tval[2 ][num_engines];uint64_t val[num_engines];
@@ -443,15 +503,12 @@ most_busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,if (!gem_has_engine (gem_fd, e_->class, e_->instance))continue ; -if (e == e_) { +if (e == e_) idle_idx = i; - }else if (spin) { -__submit_spin_batch (gem_fd, &obj, e_); - }else { - spin =igt_spin_batch_new (gem_fd,0 , -e2ring (gem_fd, e_),0 ); - obj.handle = spin->handle; - } +else if (spin) +__submit_spin_batch (gem_fd, spin, e_,64 ); +else + spin =__spin_poll (gem_fd,0 ,e2ring (gem_fd, e_)); val[i++] =I915_PMU_ENGINE_BUSY (e_->class, e_->instance); }
@@ -461,6 +518,9 @@ most_busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,for (i =0 ; i < num_engines; i++) fd[i] =open_group (val[i], fd[0 ]); +/* Small delay to allow engines to start. */ +usleep (__spin_wait (gem_fd, spin) * num_engines /1e3 ); +pmu_read_multi (fd[0 ], num_engines, tval[0 ]); slept =measured_usleep (batch_duration_ns /1000 );if (flags &TEST_TRAILING_IDLE )
@@ -489,7 +549,6 @@ static void all_busy_check_all(int gem_fd, const unsigned int num_engines, unsigned int flags) { - struct drm_i915_gem_exec_object2 obj = {}; const struct intel_execution_engine2 *e;uint64_t tval[2 ][num_engines];uint64_t val[num_engines];
@@ -503,13 +562,10 @@ all_busy_check_all(int gem_fd, const unsigned int num_engines,if (!gem_has_engine (gem_fd, e->class, e->instance))continue ; -if (spin) { -__submit_spin_batch (gem_fd, &obj, e); - }else { - spin =igt_spin_batch_new (gem_fd,0 , -e2ring (gem_fd, e),0 ); - obj.handle = spin->handle; - } +if (spin) +__submit_spin_batch (gem_fd, spin, e,64 ); +else + spin =__spin_poll (gem_fd,0 ,e2ring (gem_fd, e)); val[i++] =I915_PMU_ENGINE_BUSY (e->class, e->instance); }
@@ -519,6 +575,9 @@ all_busy_check_all(int gem_fd, const unsigned int num_engines,for (i =0 ; i < num_engines; i++) fd[i] =open_group (val[i], fd[0 ]); +/* Small delay to allow engines to start. */ +usleep (__spin_wait (gem_fd, spin) * num_engines /1e3 ); +pmu_read_multi (fd[0 ], num_engines, tval[0 ]); slept =measured_usleep (batch_duration_ns /1000 );if (flags &TEST_TRAILING_IDLE )
@@ -550,7 +609,7 @@ no_sema(int gem_fd, const struct intel_execution_engine2 *e, unsigned int flags)open_group (I915_PMU_ENGINE_WAIT (e->class, e->instance), fd);if (flags &TEST_BUSY ) - spin =igt_spin_batch_new (gem_fd,0 ,e2ring (gem_fd, e),0 ); + spin =spin_sync (gem_fd,0 ,e2ring (gem_fd, e));else spin =NULL ;
@@ -884,7 +943,7 @@ multi_client(int gem_fd, const struct intel_execution_engine2 *e)*/ fd[1 ] =open_pmu (config); - spin =igt_spin_batch_new (gem_fd,0 ,e2ring (gem_fd, e),0 ); + spin =spin_sync (gem_fd,0 ,e2ring (gem_fd, e)); val[0 ] = val[1 ] =__pmu_read_single (fd[0 ], &ts[0 ]); slept[1 ] =measured_usleep (batch_duration_ns /1000 );
@@ -1248,7 +1307,7 @@ test_frequency(int gem_fd)igt_require (igt_sysfs_get_u32 (sysfs,"gt_boost_freq_mhz" ) == min_freq);gem_quiescent_gpu (gem_fd);/* Idle to be sure the change takes effect */ - spin =igt_spin_batch_new (gem_fd,0 ,I915_EXEC_RENDER ,0 ); + spin =spin_sync (gem_fd,0 ,I915_EXEC_RENDER ); slept =pmu_read_multi (fd,2 , start);measured_usleep (batch_duration_ns /1000 );
@@ -1274,7 +1333,7 @@ test_frequency(int gem_fd)igt_require (igt_sysfs_get_u32 (sysfs,"gt_min_freq_mhz" ) == max_freq);gem_quiescent_gpu (gem_fd); - spin =igt_spin_batch_new (gem_fd,0 ,I915_EXEC_RENDER ,0 ); + spin =spin_sync (gem_fd,0 ,I915_EXEC_RENDER ); slept =pmu_read_multi (fd,2 , start);measured_usleep (batch_duration_ns /1000 );
@@ -1517,7 +1576,6 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e,const unsigned long timeout[] = { pwm_calibration_us *1000 , test_us *1000 }; -struct drm_i915_gem_exec_object2 obj = {};uint64_t total_busy_ns =0 , total_idle_ns =0 ;igt_spin_t *spin;int ret;
@@ -1531,11 +1589,8 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e,/* Allocate our spin batch and idle it. */ spin =igt_spin_batch_new (gem_fd,0 ,e2ring (gem_fd, e),0 ); - obj.handle = spin->handle; -__submit_spin_batch (gem_fd, &obj, e);/* record its location */ igt_spin_batch_end (spin); -gem_sync (gem_fd, obj.handle); - obj.flags |=EXEC_OBJECT_PINNED ; +gem_sync (gem_fd, spin->handle);/* 1st pass is calibration, second pass is the test. */ for (int pass =0 ; pass <ARRAY_SIZE (timeout); pass++) {
@@ -1549,7 +1604,7 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e,/* Restart the spinbatch. */ __rearm_spin_batch (spin); -__submit_spin_batch (gem_fd, &obj, e); +__submit_spin_batch (gem_fd, spin, e,0 );/* * Note that the submission may be delayed to a
@@ -1559,7 +1614,7 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e, t_busy =measured_usleep (busy_us);igt_spin_batch_end (spin); -gem_sync (gem_fd, obj.handle); +gem_sync (gem_fd, spin->handle); total_busy_ns += t_busy;
Signature · 6 lines
2.14.1 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoting Tvrtko Ursulin (2018-03-22 11:17:10)
Quoted 10 lines
From: Tvrtko Ursulin <[email protected]>
Pollable spin batch exports a
spin->runningpointer which can be checked by dereferencing it to see if the spinner is actually executing on the GPU.This is useful for tests which want to make sure they do not proceed with their next step whilst the spinner is potentially only being processed by the driver and not actually executing.
Quoted 5 lines
Pollable spinner can be created with
igt_spin_batch_new_pollor__igt_spin_batch_new_poll, after which a loop similar to:while (!*(volatile bool *)spin->running) ;
Let's actually make READ_ONCE() a common thing and make this a convenient igt_spin_busywait_until_running() (igt_spin_spin)?
Quoted 3 lines
Can be used to wait until the spinner start execution.
Signed-off-by Tvrtko Ursulin <[email protected]>
-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Patchwork
CI[igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,1/3] lib/dummyload: Add pollable spin batch (rev2)
In reply to Tvrtko Ursulin== Series Details ==
== Series Details ==
Series: series starting with [i-g-t,1/3] lib/dummyload: Add pollable spin batch (rev2)
URL : https://patchwork.freedesktop.org/series/40453/
State : success
== Summary ==
IGT patchset tested on top of latest successful build c30e331188c97c9cb8e125abbfe56e1aea3241f7 lib/kms: Use named initializers for prop name arrays
with latest DRM-Tip kernel build CI_DRM_3966dff9ece60048 drm-tip: 2018y-03m-21d-20h-44m-14s UTC integration manifest
No testlist changes.
---- Known issues:
Test debugfs_test:
Subgroup read_all_entries:
incomplete -> PASS (fi-snb-2520m) fdo#103713
Test kms_flip:
Subgroup basic-flip-vs-wf_vblank:
fail -> PASS (fi-skl-6770hq) fdo#100368
Test kms_pipe_crc_basic:
Subgroup suspend-read-crc-pipe-c:
pass -> INCOMPLETE (fi-hsw-4770) fdo#104944fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713
fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
fdo#104944 https://bugs.freedesktop.org/show_bug.cgi?id=104944
fi-bdw-5557u total:285 pass:264 dwarn:0 dfail:0 fail:0 skip:21 time:430s fi-bdw-gvtdvm total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:443s fi-blb-e6850 total:285 pass:220 dwarn:1 dfail:0 fail:0 skip:64 time:385s fi-bsw-n3050 total:285 pass:239 dwarn:0 dfail:0 fail:0 skip:46 time:547s fi-bwr-2160 total:285 pass:180 dwarn:0 dfail:0 fail:0 skip:105 time:298s fi-bxt-dsi total:285 pass:255 dwarn:0 dfail:0 fail:0 skip:30 time:516s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:516s fi-byt-j1900 total:285 pass:250 dwarn:0 dfail:0 fail:0 skip:35 time:517s fi-byt-n2820 total:285 pass:246 dwarn:0 dfail:0 fail:0 skip:39 time:502s fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:410s fi-cnl-drrs total:285 pass:254 dwarn:3 dfail:0 fail:0 skip:28 time:529s fi-cnl-y3 total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:588s fi-elk-e7500 total:285 pass:225 dwarn:1 dfail:0 fail:0 skip:59 time:426s fi-gdg-551 total:285 pass:176 dwarn:0 dfail:0 fail:1 skip:108 time:319s fi-glk-1 total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:538s fi-hsw-4770 total:243 pass:219 dwarn:0 dfail:0 fail:0 skip:23 fi-ilk-650 total:285 pass:225 dwarn:0 dfail:0 fail:0 skip:60 time:424s fi-ivb-3520m total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:464s fi-ivb-3770 total:285 pass:252 dwarn:0 dfail:0 fail:0 skip:33 time:432s fi-kbl-7500u total:285 pass:260 dwarn:1 dfail:0 fail:0 skip:24 time:474s fi-kbl-7567u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:467s fi-kbl-r total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:516s fi-pnv-d510 total:285 pass:219 dwarn:1 dfail:0 fail:0 skip:65 time:651s fi-skl-6260u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:436s fi-skl-6600u total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:531s fi-skl-6700k2 total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:504s fi-skl-6770hq total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:497s fi-skl-guc total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:427s fi-skl-gvtdvm total:285 pass:262 dwarn:0 dfail:0 fail:0 skip:23 time:447s fi-snb-2520m total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:578s fi-snb-2600 total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:405s
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_1179/issues.html
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Patchwork
CI[igt-dev] ✗ Fi.CI.IGT: failure for series starting with [i-g-t,1/3] lib/dummyload: Add pollable spin batch (rev2)
In reply to Tvrtko Ursulin== Series Details ==
== Series Details ==
Series: series starting with [i-g-t,1/3] lib/dummyload: Add pollable spin batch (rev2)
URL : https://patchwork.freedesktop.org/series/40453/
State : failure
== Summary ==
---- Possible new issues:
Test gem_eio:
Subgroup wait:
pass -> FAIL (shard-apl)
Test kms_cursor_legacy:
Subgroup flip-vs-cursor-legacy:
pass -> FAIL (shard-hsw)---- Known issues:
Test kms_flip:
Subgroup flip-vs-wf_vblank-interruptible:
fail -> PASS (shard-hsw) fdo#100368
Test kms_frontbuffer_tracking:
Subgroup fbc-1p-primscrn-pri-shrfb-draw-render:
pass -> FAIL (shard-snb) fdo#103167
Test kms_plane_multiple:
Subgroup atomic-pipe-a-tiling-x:
fail -> PASS (shard-snb) fdo#103166
Test kms_setmode:
Subgroup basic:
pass -> FAIL (shard-apl) fdo#99912
Test kms_sysfs_edid_timing:
pass -> WARN (shard-apl) fdo#100047fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
fdo#103166 https://bugs.freedesktop.org/show_bug.cgi?id=103166
fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912
fdo#100047 https://bugs.freedesktop.org/show_bug.cgi?id=100047
shard-apl total:3478 pass:1813 dwarn:1 dfail:0 fail:8 skip:1655 time:12969s shard-hsw total:3478 pass:1767 dwarn:1 dfail:0 fail:2 skip:1707 time:11706s shard-snb total:3478 pass:1357 dwarn:1 dfail:0 fail:3 skip:2117 time:7140s
Blacklisted hosts:
shard-kbl total:3478 pass:1940 dwarn:1 dfail:0 fail:9 skip:1528 time:9821s
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_1179/shards.html
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev