* Re: [i-g-t PATCH v7 2/5] lib: add igt_dummyload
2016-11-16 21:18 ` [i-g-t PATCH v7 2/5] lib: add igt_dummyload Abdiel Janulgue
@ 2016-11-16 13:56 ` Chris Wilson
2016-11-16 14:07 ` Abdiel Janulgue
0 siblings, 1 reply; 14+ messages in thread
From: Chris Wilson @ 2016-11-16 13:56 UTC (permalink / raw)
To: Abdiel Janulgue; +Cc: Daniel Vetter, intel-gfx
On Wed, Nov 16, 2016 at 11:18:01PM +0200, Abdiel Janulgue wrote:
> A lot of igt testcases need some GPU workload to make sure a race
> window is big enough. Unfortunately having a fixed amount of
> workload leads to spurious test failures or overtly long runtimes
> on some fast/slow platforms. This library contains functionality
> to submit GPU workloads that should consume exactly a specific
> amount of time.
>
> v2 : Add recursive batch feature from Chris
> v3 : Drop auto-tuned stuff. Add bo dependecy to recursive batch
> by adding a dummy reloc to the bo as suggested by Ville.
> v4: Fix dependency reloc as write instead of read (Ville).
> Fix wrong handling of batchbuffer start on ILK causing
> test failure
> v5: Convert kms_busy to use this api
> v6: Add this library to docs
> v7: Document global use of batch, reuse defines
> Minor code cleanups.
> Rename igt_spin_batch and igt_post_spin_batch to
> igt_spin_batch_new and igt_spin_batch_free
> respectively (Tomeu Vizoso).
> Fix error in dependency relocation handling in HSW causing
> tests to fail.
>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: tomeu@tomeuvizoso.net
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> ---
> .../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 +
> lib/Makefile.sources | 2 +
> lib/igt.h | 1 +
> lib/igt_dummyload.c | 281 +++++++++++++++++++++
> lib/igt_dummyload.h | 43 ++++
> 5 files changed, 328 insertions(+)
> create mode 100644 lib/igt_dummyload.c
> create mode 100644 lib/igt_dummyload.h
>
> diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> index c862f2a..55902ab 100644
> --- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> +++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> @@ -32,6 +32,7 @@
> <xi:include href="xml/intel_io.xml"/>
> <xi:include href="xml/igt_vc4.xml"/>
> <xi:include href="xml/igt_vgem.xml"/>
> + <xi:include href="xml/igt_dummyload.xml"/>
> </chapter>
> <xi:include href="xml/igt_test_programs.xml"/>
>
> diff --git a/lib/Makefile.sources b/lib/Makefile.sources
> index e8e277b..7fc5ec2 100644
> --- a/lib/Makefile.sources
> +++ b/lib/Makefile.sources
> @@ -75,6 +75,8 @@ lib_source_list = \
> igt_draw.h \
> igt_pm.c \
> igt_pm.h \
> + igt_dummyload.c \
> + igt_dummyload.h \
> uwildmat/uwildmat.h \
> uwildmat/uwildmat.c \
> $(NULL)
> diff --git a/lib/igt.h b/lib/igt.h
> index d751f24..a0028d5 100644
> --- a/lib/igt.h
> +++ b/lib/igt.h
> @@ -32,6 +32,7 @@
> #include "igt_core.h"
> #include "igt_debugfs.h"
> #include "igt_draw.h"
> +#include "igt_dummyload.h"
> #include "igt_fb.h"
> #include "igt_gt.h"
> #include "igt_kms.h"
> diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
> new file mode 100644
> index 0000000..d266195
> --- /dev/null
> +++ b/lib/igt_dummyload.c
> @@ -0,0 +1,281 @@
> +/*
> + * Copyright © 2016 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 "igt.h"
> +#include "igt_dummyload.h"
> +#include <time.h>
> +#include <signal.h>
> +#include <sys/syscall.h>
> +
> +/**
> + * SECTION:igt_dummyload
> + * @short_description: Library for submitting GPU workloads
> + * @title: Dummyload
> + * @include: igt.h
> + *
> + * A lot of igt testcases need some GPU workload to make sure a race window is
> + * big enough. Unfortunately having a fixed amount of workload leads to
> + * spurious test failures or overly long runtimes on some fast/slow platforms.
> + * This library contains functionality to submit GPU workloads that should
> + * consume exactly a specific amount of time.
> + */
> +
> +#define LOCAL_I915_EXEC_BSD_SHIFT (13)
> +#define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
> +
> +#define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
> +
> +static const int bo_size = 4096;
> +
> +static void
> +fill_object(struct drm_i915_gem_exec_object2 *obj, uint32_t gem_handle,
> + struct drm_i915_gem_relocation_entry *relocs, uint32_t count)
> +{
> + memset(obj, 0, sizeof(*obj));
> + obj->handle = gem_handle;
> + obj->relocation_count = count;
> + obj->relocs_ptr = (uintptr_t)relocs;
> +}
> +
> +static void
> +fill_reloc(struct drm_i915_gem_relocation_entry *reloc,
> + uint32_t gem_handle, uint32_t offset,
> + uint32_t read_domains, uint32_t write_domains)
> +{
> + reloc->target_handle = gem_handle;
> + reloc->delta = 0;
> + reloc->offset = offset * sizeof(uint32_t);
> + reloc->presumed_offset = 0;
> + reloc->read_domains = read_domains;
> + reloc->write_domain = write_domains;
> +}
> +
> +/*
> + * Needs to be global. Signal handlers don't accept arguments
> + */
> +static uint32_t *batch;
> +
> +static uint32_t emit_recursive_batch(int fd, int engine, unsigned dep_handle)
> +{
> + const 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;
> + unsigned engines[16];
> + unsigned nengine, handle;
> + int i = 0, reloc_count = 0, buf_count = 0;
> +
> + buf_count = 0;
> + nengine = 0;
> + if (engine < 0) {
> + for_each_engine(fd, engine)
> + if (engine)
> + engines[nengine++] = engine;
> + } else {
> + gem_require_ring(fd, engine);
> + engines[nengine++] = engine;
> + }
> + igt_require(nengine);
> +
> + memset(&execbuf, 0, sizeof(execbuf));
> + memset(obj, 0, sizeof(obj));
> + memset(relocs, 0, sizeof(relocs));
> +
> + execbuf.buffers_ptr = (uintptr_t) obj;
> + handle = gem_create(fd, bo_size);
> + batch = gem_mmap__gtt(fd, handle, bo_size, PROT_WRITE);
> + igt_assert(batch);
> + gem_set_domain(fd, handle,
> + I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
> +
> + if (gen >= 8) {
> + batch[i++] = MI_BATCH_BUFFER_START | 1 << 8 | 1;
> + /* recurse */
> + fill_reloc(&relocs[reloc_count], handle, i,
> + I915_GEM_DOMAIN_COMMAND, 0);
> + batch[i++] = 0;
> + batch[i++] = 0;
> + } else if (gen >= 6) {
> + batch[i++] = MI_BATCH_BUFFER_START | 1 << 8;
> + /* recurse */
> + fill_reloc(&relocs[reloc_count], handle, i,
> + I915_GEM_DOMAIN_COMMAND, 0);
> + batch[i++] = 0;
> + } else {
> + batch[i++] = MI_BATCH_BUFFER_START | 2 << 6 |
> + ((gen < 4) ? 1 : 0);
> + /* recurse */
> + fill_reloc(&relocs[reloc_count], handle, i,
> + I915_GEM_DOMAIN_COMMAND, 0);
> + batch[i++] = 0;
> + if (gen < 4)
> + relocs[reloc_count].delta = 1;
> + }
> + reloc_count++;
> +
> + if (dep_handle > 0) {
> + igt_assert(nengine == 1);
> + /* dummy write to dependency */
> + fill_object(&obj[buf_count], dep_handle, NULL, 0);
> + buf_count++;
> +
> + fill_reloc(&relocs[reloc_count], dep_handle, 256,
> + I915_GEM_DOMAIN_RENDER,
> + I915_GEM_DOMAIN_RENDER);
> + reloc_count++;
> + }
This is not the dummy load you were looking for. This is an infinite
walk with no termination condition.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [i-g-t PATCH v7 2/5] lib: add igt_dummyload
2016-11-16 13:56 ` Chris Wilson
@ 2016-11-16 14:07 ` Abdiel Janulgue
2016-11-16 14:17 ` Chris Wilson
0 siblings, 1 reply; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-16 14:07 UTC (permalink / raw)
To: Chris Wilson, intel-gfx, Daniel Vetter, Ville Syrjälä,
tomeu
On 16.11.2016 15:56, Chris Wilson wrote:
> On Wed, Nov 16, 2016 at 11:18:01PM +0200, Abdiel Janulgue wrote:
>> A lot of igt testcases need some GPU workload to make sure a race
>> window is big enough. Unfortunately having a fixed amount of
>> workload leads to spurious test failures or overtly long runtimes
>> on some fast/slow platforms. This library contains functionality
>> to submit GPU workloads that should consume exactly a specific
>> amount of time.
>>
>> v2 : Add recursive batch feature from Chris
>> v3 : Drop auto-tuned stuff. Add bo dependecy to recursive batch
>> by adding a dummy reloc to the bo as suggested by Ville.
>> v4: Fix dependency reloc as write instead of read (Ville).
>> Fix wrong handling of batchbuffer start on ILK causing
>> test failure
>> v5: Convert kms_busy to use this api
>> v6: Add this library to docs
>> v7: Document global use of batch, reuse defines
>> Minor code cleanups.
>> Rename igt_spin_batch and igt_post_spin_batch to
>> igt_spin_batch_new and igt_spin_batch_free
>> respectively (Tomeu Vizoso).
>> Fix error in dependency relocation handling in HSW causing
>> tests to fail.
>>
>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> Cc: tomeu@tomeuvizoso.net
>> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
>> ---
>> .../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 +
>> lib/Makefile.sources | 2 +
>> lib/igt.h | 1 +
>> lib/igt_dummyload.c | 281 +++++++++++++++++++++
>> lib/igt_dummyload.h | 43 ++++
>> 5 files changed, 328 insertions(+)
>> create mode 100644 lib/igt_dummyload.c
>> create mode 100644 lib/igt_dummyload.h
>>
>> diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
>> index c862f2a..55902ab 100644
>> --- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
>> +++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
>> @@ -32,6 +32,7 @@
>> <xi:include href="xml/intel_io.xml"/>
>> <xi:include href="xml/igt_vc4.xml"/>
>> <xi:include href="xml/igt_vgem.xml"/>
>> + <xi:include href="xml/igt_dummyload.xml"/>
>> </chapter>
>> <xi:include href="xml/igt_test_programs.xml"/>
>>
>> diff --git a/lib/Makefile.sources b/lib/Makefile.sources
>> index e8e277b..7fc5ec2 100644
>> --- a/lib/Makefile.sources
>> +++ b/lib/Makefile.sources
>> @@ -75,6 +75,8 @@ lib_source_list = \
>> igt_draw.h \
>> igt_pm.c \
>> igt_pm.h \
>> + igt_dummyload.c \
>> + igt_dummyload.h \
>> uwildmat/uwildmat.h \
>> uwildmat/uwildmat.c \
>> $(NULL)
>> diff --git a/lib/igt.h b/lib/igt.h
>> index d751f24..a0028d5 100644
>> --- a/lib/igt.h
>> +++ b/lib/igt.h
>> @@ -32,6 +32,7 @@
>> #include "igt_core.h"
>> #include "igt_debugfs.h"
>> #include "igt_draw.h"
>> +#include "igt_dummyload.h"
>> #include "igt_fb.h"
>> #include "igt_gt.h"
>> #include "igt_kms.h"
>> diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
>> new file mode 100644
>> index 0000000..d266195
>> --- /dev/null
>> +++ b/lib/igt_dummyload.c
>> @@ -0,0 +1,281 @@
>> +/*
>> + * Copyright © 2016 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 "igt.h"
>> +#include "igt_dummyload.h"
>> +#include <time.h>
>> +#include <signal.h>
>> +#include <sys/syscall.h>
>> +
>> +/**
>> + * SECTION:igt_dummyload
>> + * @short_description: Library for submitting GPU workloads
>> + * @title: Dummyload
>> + * @include: igt.h
>> + *
>> + * A lot of igt testcases need some GPU workload to make sure a race window is
>> + * big enough. Unfortunately having a fixed amount of workload leads to
>> + * spurious test failures or overly long runtimes on some fast/slow platforms.
>> + * This library contains functionality to submit GPU workloads that should
>> + * consume exactly a specific amount of time.
>> + */
>> +
>> +#define LOCAL_I915_EXEC_BSD_SHIFT (13)
>> +#define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
>> +
>> +#define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
>> +
>> +static const int bo_size = 4096;
>> +
>> +static void
>> +fill_object(struct drm_i915_gem_exec_object2 *obj, uint32_t gem_handle,
>> + struct drm_i915_gem_relocation_entry *relocs, uint32_t count)
>> +{
>> + memset(obj, 0, sizeof(*obj));
>> + obj->handle = gem_handle;
>> + obj->relocation_count = count;
>> + obj->relocs_ptr = (uintptr_t)relocs;
>> +}
>> +
>> +static void
>> +fill_reloc(struct drm_i915_gem_relocation_entry *reloc,
>> + uint32_t gem_handle, uint32_t offset,
>> + uint32_t read_domains, uint32_t write_domains)
>> +{
>> + reloc->target_handle = gem_handle;
>> + reloc->delta = 0;
>> + reloc->offset = offset * sizeof(uint32_t);
>> + reloc->presumed_offset = 0;
>> + reloc->read_domains = read_domains;
>> + reloc->write_domain = write_domains;
>> +}
>> +
>> +/*
>> + * Needs to be global. Signal handlers don't accept arguments
>> + */
>> +static uint32_t *batch;
>> +
>> +static uint32_t emit_recursive_batch(int fd, int engine, unsigned dep_handle)
>> +{
>> + const 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;
>> + unsigned engines[16];
>> + unsigned nengine, handle;
>> + int i = 0, reloc_count = 0, buf_count = 0;
>> +
>> + buf_count = 0;
>> + nengine = 0;
>> + if (engine < 0) {
>> + for_each_engine(fd, engine)
>> + if (engine)
>> + engines[nengine++] = engine;
>> + } else {
>> + gem_require_ring(fd, engine);
>> + engines[nengine++] = engine;
>> + }
>> + igt_require(nengine);
>> +
>> + memset(&execbuf, 0, sizeof(execbuf));
>> + memset(obj, 0, sizeof(obj));
>> + memset(relocs, 0, sizeof(relocs));
>> +
>> + execbuf.buffers_ptr = (uintptr_t) obj;
>> + handle = gem_create(fd, bo_size);
>> + batch = gem_mmap__gtt(fd, handle, bo_size, PROT_WRITE);
>> + igt_assert(batch);
>> + gem_set_domain(fd, handle,
>> + I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
>> +
>> + if (gen >= 8) {
>> + batch[i++] = MI_BATCH_BUFFER_START | 1 << 8 | 1;
>> + /* recurse */
>> + fill_reloc(&relocs[reloc_count], handle, i,
>> + I915_GEM_DOMAIN_COMMAND, 0);
>> + batch[i++] = 0;
>> + batch[i++] = 0;
>> + } else if (gen >= 6) {
>> + batch[i++] = MI_BATCH_BUFFER_START | 1 << 8;
>> + /* recurse */
>> + fill_reloc(&relocs[reloc_count], handle, i,
>> + I915_GEM_DOMAIN_COMMAND, 0);
>> + batch[i++] = 0;
>> + } else {
>> + batch[i++] = MI_BATCH_BUFFER_START | 2 << 6 |
>> + ((gen < 4) ? 1 : 0);
>> + /* recurse */
>> + fill_reloc(&relocs[reloc_count], handle, i,
>> + I915_GEM_DOMAIN_COMMAND, 0);
>> + batch[i++] = 0;
>> + if (gen < 4)
>> + relocs[reloc_count].delta = 1;
>> + }
>> + reloc_count++;
>> +
>> + if (dep_handle > 0) {
>> + igt_assert(nengine == 1);
>> + /* dummy write to dependency */
>> + fill_object(&obj[buf_count], dep_handle, NULL, 0);
>> + buf_count++;
>> +
>> + fill_reloc(&relocs[reloc_count], dep_handle, 256,
>> + I915_GEM_DOMAIN_RENDER,
>> + I915_GEM_DOMAIN_RENDER);
>> + reloc_count++;
>> +
>
> This is not the dummy load you were looking for. This is an infinite
> walk with no termination condition.
This is based on kms_busy's previous make_fb_busy() recursive batch
setup. I'm wondering why that one works for making the bo busy? Or did I
miss something?
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [i-g-t PATCH v7 2/5] lib: add igt_dummyload
2016-11-16 14:07 ` Abdiel Janulgue
@ 2016-11-16 14:17 ` Chris Wilson
2016-11-17 17:45 ` [i-g-t PATCH v8 " Abdiel Janulgue
0 siblings, 1 reply; 14+ messages in thread
From: Chris Wilson @ 2016-11-16 14:17 UTC (permalink / raw)
To: Abdiel Janulgue; +Cc: Daniel Vetter, intel-gfx
On Wed, Nov 16, 2016 at 04:07:33PM +0200, Abdiel Janulgue wrote:
>
>
> On 16.11.2016 15:56, Chris Wilson wrote:
> > On Wed, Nov 16, 2016 at 11:18:01PM +0200, Abdiel Janulgue wrote:
> >> A lot of igt testcases need some GPU workload to make sure a race
> >> window is big enough. Unfortunately having a fixed amount of
> >> workload leads to spurious test failures or overtly long runtimes
> >> on some fast/slow platforms. This library contains functionality
> >> to submit GPU workloads that should consume exactly a specific
> >> amount of time.
> >>
> >> v2 : Add recursive batch feature from Chris
> >> v3 : Drop auto-tuned stuff. Add bo dependecy to recursive batch
> >> by adding a dummy reloc to the bo as suggested by Ville.
> >> v4: Fix dependency reloc as write instead of read (Ville).
> >> Fix wrong handling of batchbuffer start on ILK causing
> >> test failure
> >> v5: Convert kms_busy to use this api
> >> v6: Add this library to docs
> >> v7: Document global use of batch, reuse defines
> >> Minor code cleanups.
> >> Rename igt_spin_batch and igt_post_spin_batch to
> >> igt_spin_batch_new and igt_spin_batch_free
> >> respectively (Tomeu Vizoso).
> >> Fix error in dependency relocation handling in HSW causing
> >> tests to fail.
> >>
> >> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> >> Cc: tomeu@tomeuvizoso.net
> >> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> >> ---
> >> .../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 +
> >> lib/Makefile.sources | 2 +
> >> lib/igt.h | 1 +
> >> lib/igt_dummyload.c | 281 +++++++++++++++++++++
> >> lib/igt_dummyload.h | 43 ++++
> >> 5 files changed, 328 insertions(+)
> >> create mode 100644 lib/igt_dummyload.c
> >> create mode 100644 lib/igt_dummyload.h
> >>
> >> diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> >> index c862f2a..55902ab 100644
> >> --- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> >> +++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
> >> @@ -32,6 +32,7 @@
> >> <xi:include href="xml/intel_io.xml"/>
> >> <xi:include href="xml/igt_vc4.xml"/>
> >> <xi:include href="xml/igt_vgem.xml"/>
> >> + <xi:include href="xml/igt_dummyload.xml"/>
> >> </chapter>
> >> <xi:include href="xml/igt_test_programs.xml"/>
> >>
> >> diff --git a/lib/Makefile.sources b/lib/Makefile.sources
> >> index e8e277b..7fc5ec2 100644
> >> --- a/lib/Makefile.sources
> >> +++ b/lib/Makefile.sources
> >> @@ -75,6 +75,8 @@ lib_source_list = \
> >> igt_draw.h \
> >> igt_pm.c \
> >> igt_pm.h \
> >> + igt_dummyload.c \
> >> + igt_dummyload.h \
> >> uwildmat/uwildmat.h \
> >> uwildmat/uwildmat.c \
> >> $(NULL)
> >> diff --git a/lib/igt.h b/lib/igt.h
> >> index d751f24..a0028d5 100644
> >> --- a/lib/igt.h
> >> +++ b/lib/igt.h
> >> @@ -32,6 +32,7 @@
> >> #include "igt_core.h"
> >> #include "igt_debugfs.h"
> >> #include "igt_draw.h"
> >> +#include "igt_dummyload.h"
> >> #include "igt_fb.h"
> >> #include "igt_gt.h"
> >> #include "igt_kms.h"
> >> diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
> >> new file mode 100644
> >> index 0000000..d266195
> >> --- /dev/null
> >> +++ b/lib/igt_dummyload.c
> >> @@ -0,0 +1,281 @@
> >> +/*
> >> + * Copyright © 2016 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 "igt.h"
> >> +#include "igt_dummyload.h"
> >> +#include <time.h>
> >> +#include <signal.h>
> >> +#include <sys/syscall.h>
> >> +
> >> +/**
> >> + * SECTION:igt_dummyload
> >> + * @short_description: Library for submitting GPU workloads
> >> + * @title: Dummyload
> >> + * @include: igt.h
> >> + *
> >> + * A lot of igt testcases need some GPU workload to make sure a race window is
> >> + * big enough. Unfortunately having a fixed amount of workload leads to
> >> + * spurious test failures or overly long runtimes on some fast/slow platforms.
> >> + * This library contains functionality to submit GPU workloads that should
> >> + * consume exactly a specific amount of time.
> >> + */
> >> +
> >> +#define LOCAL_I915_EXEC_BSD_SHIFT (13)
> >> +#define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
> >> +
> >> +#define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
> >> +
> >> +static const int bo_size = 4096;
> >> +
> >> +static void
> >> +fill_object(struct drm_i915_gem_exec_object2 *obj, uint32_t gem_handle,
> >> + struct drm_i915_gem_relocation_entry *relocs, uint32_t count)
> >> +{
> >> + memset(obj, 0, sizeof(*obj));
> >> + obj->handle = gem_handle;
> >> + obj->relocation_count = count;
> >> + obj->relocs_ptr = (uintptr_t)relocs;
> >> +}
> >> +
> >> +static void
> >> +fill_reloc(struct drm_i915_gem_relocation_entry *reloc,
> >> + uint32_t gem_handle, uint32_t offset,
> >> + uint32_t read_domains, uint32_t write_domains)
> >> +{
> >> + reloc->target_handle = gem_handle;
> >> + reloc->delta = 0;
> >> + reloc->offset = offset * sizeof(uint32_t);
> >> + reloc->presumed_offset = 0;
> >> + reloc->read_domains = read_domains;
> >> + reloc->write_domain = write_domains;
> >> +}
> >> +
> >> +/*
> >> + * Needs to be global. Signal handlers don't accept arguments
> >> + */
> >> +static uint32_t *batch;
> >> +
> >> +static uint32_t emit_recursive_batch(int fd, int engine, unsigned dep_handle)
> >> +{
> >> + const 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;
> >> + unsigned engines[16];
> >> + unsigned nengine, handle;
> >> + int i = 0, reloc_count = 0, buf_count = 0;
> >> +
> >> + buf_count = 0;
> >> + nengine = 0;
> >> + if (engine < 0) {
> >> + for_each_engine(fd, engine)
> >> + if (engine)
> >> + engines[nengine++] = engine;
> >> + } else {
> >> + gem_require_ring(fd, engine);
> >> + engines[nengine++] = engine;
> >> + }
> >> + igt_require(nengine);
> >> +
> >> + memset(&execbuf, 0, sizeof(execbuf));
> >> + memset(obj, 0, sizeof(obj));
> >> + memset(relocs, 0, sizeof(relocs));
> >> +
> >> + execbuf.buffers_ptr = (uintptr_t) obj;
> >> + handle = gem_create(fd, bo_size);
> >> + batch = gem_mmap__gtt(fd, handle, bo_size, PROT_WRITE);
> >> + igt_assert(batch);
> >> + gem_set_domain(fd, handle,
> >> + I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
> >> +
> >> + if (gen >= 8) {
> >> + batch[i++] = MI_BATCH_BUFFER_START | 1 << 8 | 1;
> >> + /* recurse */
> >> + fill_reloc(&relocs[reloc_count], handle, i,
> >> + I915_GEM_DOMAIN_COMMAND, 0);
> >> + batch[i++] = 0;
> >> + batch[i++] = 0;
> >> + } else if (gen >= 6) {
> >> + batch[i++] = MI_BATCH_BUFFER_START | 1 << 8;
> >> + /* recurse */
> >> + fill_reloc(&relocs[reloc_count], handle, i,
> >> + I915_GEM_DOMAIN_COMMAND, 0);
> >> + batch[i++] = 0;
> >> + } else {
> >> + batch[i++] = MI_BATCH_BUFFER_START | 2 << 6 |
> >> + ((gen < 4) ? 1 : 0);
> >> + /* recurse */
> >> + fill_reloc(&relocs[reloc_count], handle, i,
> >> + I915_GEM_DOMAIN_COMMAND, 0);
> >> + batch[i++] = 0;
> >> + if (gen < 4)
> >> + relocs[reloc_count].delta = 1;
> >> + }
> >> + reloc_count++;
> >> +
> >> + if (dep_handle > 0) {
> >> + igt_assert(nengine == 1);
> >> + /* dummy write to dependency */
> >> + fill_object(&obj[buf_count], dep_handle, NULL, 0);
> >> + buf_count++;
> >> +
> >> + fill_reloc(&relocs[reloc_count], dep_handle, 256,
> >> + I915_GEM_DOMAIN_RENDER,
> >> + I915_GEM_DOMAIN_RENDER);
> >> + reloc_count++;
> >> +
> >
> > This is not the dummy load you were looking for. This is an infinite
> > walk with no termination condition.
>
> This is based on kms_busy's previous make_fb_busy() recursive batch
> setup. I'm wondering why that one works for making the bo busy? Or did I
> miss something?
Scatch is object 0, the batch is object 1.
In the current execbuffer API, the batch is always the last object in
the list. Your code executed the empty scratch object, which would then
quite happily walk through 2^48-4096 bytes before hitting the MI_BB_END
in the batch. (The relocation inside the scratch should just write
itself into the nopid register.)
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* i-g-t dummyload/spin batch v7
@ 2016-11-16 21:17 Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 1/5] lib: Make signal helper definitions reusable Abdiel Janulgue
` (4 more replies)
0 siblings, 5 replies; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-16 21:17 UTC (permalink / raw)
To: intel-gfx
* Fix for Haswell in generating a dummy reloc
* code cleanups / api name clarifications
- Abdiel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* [i-g-t PATCH v7 1/5] lib: Make signal helper definitions reusable
2016-11-16 21:17 i-g-t dummyload/spin batch v7 Abdiel Janulgue
@ 2016-11-16 21:18 ` Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 2/5] lib: add igt_dummyload Abdiel Janulgue
` (3 subsequent siblings)
4 siblings, 0 replies; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-16 21:18 UTC (permalink / raw)
To: intel-gfx
More and more test-cases are using this.
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
lib/igt_aux.c | 11 -----------
lib/igt_aux.h | 10 ++++++++++
lib/igt_core.c | 3 ---
tests/drv_hangman.c | 1 -
4 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index 421f6d4..b5ae854 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -75,17 +75,6 @@
* fit into any other topic.
*/
-
-/* signal interrupt helpers */
-
-#define MSEC_PER_SEC (1000)
-#define USEC_PER_SEC (1000*MSEC_PER_SEC)
-#define NSEC_PER_SEC (1000*USEC_PER_SEC)
-
-/* signal interrupt helpers */
-#define gettid() syscall(__NR_gettid)
-#define sigev_notify_thread_id _sigev_un._tid
-
static struct __igt_sigiter_global {
pid_t tid;
timer_t timer;
diff --git a/lib/igt_aux.h b/lib/igt_aux.h
index d30196b..d4da499 100644
--- a/lib/igt_aux.h
+++ b/lib/igt_aux.h
@@ -35,6 +35,16 @@
extern drm_intel_bo **trash_bos;
extern int num_trash_bos;
+/* signal interrupt helpers */
+
+#define MSEC_PER_SEC (1000)
+#define USEC_PER_SEC (1000*MSEC_PER_SEC)
+#define NSEC_PER_SEC (1000*USEC_PER_SEC)
+
+/* signal interrupt helpers */
+#define gettid() syscall(__NR_gettid)
+#define sigev_notify_thread_id _sigev_un._tid
+
/* auxialiary igt helpers from igt_aux.c */
/* generally useful helpers */
void igt_fork_signal_helper(void);
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 9cd5f98..f64c809 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -398,9 +398,6 @@ error:
return -errno;
}
-#define MSEC_PER_SEC (1000)
-#define USEC_PER_SEC (1000*MSEC_PER_SEC)
-#define NSEC_PER_SEC (1000*USEC_PER_SEC)
uint64_t igt_nsec_elapsed(struct timespec *start)
{
struct timespec now;
diff --git a/tests/drv_hangman.c b/tests/drv_hangman.c
index f80d65d..db0a077 100644
--- a/tests/drv_hangman.c
+++ b/tests/drv_hangman.c
@@ -293,7 +293,6 @@ static void test_error_state_capture(unsigned ring_id,
* case and it takes a lot more time to wrap, so the acthd can potentially keep
* increasing for a long time
*/
-#define NSEC_PER_SEC 1000000000LL
static void hangcheck_unterminated(void)
{
int fd;
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [i-g-t PATCH v7 2/5] lib: add igt_dummyload
2016-11-16 21:17 i-g-t dummyload/spin batch v7 Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 1/5] lib: Make signal helper definitions reusable Abdiel Janulgue
@ 2016-11-16 21:18 ` Abdiel Janulgue
2016-11-16 13:56 ` Chris Wilson
2016-11-16 21:18 ` [i-g-t PATCH v7 3/5] igt/gem_wait: Use new igt_spin_batch Abdiel Janulgue
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-16 21:18 UTC (permalink / raw)
To: intel-gfx; +Cc: Daniel Vetter
A lot of igt testcases need some GPU workload to make sure a race
window is big enough. Unfortunately having a fixed amount of
workload leads to spurious test failures or overtly long runtimes
on some fast/slow platforms. This library contains functionality
to submit GPU workloads that should consume exactly a specific
amount of time.
v2 : Add recursive batch feature from Chris
v3 : Drop auto-tuned stuff. Add bo dependecy to recursive batch
by adding a dummy reloc to the bo as suggested by Ville.
v4: Fix dependency reloc as write instead of read (Ville).
Fix wrong handling of batchbuffer start on ILK causing
test failure
v5: Convert kms_busy to use this api
v6: Add this library to docs
v7: Document global use of batch, reuse defines
Minor code cleanups.
Rename igt_spin_batch and igt_post_spin_batch to
igt_spin_batch_new and igt_spin_batch_free
respectively (Tomeu Vizoso).
Fix error in dependency relocation handling in HSW causing
tests to fail.
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: tomeu@tomeuvizoso.net
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
.../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 +
lib/Makefile.sources | 2 +
lib/igt.h | 1 +
lib/igt_dummyload.c | 281 +++++++++++++++++++++
lib/igt_dummyload.h | 43 ++++
5 files changed, 328 insertions(+)
create mode 100644 lib/igt_dummyload.c
create mode 100644 lib/igt_dummyload.h
diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
index c862f2a..55902ab 100644
--- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
+++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
@@ -32,6 +32,7 @@
<xi:include href="xml/intel_io.xml"/>
<xi:include href="xml/igt_vc4.xml"/>
<xi:include href="xml/igt_vgem.xml"/>
+ <xi:include href="xml/igt_dummyload.xml"/>
</chapter>
<xi:include href="xml/igt_test_programs.xml"/>
diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index e8e277b..7fc5ec2 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -75,6 +75,8 @@ lib_source_list = \
igt_draw.h \
igt_pm.c \
igt_pm.h \
+ igt_dummyload.c \
+ igt_dummyload.h \
uwildmat/uwildmat.h \
uwildmat/uwildmat.c \
$(NULL)
diff --git a/lib/igt.h b/lib/igt.h
index d751f24..a0028d5 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -32,6 +32,7 @@
#include "igt_core.h"
#include "igt_debugfs.h"
#include "igt_draw.h"
+#include "igt_dummyload.h"
#include "igt_fb.h"
#include "igt_gt.h"
#include "igt_kms.h"
diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
new file mode 100644
index 0000000..d266195
--- /dev/null
+++ b/lib/igt_dummyload.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright © 2016 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 "igt.h"
+#include "igt_dummyload.h"
+#include <time.h>
+#include <signal.h>
+#include <sys/syscall.h>
+
+/**
+ * SECTION:igt_dummyload
+ * @short_description: Library for submitting GPU workloads
+ * @title: Dummyload
+ * @include: igt.h
+ *
+ * A lot of igt testcases need some GPU workload to make sure a race window is
+ * big enough. Unfortunately having a fixed amount of workload leads to
+ * spurious test failures or overly long runtimes on some fast/slow platforms.
+ * This library contains functionality to submit GPU workloads that should
+ * consume exactly a specific amount of time.
+ */
+
+#define LOCAL_I915_EXEC_BSD_SHIFT (13)
+#define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
+
+#define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
+
+static const int bo_size = 4096;
+
+static void
+fill_object(struct drm_i915_gem_exec_object2 *obj, uint32_t gem_handle,
+ struct drm_i915_gem_relocation_entry *relocs, uint32_t count)
+{
+ memset(obj, 0, sizeof(*obj));
+ obj->handle = gem_handle;
+ obj->relocation_count = count;
+ obj->relocs_ptr = (uintptr_t)relocs;
+}
+
+static void
+fill_reloc(struct drm_i915_gem_relocation_entry *reloc,
+ uint32_t gem_handle, uint32_t offset,
+ uint32_t read_domains, uint32_t write_domains)
+{
+ reloc->target_handle = gem_handle;
+ reloc->delta = 0;
+ reloc->offset = offset * sizeof(uint32_t);
+ reloc->presumed_offset = 0;
+ reloc->read_domains = read_domains;
+ reloc->write_domain = write_domains;
+}
+
+/*
+ * Needs to be global. Signal handlers don't accept arguments
+ */
+static uint32_t *batch;
+
+static uint32_t emit_recursive_batch(int fd, int engine, unsigned dep_handle)
+{
+ const 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;
+ unsigned engines[16];
+ unsigned nengine, handle;
+ int i = 0, reloc_count = 0, buf_count = 0;
+
+ buf_count = 0;
+ nengine = 0;
+ if (engine < 0) {
+ for_each_engine(fd, engine)
+ if (engine)
+ engines[nengine++] = engine;
+ } else {
+ gem_require_ring(fd, engine);
+ engines[nengine++] = engine;
+ }
+ igt_require(nengine);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ memset(obj, 0, sizeof(obj));
+ memset(relocs, 0, sizeof(relocs));
+
+ execbuf.buffers_ptr = (uintptr_t) obj;
+ handle = gem_create(fd, bo_size);
+ batch = gem_mmap__gtt(fd, handle, bo_size, PROT_WRITE);
+ igt_assert(batch);
+ gem_set_domain(fd, handle,
+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+ if (gen >= 8) {
+ batch[i++] = MI_BATCH_BUFFER_START | 1 << 8 | 1;
+ /* recurse */
+ fill_reloc(&relocs[reloc_count], handle, i,
+ I915_GEM_DOMAIN_COMMAND, 0);
+ batch[i++] = 0;
+ batch[i++] = 0;
+ } else if (gen >= 6) {
+ batch[i++] = MI_BATCH_BUFFER_START | 1 << 8;
+ /* recurse */
+ fill_reloc(&relocs[reloc_count], handle, i,
+ I915_GEM_DOMAIN_COMMAND, 0);
+ batch[i++] = 0;
+ } else {
+ batch[i++] = MI_BATCH_BUFFER_START | 2 << 6 |
+ ((gen < 4) ? 1 : 0);
+ /* recurse */
+ fill_reloc(&relocs[reloc_count], handle, i,
+ I915_GEM_DOMAIN_COMMAND, 0);
+ batch[i++] = 0;
+ if (gen < 4)
+ relocs[reloc_count].delta = 1;
+ }
+ reloc_count++;
+
+ if (dep_handle > 0) {
+ igt_assert(nengine == 1);
+ /* dummy write to dependency */
+ fill_object(&obj[buf_count], dep_handle, NULL, 0);
+ buf_count++;
+
+ fill_reloc(&relocs[reloc_count], dep_handle, 256,
+ I915_GEM_DOMAIN_RENDER,
+ I915_GEM_DOMAIN_RENDER);
+ reloc_count++;
+ }
+
+ fill_object(&obj[buf_count], handle, relocs, reloc_count);
+ buf_count++;
+
+ for (i = 0; i < nengine; i++) {
+ execbuf.flags &= ~ENGINE_MASK;
+ execbuf.flags = engines[i];
+ execbuf.buffer_count = buf_count;
+ gem_execbuf(fd, &execbuf);
+ }
+
+ return handle;
+}
+
+static void sigiter(int sig, siginfo_t *info, void *arg)
+{
+ *batch = MI_BATCH_BUFFER_END;
+ __sync_synchronize();
+}
+
+static timer_t setup_batch_exit_timer(int64_t ns)
+{
+ timer_t timer;
+ struct sigevent sev;
+ struct sigaction act;
+ struct itimerspec its;
+
+ memset(&sev, 0, sizeof(sev));
+ sev.sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID;
+ sev.sigev_notify_thread_id = gettid();
+ sev.sigev_signo = SIGRTMIN + 1;
+ igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
+ igt_assert(timer > 0);
+
+ memset(&act, 0, sizeof(act));
+ act.sa_sigaction = sigiter;
+ act.sa_flags = SA_SIGINFO;
+ igt_assert(sigaction(SIGRTMIN + 1, &act, NULL) == 0);
+
+ memset(&its, 0, sizeof(its));
+ its.it_value.tv_sec = ns / NSEC_PER_SEC;
+ its.it_value.tv_nsec = ns % NSEC_PER_SEC;
+ igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
+
+ return timer;
+}
+
+/**
+ * igt_spin_batch_new:
+ * @fd: open i915 drm file descriptor
+ * @ns: amount of time in nanoseconds the batch executes after terminating.
+ * If value is less than 0, execute batch forever.
+ * @engine: Ring to execute batch OR'd with execbuf flags. If value is less
+ * than 0, execute on all available rings.
+ * @dep_handle: handle to a buffer object dependency. If greater than 0, add a
+ * relocation entry to this buffer within the batch.
+ *
+ * Start a recursive batch on a ring that terminates after an exact amount
+ * of time has elapsed. 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.
+ *
+ * Returns:
+ * Structure with helper internal state for igt_spin_batch_free().
+ */
+igt_spin_t *
+igt_spin_batch_new(int fd, int64_t ns, int engine, unsigned dep_handle)
+{
+ timer_t timer;
+ igt_spin_t *spin = calloc(1, sizeof(struct igt_spin));
+ uint32_t handle = emit_recursive_batch(fd, engine, dep_handle);
+ int64_t wait_timeout = 0;
+ igt_assert_eq(gem_wait(fd, handle, &wait_timeout), -ETIME);
+
+ spin->handle = handle;
+ spin->batch = batch;
+ spin->timer = NULL;
+ if (ns == 0) {
+ *batch = MI_BATCH_BUFFER_END;
+ __sync_synchronize();
+ } else if (ns > 0) {
+ timer = setup_batch_exit_timer(ns);
+ spin->timer = timer;
+ }
+
+ return spin;
+}
+
+/**
+ * igt_spin_batch_free:
+ * @fd: open i915 drm file descriptor
+ * @arg: spin batch state from igt_spin_batch()
+ *
+ * This function does the necessary post-processing after starting a recursive
+ * batch with igt_spin_batch().
+ */
+void igt_spin_batch_free(int fd, igt_spin_t *arg)
+{
+ if (!arg)
+ return;
+
+ if (arg->handle == 0)
+ return;
+
+ if (arg->timer > 0)
+ timer_delete(arg->timer);
+
+ gem_close(fd, arg->handle);
+ munmap(arg->batch, bo_size);
+ free(arg);
+}
+
+/**
+ * igt_spin_batch_wait:
+ * @fd: open i915 drm file descriptor
+ * @ns: amount of time in nanoseconds the batch executes after terminating.
+ * If value is less than 0, execute batch forever.
+ * @engine: ring to execute batch OR'd with execbuf flags. If value is less
+ * than 0, execute on all available rings.
+ * @dep_handle: handle to a buffer object dependency. If greater than 0, include
+ * this buffer on the wait dependency
+ *
+ * This is similar to igt_spin_batch_new(), but waits on the recursive batch to finish
+ * instead of returning right away. The function also does the necessary
+ * post-processing automatically if set to timeout.
+ */
+void igt_spin_batch_wait(int fd, int64_t ns, int engine, unsigned dep_handle)
+{
+ igt_spin_t *spin = igt_spin_batch_new(fd, ns, engine, dep_handle);
+ int64_t wait_timeout = ns + (0.5 * NSEC_PER_SEC);
+ igt_assert_eq(gem_wait(fd, spin->handle, &wait_timeout), 0);
+
+ igt_spin_batch_free(fd, spin);
+}
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
new file mode 100644
index 0000000..f06e84b
--- /dev/null
+++ b/lib/igt_dummyload.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2016 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_DUMMYLOAD_H__
+#define __IGT_DUMMYLOAD_H__
+
+typedef struct igt_spin {
+ unsigned handle;
+ uint32_t *batch;
+ timer_t timer;
+} igt_spin_t;
+
+
+igt_spin_t *
+igt_spin_batch_new(int fd, int64_t ns, int engine, unsigned dep_handle);
+
+void igt_spin_batch_free(int fd, igt_spin_t *arg);
+
+void igt_spin_batch_wait(int fd, int64_t ns, int engine, unsigned dep_handle);
+
+
+#endif /* __IGT_DUMMYLOAD_H__ */
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [i-g-t PATCH v7 3/5] igt/gem_wait: Use new igt_spin_batch
2016-11-16 21:17 i-g-t dummyload/spin batch v7 Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 1/5] lib: Make signal helper definitions reusable Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 2/5] lib: add igt_dummyload Abdiel Janulgue
@ 2016-11-16 21:18 ` Abdiel Janulgue
2016-11-17 10:22 ` Chris Wilson
2016-11-16 21:18 ` [i-g-t PATCH v7 4/5] igt/kms_flip: " Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 5/5] igt/kms_busy.c: " Abdiel Janulgue
4 siblings, 1 reply; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-16 21:18 UTC (permalink / raw)
To: intel-gfx; +Cc: Daniel Vetter
v7: Adapt to api rename
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
tests/gem_wait.c | 129 +++----------------------------------------------------
1 file changed, 7 insertions(+), 122 deletions(-)
diff --git a/tests/gem_wait.c b/tests/gem_wait.c
index b4127de..d2920e5 100644
--- a/tests/gem_wait.c
+++ b/tests/gem_wait.c
@@ -27,18 +27,6 @@
#include "igt.h"
-#include <signal.h>
-#include <time.h>
-#include <sys/syscall.h>
-
-#define gettid() syscall(__NR_gettid)
-#define sigev_notify_thread_id _sigev_un._tid
-
-#define LOCAL_I915_EXEC_BSD_SHIFT (13)
-#define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
-
-#define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
-
static int __gem_wait(int fd, struct drm_i915_gem_wait *w)
{
int err;
@@ -75,129 +63,30 @@ static void invalid_buf(int fd)
igt_assert_eq(__gem_wait(fd, &wait), -ENOENT);
}
-static uint32_t *batch;
-
-static void sigiter(int sig, siginfo_t *info, void *arg)
-{
- *batch = MI_BATCH_BUFFER_END;
- __sync_synchronize();
-}
-
-#define MSEC_PER_SEC (1000)
-#define USEC_PER_SEC (1000 * MSEC_PER_SEC)
-#define NSEC_PER_SEC (1000 * USEC_PER_SEC)
-
#define BUSY 1
#define HANG 2
static void basic(int fd, unsigned engine, unsigned flags)
{
- const int gen = intel_gen(intel_get_drm_devid(fd));
- struct drm_i915_gem_exec_object2 obj;
- struct drm_i915_gem_relocation_entry reloc;
- struct drm_i915_gem_execbuffer2 execbuf;
struct drm_i915_gem_wait wait;
- unsigned engines[16];
- unsigned nengine;
- int i, timeout;
-
- nengine = 0;
- if (engine == -1) {
- for_each_engine(fd, engine)
- if (engine) engines[nengine++] = engine;
- } else {
- igt_require(gem_has_ring(fd, engine));
- engines[nengine++] = engine;
- }
- igt_require(nengine);
-
- memset(&execbuf, 0, sizeof(execbuf));
- execbuf.buffers_ptr = (uintptr_t)&obj;
- execbuf.buffer_count = 1;
-
- memset(&obj, 0, sizeof(obj));
- obj.handle = gem_create(fd, 4096);
-
- obj.relocs_ptr = (uintptr_t)&reloc;
- obj.relocation_count = 1;
- memset(&reloc, 0, sizeof(reloc));
-
- batch = gem_mmap__gtt(fd, obj.handle, 4096, PROT_WRITE);
- gem_set_domain(fd, obj.handle,
- I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
-
- reloc.target_handle = obj.handle; /* recurse */
- reloc.presumed_offset = 0;
- reloc.offset = sizeof(uint32_t);
- reloc.delta = 0;
- reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
- reloc.write_domain = 0;
-
- i = 0;
- batch[i] = MI_BATCH_BUFFER_START;
- if (gen >= 8) {
- batch[i] |= 1 << 8 | 1;
- batch[++i] = 0;
- batch[++i] = 0;
- } else if (gen >= 6) {
- batch[i] |= 1 << 8;
- batch[++i] = 0;
- } else {
- batch[i] |= 2 << 6;
- batch[++i] = 0;
- if (gen < 4) {
- batch[i] |= 1;
- reloc.delta = 1;
- }
- }
-
- for (i = 0; i < nengine; i++) {
- execbuf.flags &= ~ENGINE_MASK;
- execbuf.flags |= engines[i];
- gem_execbuf(fd, &execbuf);
- }
+ int wait_s = (flags == 0) ? NSEC_PER_SEC : 0;
+ wait_s = ((flags & HANG) == 0) ? wait_s : -1;
+ igt_spin_t *spin = igt_spin_batch_new(fd, wait_s, engine, 0);
+ int timeout;
memset(&wait, 0, sizeof(wait));
- wait.bo_handle = obj.handle;
- igt_assert_eq(__gem_wait(fd, &wait), -ETIME);
+ wait.bo_handle = spin->handle;
if (flags & BUSY) {
struct timespec tv;
timeout = 120;
- if ((flags & HANG) == 0) {
- *batch = MI_BATCH_BUFFER_END;
- __sync_synchronize();
+ if ((flags & HANG) == 0)
timeout = 1;
- }
memset(&tv, 0, sizeof(tv));
while (__gem_wait(fd, &wait) == -ETIME)
igt_assert(igt_seconds_elapsed(&tv) < timeout);
} else {
- timer_t timer;
-
- if ((flags & HANG) == 0) {
- struct sigevent sev;
- struct sigaction act;
- struct itimerspec its;
-
- memset(&sev, 0, sizeof(sev));
- sev.sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID;
- sev.sigev_notify_thread_id = gettid();
- sev.sigev_signo = SIGRTMIN + 1;
- igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
-
- memset(&act, 0, sizeof(act));
- act.sa_sigaction = sigiter;
- act.sa_flags = SA_SIGINFO;
- igt_assert(sigaction(SIGRTMIN + 1, &act, NULL) == 0);
-
- memset(&its, 0, sizeof(its));
- its.it_value.tv_nsec = 0;
- its.it_value.tv_sec = 1;
- igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
- }
-
wait.timeout_ns = NSEC_PER_SEC / 2; /* 0.5s */
igt_assert_eq(__gem_wait(fd, &wait), -ETIME);
igt_assert_eq_s64(wait.timeout_ns, 0);
@@ -215,13 +104,9 @@ static void basic(int fd, unsigned engine, unsigned flags)
wait.timeout_ns = 0;
igt_assert_eq(__gem_wait(fd, &wait), 0);
igt_assert(wait.timeout_ns == 0);
-
- if ((flags & HANG) == 0)
- timer_delete(timer);
}
- gem_close(fd, obj.handle);
- munmap(batch, 4096);
+ igt_spin_batch_free(fd, spin);
}
igt_main
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [i-g-t PATCH v7 4/5] igt/kms_flip: Use new igt_spin_batch
2016-11-16 21:17 i-g-t dummyload/spin batch v7 Abdiel Janulgue
` (2 preceding siblings ...)
2016-11-16 21:18 ` [i-g-t PATCH v7 3/5] igt/gem_wait: Use new igt_spin_batch Abdiel Janulgue
@ 2016-11-16 21:18 ` Abdiel Janulgue
2016-11-17 10:25 ` Chris Wilson
2016-11-16 21:18 ` [i-g-t PATCH v7 5/5] igt/kms_busy.c: " Abdiel Janulgue
4 siblings, 1 reply; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-16 21:18 UTC (permalink / raw)
To: intel-gfx; +Cc: Daniel Vetter
v7: Reuse NSEC_PER_SEC defines
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
tests/kms_flip.c | 188 ++-----------------------------------------------------
1 file changed, 4 insertions(+), 184 deletions(-)
diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index 2a9fe2e..c0a51b0 100644
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -85,9 +85,6 @@
#define DRM_CAP_TIMESTAMP_MONOTONIC 6
#endif
-#define USEC_PER_SEC 1000000L
-#define NSEC_PER_SEC 1000000000L
-
drmModeRes *resources;
int drm_fd;
static drm_intel_bufmgr *bufmgr;
@@ -191,109 +188,6 @@ static unsigned long gettime_us(void)
return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
}
-static int calibrate_dummy_load(struct test_output *o,
- const char *ring_name,
- int (*emit)(struct test_output *o, int limit, int timeout))
-{
- unsigned long start;
- int ops = 1;
-
- start = gettime_us();
-
- do {
- unsigned long diff;
- int ret;
-
- ret = emit(o, (ops+1)/2, 10);
- diff = gettime_us() - start;
-
- if (ret || diff / USEC_PER_SEC >= 1)
- break;
-
- ops += ops;
- } while (ops < 100000);
-
- igt_debug("%s dummy load calibrated: %d operations / second\n",
- ring_name, ops);
-
- return ops;
-}
-
-static void blit_copy(drm_intel_bo *dst, drm_intel_bo *src,
- unsigned int width, unsigned int height,
- unsigned int dst_pitch, unsigned int src_pitch)
-{
- BLIT_COPY_BATCH_START(0);
- OUT_BATCH((3 << 24) | /* 32 bits */
- (0xcc << 16) | /* copy ROP */
- dst_pitch);
- OUT_BATCH(0 << 16 | 0);
- OUT_BATCH(height << 16 | width);
- OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
- OUT_BATCH(0 << 16 | 0);
- OUT_BATCH(src_pitch);
- OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0);
- ADVANCE_BATCH();
-
- if (batch->gen >= 6) {
- BEGIN_BATCH(3, 0);
- OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
- }
-}
-
-static int _emit_dummy_load__bcs(struct test_output *o, int limit, int timeout)
-{
- int i, ret = 0;
- drm_intel_bo *src_bo, *dst_bo, *fb_bo;
- struct igt_fb *fb_info = &o->fb_info[o->current_fb_id];
-
- igt_require(bufmgr);
-
- src_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
- igt_assert(src_bo);
-
- dst_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
- igt_assert(dst_bo);
-
- fb_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle);
- igt_assert(fb_bo);
-
- for (i = 0; i < limit; i++) {
- blit_copy(dst_bo, src_bo,
- 2048, 2048,
- 2048*4, 2048*4);
-
- igt_swap(src_bo, dst_bo);
- }
- blit_copy(fb_bo, src_bo,
- min(o->fb_width, 2048), min(o->fb_height, 2048),
- fb_info->stride, 2048*4);
- intel_batchbuffer_flush(batch);
-
- if (timeout > 0)
- ret = drm_intel_gem_bo_wait(fb_bo, timeout * NSEC_PER_SEC);
-
- drm_intel_bo_unreference(src_bo);
- drm_intel_bo_unreference(dst_bo);
- drm_intel_bo_unreference(fb_bo);
-
- return ret;
-}
-
-static void emit_dummy_load__bcs(struct test_output *o, int seconds)
-{
- static int ops_per_sec;
-
- if (ops_per_sec == 0)
- ops_per_sec = calibrate_dummy_load(o, "bcs",
- _emit_dummy_load__bcs);
-
- _emit_dummy_load__bcs(o, seconds * ops_per_sec, 0);
-}
-
static void emit_fence_stress(struct test_output *o)
{
const int num_fences = gem_available_fences(drm_fd);
@@ -338,82 +232,6 @@ static void emit_fence_stress(struct test_output *o)
free(exec);
}
-static int _emit_dummy_load__rcs(struct test_output *o, int limit, int timeout)
-{
- const struct igt_fb *fb_info = &o->fb_info[o->current_fb_id];
- igt_render_copyfunc_t copyfunc;
- struct igt_buf sb[3], *src, *dst, *fb;
- int i, ret = 0;
-
- igt_require(bufmgr);
-
- copyfunc = igt_get_render_copyfunc(devid);
- if (copyfunc == NULL)
- return _emit_dummy_load__bcs(o, limit, timeout);
-
- sb[0].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
- igt_assert(sb[0].bo);
- sb[0].size = sb[0].bo->size;
- sb[0].tiling = I915_TILING_NONE;
- sb[0].data = NULL;
- sb[0].num_tiles = sb[0].bo->size;
- sb[0].stride = 4 * 2048;
-
- sb[1].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
- igt_assert(sb[1].bo);
- sb[1].size = sb[1].bo->size;
- sb[1].tiling = I915_TILING_NONE;
- sb[1].data = NULL;
- sb[1].num_tiles = sb[1].bo->size;
- sb[1].stride = 4 * 2048;
-
- sb[2].bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle);
- igt_assert(sb[2].bo);
- sb[2].size = sb[2].bo->size;
- sb[2].tiling = igt_fb_mod_to_tiling(fb_info->tiling);
- sb[2].data = NULL;
- sb[2].num_tiles = sb[2].bo->size;
- sb[2].stride = fb_info->stride;
-
- src = &sb[0];
- dst = &sb[1];
- fb = &sb[2];
-
- for (i = 0; i < limit; i++) {
- copyfunc(batch, NULL,
- src, 0, 0,
- 2048, 2048,
- dst, 0, 0);
-
- igt_swap(src, dst);
- }
- copyfunc(batch, NULL,
- src, 0, 0,
- min(o->fb_width, 2048), min(o->fb_height, 2048),
- fb, 0, 0);
- intel_batchbuffer_flush(batch);
-
- if (timeout > 0)
- ret = drm_intel_gem_bo_wait(fb->bo, timeout * NSEC_PER_SEC);
-
- drm_intel_bo_unreference(sb[0].bo);
- drm_intel_bo_unreference(sb[1].bo);
- drm_intel_bo_unreference(sb[2].bo);
-
- return ret;
-}
-
-static void emit_dummy_load__rcs(struct test_output *o, int seconds)
-{
- static int ops_per_sec;
-
- if (ops_per_sec == 0)
- ops_per_sec = calibrate_dummy_load(o, "rcs",
- _emit_dummy_load__rcs);
-
- _emit_dummy_load__bcs(o, seconds * ops_per_sec, 0);
-}
-
static void dpms_off_other_outputs(struct test_output *o)
{
int i, n;
@@ -874,10 +692,12 @@ static unsigned int run_test_step(struct test_output *o)
o->current_fb_id = !o->current_fb_id;
if (o->flags & TEST_WITH_DUMMY_BCS)
- emit_dummy_load__bcs(o, 1);
+ igt_spin_batch_wait(drm_fd, NSEC_PER_SEC, I915_EXEC_BLT,
+ o->fb_info[o->current_fb_id].gem_handle);
if (o->flags & TEST_WITH_DUMMY_RCS)
- emit_dummy_load__rcs(o, 1);
+ igt_spin_batch_wait(drm_fd, NSEC_PER_SEC, I915_EXEC_RENDER,
+ o->fb_info[o->current_fb_id].gem_handle);
if (o->flags & TEST_FB_RECREATE)
recreate_fb(o);
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [i-g-t PATCH v7 5/5] igt/kms_busy.c: Use new igt_spin_batch
2016-11-16 21:17 i-g-t dummyload/spin batch v7 Abdiel Janulgue
` (3 preceding siblings ...)
2016-11-16 21:18 ` [i-g-t PATCH v7 4/5] igt/kms_flip: " Abdiel Janulgue
@ 2016-11-16 21:18 ` Abdiel Janulgue
2016-11-17 10:27 ` Chris Wilson
4 siblings, 1 reply; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-16 21:18 UTC (permalink / raw)
To: intel-gfx; +Cc: Daniel Vetter
v7: Adapt to api rename
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
tests/kms_busy.c | 75 +++-----------------------------------------------------
1 file changed, 4 insertions(+), 71 deletions(-)
diff --git a/tests/kms_busy.c b/tests/kms_busy.c
index b555f99..680aebe 100644
--- a/tests/kms_busy.c
+++ b/tests/kms_busy.c
@@ -78,73 +78,6 @@ static void do_cleanup_display(igt_display_t *dpy)
igt_display_commit2(dpy, dpy->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
}
-static uint32_t *
-make_fb_busy(igt_display_t *dpy, unsigned ring, const struct igt_fb *fb)
-{
- const int gen = intel_gen(intel_get_drm_devid(dpy->drm_fd));
- struct drm_i915_gem_exec_object2 obj[2];
-#define SCRATCH 0
-#define BATCH 1
- struct drm_i915_gem_relocation_entry reloc[2];
- struct drm_i915_gem_execbuffer2 execbuf;
- uint32_t *batch;
- int i;
-
- memset(&execbuf, 0, sizeof(execbuf));
- execbuf.buffers_ptr = (uintptr_t)obj;
- execbuf.buffer_count = 2;
- execbuf.flags = ring;
-
- memset(obj, 0, sizeof(obj));
- obj[SCRATCH].handle = fb->gem_handle;
-
- obj[BATCH].handle = gem_create(dpy->drm_fd, 4096);
- obj[BATCH].relocs_ptr = (uintptr_t)reloc;
- obj[BATCH].relocation_count = 2;
- memset(reloc, 0, sizeof(reloc));
- reloc[0].target_handle = obj[BATCH].handle; /* recurse */
- reloc[0].presumed_offset = 0;
- reloc[0].offset = sizeof(uint32_t);
- reloc[0].delta = 0;
- reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
- reloc[0].write_domain = 0;
-
- batch = gem_mmap__wc(dpy->drm_fd,
- obj[BATCH].handle, 0, 4096, PROT_WRITE);
- gem_set_domain(dpy->drm_fd, obj[BATCH].handle,
- I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
-
- batch[i = 0] = MI_BATCH_BUFFER_START;
- if (gen >= 8) {
- batch[i] |= 1 << 8 | 1;
- batch[++i] = 0;
- batch[++i] = 0;
- } else if (gen >= 6) {
- batch[i] |= 1 << 8;
- batch[++i] = 0;
- } else {
- batch[i] |= 2 << 6;
- batch[++i] = 0;
- if (gen < 4) {
- batch[i] |= 1;
- reloc[0].delta = 1;
- }
- }
-
- /* dummy write to fb */
- reloc[1].target_handle = obj[SCRATCH].handle;
- reloc[1].presumed_offset = 0;
- reloc[1].offset = 1024;
- reloc[1].delta = 0;
- reloc[1].read_domains = I915_GEM_DOMAIN_RENDER;
- reloc[1].write_domain = I915_GEM_DOMAIN_RENDER;
-
- gem_execbuf(dpy->drm_fd, &execbuf);
- gem_close(dpy->drm_fd, obj[BATCH].handle);
-
- return batch;
-}
-
static void finish_fb_busy(uint32_t *batch, int msecs)
{
struct timespec tv = { 0, msecs * 1000 * 1000 };
@@ -165,9 +98,8 @@ static void flip_to_fb(igt_display_t *dpy, int pipe,
struct pollfd pfd = { .fd = dpy->drm_fd, .events = POLLIN };
struct timespec tv = { 1, 0 };
struct drm_event_vblank ev;
- uint32_t *batch;
-
- batch = make_fb_busy(dpy, ring, fb);
+ igt_spin_t *t = igt_spin_batch_new(dpy->drm_fd, -1,
+ ring, fb->gem_handle);
igt_fork(child, 1) {
igt_assert(gem_bo_busy(dpy->drm_fd, fb->gem_handle));
do_or_die(drmModePageFlip(dpy->drm_fd,
@@ -179,7 +111,8 @@ static void flip_to_fb(igt_display_t *dpy, int pipe,
}
igt_assert_f(nanosleep(&tv, NULL) == -1,
"flip to %s blocked waiting for busy fb", name);
- finish_fb_busy(batch, 2*TIMEOUT);
+ finish_fb_busy(t->batch, 2*TIMEOUT);
+ igt_spin_batch_free(dpy->drm_fd, t);
igt_waitchildren();
igt_assert(read(dpy->drm_fd, &ev, sizeof(ev)) == sizeof(ev));
igt_assert(poll(&pfd, 1, 0) == 0);
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [i-g-t PATCH v7 3/5] igt/gem_wait: Use new igt_spin_batch
2016-11-16 21:18 ` [i-g-t PATCH v7 3/5] igt/gem_wait: Use new igt_spin_batch Abdiel Janulgue
@ 2016-11-17 10:22 ` Chris Wilson
0 siblings, 0 replies; 14+ messages in thread
From: Chris Wilson @ 2016-11-17 10:22 UTC (permalink / raw)
To: Abdiel Janulgue; +Cc: Daniel Vetter, intel-gfx
On Wed, Nov 16, 2016 at 11:18:02PM +0200, Abdiel Janulgue wrote:
> + int wait_s = (flags == 0) ? NSEC_PER_SEC : 0;
> + wait_s = ((flags & HANG) == 0) ? wait_s : -1;
> + igt_spin_t *spin = igt_spin_batch_new(fd, wait_s, engine, 0);
We haven't been using C99 locals.
If you separated out the timer as a seperate call, this would be nicer,
as most users don't use it.
> + int timeout;
>
> memset(&wait, 0, sizeof(wait));
> - wait.bo_handle = obj.handle;
> - igt_assert_eq(__gem_wait(fd, &wait), -ETIME);
This assert should remain since it is a sanitycheck that we are setup
for testing a wait.
Other than that I could bikeshed the names for years to come, looks ok.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [i-g-t PATCH v7 4/5] igt/kms_flip: Use new igt_spin_batch
2016-11-16 21:18 ` [i-g-t PATCH v7 4/5] igt/kms_flip: " Abdiel Janulgue
@ 2016-11-17 10:25 ` Chris Wilson
0 siblings, 0 replies; 14+ messages in thread
From: Chris Wilson @ 2016-11-17 10:25 UTC (permalink / raw)
To: Abdiel Janulgue; +Cc: Daniel Vetter, intel-gfx
On Wed, Nov 16, 2016 at 11:18:03PM +0200, Abdiel Janulgue wrote:
> if (o->flags & TEST_WITH_DUMMY_BCS)
> - emit_dummy_load__bcs(o, 1);
> + igt_spin_batch_wait(drm_fd, NSEC_PER_SEC, I915_EXEC_BLT,
> + o->fb_info[o->current_fb_id].gem_handle);
This is counterintuitive for the purpose of testing flips. We don't want
the fb to be idle, which is what will happen if we wait upon it.
We want to set off a spinner that will only complete once we have queued
the flip. We can eliminate the 1s dummy load by being explicit in the
ordering.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [i-g-t PATCH v7 5/5] igt/kms_busy.c: Use new igt_spin_batch
2016-11-16 21:18 ` [i-g-t PATCH v7 5/5] igt/kms_busy.c: " Abdiel Janulgue
@ 2016-11-17 10:27 ` Chris Wilson
2016-11-17 10:29 ` Abdiel Janulgue
0 siblings, 1 reply; 14+ messages in thread
From: Chris Wilson @ 2016-11-17 10:27 UTC (permalink / raw)
To: Abdiel Janulgue; +Cc: Daniel Vetter, intel-gfx
On Wed, Nov 16, 2016 at 11:18:04PM +0200, Abdiel Janulgue wrote:
> @@ -179,7 +111,8 @@ static void flip_to_fb(igt_display_t *dpy, int pipe,
> }
> igt_assert_f(nanosleep(&tv, NULL) == -1,
> "flip to %s blocked waiting for busy fb", name);
> - finish_fb_busy(batch, 2*TIMEOUT);
> + finish_fb_busy(t->batch, 2*TIMEOUT);
As you didn't adjust finish_fb_busy, this is a double munmap.
finish_fb_busy() is now just a sleep to allow the worker to do its
things. That could be tidied up.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [i-g-t PATCH v7 5/5] igt/kms_busy.c: Use new igt_spin_batch
2016-11-17 10:27 ` Chris Wilson
@ 2016-11-17 10:29 ` Abdiel Janulgue
0 siblings, 0 replies; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-17 10:29 UTC (permalink / raw)
To: Chris Wilson, intel-gfx, Daniel Vetter
On 17.11.2016 12:27, Chris Wilson wrote:
> On Wed, Nov 16, 2016 at 11:18:04PM +0200, Abdiel Janulgue wrote:
>> @@ -179,7 +111,8 @@ static void flip_to_fb(igt_display_t *dpy, int pipe,
>> }
>> igt_assert_f(nanosleep(&tv, NULL) == -1,
>> "flip to %s blocked waiting for busy fb", name);
>> - finish_fb_busy(batch, 2*TIMEOUT);
>> + finish_fb_busy(t->batch, 2*TIMEOUT);
>
> As you didn't adjust finish_fb_busy, this is a double munmap.
>
> finish_fb_busy() is now just a sleep to allow the worker to do its
> things. That could be tidied up.
> -Chris
Hey thanks for the review! I'll follow up asap!
-Abdiel
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* [i-g-t PATCH v8 2/5] lib: add igt_dummyload
2016-11-16 14:17 ` Chris Wilson
@ 2016-11-17 17:45 ` Abdiel Janulgue
0 siblings, 0 replies; 14+ messages in thread
From: Abdiel Janulgue @ 2016-11-17 17:45 UTC (permalink / raw)
To: intel-gfx; +Cc: Daniel Vetter
A lot of igt testcases need some GPU workload to make sure a race
window is big enough. Unfortunately having a fixed amount of
workload leads to spurious test failures or overly long runtimes
on some fast/slow platforms. This library contains functionality
to submit GPU workloads that should consume exactly a specific
amount of time.
v2 : Add recursive batch feature from Chris
v3 : Drop auto-tuned stuff. Add bo dependecy to recursive batch
by adding a dummy reloc to the bo as suggested by Ville.
v4: Fix dependency reloc as write instead of read (Ville).
Fix wrong handling of batchbuffer start on ILK causing
test failure
v5: Convert kms_busy to use this api
v6: Add this library to docs
v7: Document global use of batch, reuse defines
Minor code cleanups.
Rename igt_spin_batch and igt_post_spin_batch to
igt_spin_batch_new and igt_spin_batch_free
respectively (Tomeu Vizoso).
Fix error in dependency relocation handling in HSW causing
tests to fail.
v8: Restore correct order of objects in the execbuffer. Batch
object should always be last.
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: tomeu@tomeuvizoso.net
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
.../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 +
lib/Makefile.sources | 2 +
lib/igt.h | 1 +
lib/igt_dummyload.c | 280 +++++++++++++++++++++
lib/igt_dummyload.h | 43 ++++
5 files changed, 327 insertions(+)
create mode 100644 lib/igt_dummyload.c
create mode 100644 lib/igt_dummyload.h
diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
index c862f2a..55902ab 100644
--- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
+++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
@@ -32,6 +32,7 @@
<xi:include href="xml/intel_io.xml"/>
<xi:include href="xml/igt_vc4.xml"/>
<xi:include href="xml/igt_vgem.xml"/>
+ <xi:include href="xml/igt_dummyload.xml"/>
</chapter>
<xi:include href="xml/igt_test_programs.xml"/>
diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index e8e277b..7fc5ec2 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -75,6 +75,8 @@ lib_source_list = \
igt_draw.h \
igt_pm.c \
igt_pm.h \
+ igt_dummyload.c \
+ igt_dummyload.h \
uwildmat/uwildmat.h \
uwildmat/uwildmat.c \
$(NULL)
diff --git a/lib/igt.h b/lib/igt.h
index d751f24..a0028d5 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -32,6 +32,7 @@
#include "igt_core.h"
#include "igt_debugfs.h"
#include "igt_draw.h"
+#include "igt_dummyload.h"
#include "igt_fb.h"
#include "igt_gt.h"
#include "igt_kms.h"
diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
new file mode 100644
index 0000000..957a2ac
--- /dev/null
+++ b/lib/igt_dummyload.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright © 2016 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 "igt.h"
+#include "igt_dummyload.h"
+#include <time.h>
+#include <signal.h>
+#include <sys/syscall.h>
+
+/**
+ * SECTION:igt_dummyload
+ * @short_description: Library for submitting GPU workloads
+ * @title: Dummyload
+ * @include: igt.h
+ *
+ * A lot of igt testcases need some GPU workload to make sure a race window is
+ * big enough. Unfortunately having a fixed amount of workload leads to
+ * spurious test failures or overly long runtimes on some fast/slow platforms.
+ * This library contains functionality to submit GPU workloads that should
+ * consume exactly a specific amount of time.
+ */
+
+#define LOCAL_I915_EXEC_BSD_SHIFT (13)
+#define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
+
+#define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
+
+static const int bo_size = 4096;
+
+static void
+fill_object(struct drm_i915_gem_exec_object2 *obj, uint32_t gem_handle,
+ struct drm_i915_gem_relocation_entry *relocs, uint32_t count)
+{
+ memset(obj, 0, sizeof(*obj));
+ obj->handle = gem_handle;
+ obj->relocation_count = count;
+ obj->relocs_ptr = (uintptr_t)relocs;
+}
+
+static void
+fill_reloc(struct drm_i915_gem_relocation_entry *reloc,
+ uint32_t gem_handle, uint32_t offset,
+ uint32_t read_domains, uint32_t write_domains)
+{
+ reloc->target_handle = gem_handle;
+ reloc->delta = 0;
+ reloc->offset = offset * sizeof(uint32_t);
+ reloc->presumed_offset = 0;
+ reloc->read_domains = read_domains;
+ reloc->write_domain = write_domains;
+}
+
+/*
+ * Needs to be global. Signal handlers don't accept arguments
+ */
+static uint32_t *batch;
+
+static uint32_t emit_recursive_batch(int fd, int engine, unsigned dep_handle)
+{
+ const 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;
+ unsigned engines[16];
+ unsigned nengine, handle;
+ int i = 0, reloc_count = 0, buf_count = 0;
+
+ buf_count = 0;
+ nengine = 0;
+ if (engine < 0) {
+ for_each_engine(fd, engine)
+ if (engine)
+ engines[nengine++] = engine;
+ } else {
+ gem_require_ring(fd, engine);
+ engines[nengine++] = engine;
+ }
+ igt_require(nengine);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ memset(obj, 0, sizeof(obj));
+ memset(relocs, 0, sizeof(relocs));
+
+ execbuf.buffers_ptr = (uintptr_t) obj;
+ handle = gem_create(fd, bo_size);
+ batch = gem_mmap__gtt(fd, handle, bo_size, PROT_WRITE);
+ igt_assert(batch);
+ gem_set_domain(fd, handle,
+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+ if (dep_handle > 0) {
+ igt_assert(nengine == 1);
+ /* dummy write to dependency */
+ fill_object(&obj[buf_count], dep_handle, NULL, 0);
+ buf_count++;
+
+ fill_reloc(&relocs[reloc_count], dep_handle, 256,
+ I915_GEM_DOMAIN_RENDER,
+ I915_GEM_DOMAIN_RENDER);
+ reloc_count++;
+ }
+
+ if (gen >= 8) {
+ batch[i++] = MI_BATCH_BUFFER_START | 1 << 8 | 1;
+ /* recurse */
+ fill_reloc(&relocs[reloc_count], handle, i,
+ I915_GEM_DOMAIN_COMMAND, 0);
+ batch[i++] = 0;
+ batch[i++] = 0;
+ } else if (gen >= 6) {
+ batch[i++] = MI_BATCH_BUFFER_START | 1 << 8;
+ /* recurse */
+ fill_reloc(&relocs[reloc_count], handle, i,
+ I915_GEM_DOMAIN_COMMAND, 0);
+ batch[i++] = 0;
+ } else {
+ batch[i++] = MI_BATCH_BUFFER_START | 2 << 6 |
+ ((gen < 4) ? 1 : 0);
+ /* recurse */
+ fill_reloc(&relocs[reloc_count], handle, i,
+ I915_GEM_DOMAIN_COMMAND, 0);
+ batch[i++] = 0;
+ if (gen < 4)
+ relocs[reloc_count].delta = 1;
+ }
+ reloc_count++;
+
+ fill_object(&obj[buf_count], handle, relocs, reloc_count);
+ buf_count++;
+
+ for (i = 0; i < nengine; i++) {
+ execbuf.flags &= ~ENGINE_MASK;
+ execbuf.flags = engines[i];
+ execbuf.buffer_count = buf_count;
+ gem_execbuf(fd, &execbuf);
+ }
+
+ return handle;
+}
+
+static void sigiter(int sig, siginfo_t *info, void *arg)
+{
+ *batch = MI_BATCH_BUFFER_END;
+ __sync_synchronize();
+}
+
+static timer_t setup_batch_exit_timer(int64_t ns)
+{
+ timer_t timer;
+ struct sigevent sev;
+ struct sigaction act;
+ struct itimerspec its;
+
+ memset(&sev, 0, sizeof(sev));
+ sev.sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID;
+ sev.sigev_notify_thread_id = gettid();
+ sev.sigev_signo = SIGRTMIN + 1;
+ igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
+ igt_assert(timer > 0);
+
+ memset(&act, 0, sizeof(act));
+ act.sa_sigaction = sigiter;
+ act.sa_flags = SA_SIGINFO;
+ igt_assert(sigaction(SIGRTMIN + 1, &act, NULL) == 0);
+
+ memset(&its, 0, sizeof(its));
+ its.it_value.tv_sec = ns / NSEC_PER_SEC;
+ its.it_value.tv_nsec = ns % NSEC_PER_SEC;
+ igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
+
+ return timer;
+}
+
+/**
+ * igt_spin_batch_new:
+ * @fd: open i915 drm file descriptor
+ * @ns: amount of time in nanoseconds the batch executes after terminating.
+ * If value is less than 0, execute batch forever.
+ * @engine: Ring to execute batch OR'd with execbuf flags. If value is less
+ * than 0, execute on all available rings.
+ * @dep_handle: handle to a buffer object dependency. If greater than 0, add a
+ * relocation entry to this buffer within the batch.
+ *
+ * Start a recursive batch on a ring that terminates after an exact amount
+ * of time has elapsed. 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.
+ *
+ * Returns:
+ * Structure with helper internal state for igt_spin_batch_free().
+ */
+igt_spin_t *
+igt_spin_batch_new(int fd, int64_t ns, int engine, unsigned dep_handle)
+{
+ timer_t timer;
+ igt_spin_t *spin = calloc(1, sizeof(struct igt_spin));
+ uint32_t handle = emit_recursive_batch(fd, engine, dep_handle);
+ int64_t wait_timeout = 0;
+ igt_assert_eq(gem_wait(fd, handle, &wait_timeout), -ETIME);
+
+ spin->handle = handle;
+ spin->batch = batch;
+ spin->timer = NULL;
+ if (ns == 0) {
+ *batch = MI_BATCH_BUFFER_END;
+ __sync_synchronize();
+ } else if (ns > 0) {
+ timer = setup_batch_exit_timer(ns);
+ spin->timer = timer;
+ }
+
+ return spin;
+}
+
+/**
+ * igt_spin_batch_free:
+ * @fd: open i915 drm file descriptor
+ * @arg: spin batch state from igt_spin_batch()
+ *
+ * This function does the necessary post-processing after starting a recursive
+ * batch with igt_spin_batch_new().
+ */
+void igt_spin_batch_free(int fd, igt_spin_t *arg)
+{
+ if (!arg)
+ return;
+
+ if (arg->handle > 0)
+ gem_close(fd, arg->handle);
+
+ if (arg->timer > 0)
+ timer_delete(arg->timer);
+
+ munmap(arg->batch, bo_size);
+ free(arg);
+}
+
+/**
+ * igt_spin_batch_wait:
+ * @fd: open i915 drm file descriptor
+ * @ns: amount of time in nanoseconds the batch executes after terminating.
+ * If value is less than 0, execute batch forever.
+ * @engine: ring to execute batch OR'd with execbuf flags. If value is less
+ * than 0, execute on all available rings.
+ * @dep_handle: handle to a buffer object dependency. If greater than 0, include
+ * this buffer on the wait dependency
+ *
+ * This is similar to igt_spin_batch_new(), but waits on the recursive batch to finish
+ * instead of returning right away. The function also does the necessary
+ * post-processing automatically if set to timeout.
+ */
+void igt_spin_batch_wait(int fd, int64_t ns, int engine, unsigned dep_handle)
+{
+ igt_spin_t *spin = igt_spin_batch_new(fd, ns, engine, dep_handle);
+ int64_t wait_timeout = ns + (0.5 * NSEC_PER_SEC);
+ igt_assert_eq(gem_wait(fd, spin->handle, &wait_timeout), 0);
+
+ igt_spin_batch_free(fd, spin);
+}
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
new file mode 100644
index 0000000..f06e84b
--- /dev/null
+++ b/lib/igt_dummyload.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2016 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_DUMMYLOAD_H__
+#define __IGT_DUMMYLOAD_H__
+
+typedef struct igt_spin {
+ unsigned handle;
+ uint32_t *batch;
+ timer_t timer;
+} igt_spin_t;
+
+
+igt_spin_t *
+igt_spin_batch_new(int fd, int64_t ns, int engine, unsigned dep_handle);
+
+void igt_spin_batch_free(int fd, igt_spin_t *arg);
+
+void igt_spin_batch_wait(int fd, int64_t ns, int engine, unsigned dep_handle);
+
+
+#endif /* __IGT_DUMMYLOAD_H__ */
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2016-11-17 10:29 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-16 21:17 i-g-t dummyload/spin batch v7 Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 1/5] lib: Make signal helper definitions reusable Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 2/5] lib: add igt_dummyload Abdiel Janulgue
2016-11-16 13:56 ` Chris Wilson
2016-11-16 14:07 ` Abdiel Janulgue
2016-11-16 14:17 ` Chris Wilson
2016-11-17 17:45 ` [i-g-t PATCH v8 " Abdiel Janulgue
2016-11-16 21:18 ` [i-g-t PATCH v7 3/5] igt/gem_wait: Use new igt_spin_batch Abdiel Janulgue
2016-11-17 10:22 ` Chris Wilson
2016-11-16 21:18 ` [i-g-t PATCH v7 4/5] igt/kms_flip: " Abdiel Janulgue
2016-11-17 10:25 ` Chris Wilson
2016-11-16 21:18 ` [i-g-t PATCH v7 5/5] igt/kms_busy.c: " Abdiel Janulgue
2016-11-17 10:27 ` Chris Wilson
2016-11-17 10:29 ` Abdiel Janulgue
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).