intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH i-g-t v5 1/4] lib: add igt_dummyload
  2016-11-11 17:41 ` [PATCH i-g-t v5 1/4] lib: add igt_dummyload Abdiel Janulgue
@ 2016-11-11 16:16   ` Daniel Vetter
  2016-11-14 18:24     ` (no subject) Abdiel Janulgue
  0 siblings, 1 reply; 39+ messages in thread
From: Daniel Vetter @ 2016-11-11 16:16 UTC (permalink / raw)
  To: Abdiel Janulgue; +Cc: Daniel Vetter, intel-gfx

On Fri, Nov 11, 2016 at 07:41:10PM +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
> 
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> ---
>  lib/Makefile.sources |   2 +
>  lib/igt.h            |   1 +
>  lib/igt_dummyload.c  | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_dummyload.h  |  42 ++++++++

Did you check that your new docs do show up in the generated
documentation? Iirc you need to edit some xml under docs/.
-Daniel

>  4 files changed, 321 insertions(+)
>  create mode 100644 lib/igt_dummyload.c
>  create mode 100644 lib/igt_dummyload.h
> 
> 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..b934fd5
> --- /dev/null
> +++ b/lib/igt_dummyload.c
> @@ -0,0 +1,276 @@
> +/*
> + * 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 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.
> + */
> +
> +#define NSEC_PER_SEC 1000000000L
> +
> +#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 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;
> +}
> +
> +
> +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 {
> +		igt_require(gem_has_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, 4096);
> +	batch = gem_mmap__gtt(fd, handle, 4096, PROT_WRITE);
> +	gem_set_domain(fd, handle,
> +			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
> +
> +	if (nengine == 1 && dep_handle > 0) {
> +		/* dummy write to dependency */
> +		fill_object(&obj[buf_count], dep_handle, NULL, 0);
> +		buf_count++;
> +
> +		fill_reloc(&relocs[reloc_count], dep_handle, i,
> +			   I915_GEM_DOMAIN_RENDER,
> +			   I915_GEM_DOMAIN_RENDER);
> +		batch[i++] = 0; /* reloc */
> +		reloc_count++;
> +		batch[i++] = MI_NOOP;
> +	}
> +
> +	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:
> + * @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_post_spin_batch() for post-processing.
> + *
> + * Returns:
> + * Structure with helper internal state for igt_post_spin_batch().
> + */
> +igt_spin_t igt_spin_batch(int fd, int64_t ns, int engine, unsigned dep_handle)
> +{
> +	timer_t timer;
> +	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);
> +
> +	if (ns < 1) {
> +		if (ns == 0) {
> +			*batch = MI_BATCH_BUFFER_END;
> +			__sync_synchronize();
> +			return (igt_spin_t){ handle, batch, 0};
> +		}
> +		return (igt_spin_t){ handle, batch, 0 };
> +	}
> +	timer = setup_batch_exit_timer(ns);
> +
> +	return (igt_spin_t){ handle, batch, timer };
> +}
> +
> +/**
> + * igt_post_spin_batch:
> + * @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_post_spin_batch(int fd, igt_spin_t arg)
> +{
> +	if (arg.handle == 0)
> +		return;
> +
> +	if (arg.timer > 0)
> +		timer_delete(arg.timer);
> +
> +	gem_close(fd, arg.handle);
> +	munmap(arg.batch, 4096);
> +}
> +
> +
> +/**
> + * 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(), 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(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_post_spin_batch(fd, spin);
> +}
> diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
> new file mode 100644
> index 0000000..79ead2c
> --- /dev/null
> +++ b/lib/igt_dummyload.h
> @@ -0,0 +1,42 @@
> +/*
> + * 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(int fd, int64_t ns, int engine, unsigned dep_handle);
> +
> +void igt_post_spin_batch(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.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* i-g-t dummyload/spin batch v5
@ 2016-11-11 17:41 Abdiel Janulgue
  2016-11-11 17:41 ` [PATCH i-g-t v5 1/4] lib: add igt_dummyload Abdiel Janulgue
                   ` (3 more replies)
  0 siblings, 4 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-11 17:41 UTC (permalink / raw)
  To: intel-gfx

v5: Add kms_busy to satisfy rule of 3.

- Abdiel

[PATCH 1/4] lib: add igt_dummyload
[PATCH 2/4] igt/gem_wait: Use new igt_spin_batch
[PATCH 3/4] igt/kms_flip: Use new igt_spin_batch
[PATCH 4/4] igt/kms_busy.c: Use new igt_spin_batch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH i-g-t v5 1/4] lib: add igt_dummyload
  2016-11-11 17:41 i-g-t dummyload/spin batch v5 Abdiel Janulgue
@ 2016-11-11 17:41 ` Abdiel Janulgue
  2016-11-11 16:16   ` Daniel Vetter
  2016-11-11 17:41 ` [PATCH i-g-t v5 2/4] igt/gem_wait: " Abdiel Janulgue
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-11 17:41 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

Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
 lib/Makefile.sources |   2 +
 lib/igt.h            |   1 +
 lib/igt_dummyload.c  | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_dummyload.h  |  42 ++++++++
 4 files changed, 321 insertions(+)
 create mode 100644 lib/igt_dummyload.c
 create mode 100644 lib/igt_dummyload.h

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..b934fd5
--- /dev/null
+++ b/lib/igt_dummyload.c
@@ -0,0 +1,276 @@
+/*
+ * 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 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.
+ */
+
+#define NSEC_PER_SEC 1000000000L
+
+#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 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;
+}
+
+
+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 {
+		igt_require(gem_has_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, 4096);
+	batch = gem_mmap__gtt(fd, handle, 4096, PROT_WRITE);
+	gem_set_domain(fd, handle,
+			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+	if (nengine == 1 && dep_handle > 0) {
+		/* dummy write to dependency */
+		fill_object(&obj[buf_count], dep_handle, NULL, 0);
+		buf_count++;
+
+		fill_reloc(&relocs[reloc_count], dep_handle, i,
+			   I915_GEM_DOMAIN_RENDER,
+			   I915_GEM_DOMAIN_RENDER);
+		batch[i++] = 0; /* reloc */
+		reloc_count++;
+		batch[i++] = MI_NOOP;
+	}
+
+	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:
+ * @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_post_spin_batch() for post-processing.
+ *
+ * Returns:
+ * Structure with helper internal state for igt_post_spin_batch().
+ */
+igt_spin_t igt_spin_batch(int fd, int64_t ns, int engine, unsigned dep_handle)
+{
+	timer_t timer;
+	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);
+
+	if (ns < 1) {
+		if (ns == 0) {
+			*batch = MI_BATCH_BUFFER_END;
+			__sync_synchronize();
+			return (igt_spin_t){ handle, batch, 0};
+		}
+		return (igt_spin_t){ handle, batch, 0 };
+	}
+	timer = setup_batch_exit_timer(ns);
+
+	return (igt_spin_t){ handle, batch, timer };
+}
+
+/**
+ * igt_post_spin_batch:
+ * @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_post_spin_batch(int fd, igt_spin_t arg)
+{
+	if (arg.handle == 0)
+		return;
+
+	if (arg.timer > 0)
+		timer_delete(arg.timer);
+
+	gem_close(fd, arg.handle);
+	munmap(arg.batch, 4096);
+}
+
+
+/**
+ * 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(), 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(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_post_spin_batch(fd, spin);
+}
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
new file mode 100644
index 0000000..79ead2c
--- /dev/null
+++ b/lib/igt_dummyload.h
@@ -0,0 +1,42 @@
+/*
+ * 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(int fd, int64_t ns, int engine, unsigned dep_handle);
+
+void igt_post_spin_batch(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.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH i-g-t v5 2/4] igt/gem_wait: Use new igt_spin_batch
  2016-11-11 17:41 i-g-t dummyload/spin batch v5 Abdiel Janulgue
  2016-11-11 17:41 ` [PATCH i-g-t v5 1/4] lib: add igt_dummyload Abdiel Janulgue
@ 2016-11-11 17:41 ` Abdiel Janulgue
  2016-11-11 17:41 ` [PATCH i-g-t v5 3/4] igt/kms_flip: " Abdiel Janulgue
  2016-11-11 17:41 ` [PATCH i-g-t v5 4/4] igt/kms_busy.c: " Abdiel Janulgue
  3 siblings, 0 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-11 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

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 | 125 ++++---------------------------------------------------
 1 file changed, 7 insertions(+), 118 deletions(-)

diff --git a/tests/gem_wait.c b/tests/gem_wait.c
index b4127de..785bb14 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,14 +63,6 @@ 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)
@@ -91,113 +71,26 @@ static void sigiter(int sig, siginfo_t *info, void *arg)
 #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(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 +108,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_post_spin_batch(fd, spin);
 }
 
 igt_main
-- 
2.7.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH i-g-t v5 3/4] igt/kms_flip: Use new igt_spin_batch
  2016-11-11 17:41 i-g-t dummyload/spin batch v5 Abdiel Janulgue
  2016-11-11 17:41 ` [PATCH i-g-t v5 1/4] lib: add igt_dummyload Abdiel Janulgue
  2016-11-11 17:41 ` [PATCH i-g-t v5 2/4] igt/gem_wait: " Abdiel Janulgue
@ 2016-11-11 17:41 ` Abdiel Janulgue
  2016-11-11 17:41 ` [PATCH i-g-t v5 4/4] igt/kms_busy.c: " Abdiel Janulgue
  3 siblings, 0 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-11 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

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 | 185 ++-----------------------------------------------------
 1 file changed, 4 insertions(+), 181 deletions(-)

diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index 2a9fe2e..79cb783 100644
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -191,109 +191,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 +235,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 +695,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.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH i-g-t v5 4/4] igt/kms_busy.c: Use new igt_spin_batch
  2016-11-11 17:41 i-g-t dummyload/spin batch v5 Abdiel Janulgue
                   ` (2 preceding siblings ...)
  2016-11-11 17:41 ` [PATCH i-g-t v5 3/4] igt/kms_flip: " Abdiel Janulgue
@ 2016-11-11 17:41 ` Abdiel Janulgue
  3 siblings, 0 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-11 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

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..d0fe412 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(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_post_spin_batch(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.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* (no subject)
  2016-11-11 16:16   ` Daniel Vetter
@ 2016-11-14 18:24     ` Abdiel Janulgue
  2016-11-14 18:24       ` [i-g-t PATCH v6 1/4] lib: add igt_dummyload Abdiel Janulgue
                         ` (3 more replies)
  0 siblings, 4 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-14 18:24 UTC (permalink / raw)
  To: intel-gfx

On 11.11.2016 18:16, Daniel Vetter wrote:
> On Fri, Nov 11, 2016 at 07:41:10PM +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
>>
>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
>> ---
>>  lib/Makefile.sources |   2 +
>>  lib/igt.h            |   1 +
>>  lib/igt_dummyload.c  | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  lib/igt_dummyload.h  |  42 ++++++++
> 
> Did you check that your new docs do show up in the generated
> documentation? Iirc you need to edit some xml under docs/.
> -Daniel
> 

Yeah I missed that. Updated now to include the docs in generated
documentation.


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [i-g-t PATCH v6 1/4] lib: add igt_dummyload
  2016-11-14 18:24     ` (no subject) Abdiel Janulgue
@ 2016-11-14 18:24       ` Abdiel Janulgue
  2016-11-15 10:59         ` Tomeu Vizoso
  2016-11-14 18:24       ` [i-g-t PATCH v6 2/4] igt/gem_wait: Use new igt_spin_batch Abdiel Janulgue
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-14 18:24 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

Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
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                                | 276 +++++++++++++++++++++
 lib/igt_dummyload.h                                |  42 ++++
 5 files changed, 322 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..b934fd5
--- /dev/null
+++ b/lib/igt_dummyload.c
@@ -0,0 +1,276 @@
+/*
+ * 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 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.
+ */
+
+#define NSEC_PER_SEC 1000000000L
+
+#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 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;
+}
+
+
+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 {
+		igt_require(gem_has_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, 4096);
+	batch = gem_mmap__gtt(fd, handle, 4096, PROT_WRITE);
+	gem_set_domain(fd, handle,
+			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+	if (nengine == 1 && dep_handle > 0) {
+		/* dummy write to dependency */
+		fill_object(&obj[buf_count], dep_handle, NULL, 0);
+		buf_count++;
+
+		fill_reloc(&relocs[reloc_count], dep_handle, i,
+			   I915_GEM_DOMAIN_RENDER,
+			   I915_GEM_DOMAIN_RENDER);
+		batch[i++] = 0; /* reloc */
+		reloc_count++;
+		batch[i++] = MI_NOOP;
+	}
+
+	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:
+ * @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_post_spin_batch() for post-processing.
+ *
+ * Returns:
+ * Structure with helper internal state for igt_post_spin_batch().
+ */
+igt_spin_t igt_spin_batch(int fd, int64_t ns, int engine, unsigned dep_handle)
+{
+	timer_t timer;
+	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);
+
+	if (ns < 1) {
+		if (ns == 0) {
+			*batch = MI_BATCH_BUFFER_END;
+			__sync_synchronize();
+			return (igt_spin_t){ handle, batch, 0};
+		}
+		return (igt_spin_t){ handle, batch, 0 };
+	}
+	timer = setup_batch_exit_timer(ns);
+
+	return (igt_spin_t){ handle, batch, timer };
+}
+
+/**
+ * igt_post_spin_batch:
+ * @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_post_spin_batch(int fd, igt_spin_t arg)
+{
+	if (arg.handle == 0)
+		return;
+
+	if (arg.timer > 0)
+		timer_delete(arg.timer);
+
+	gem_close(fd, arg.handle);
+	munmap(arg.batch, 4096);
+}
+
+
+/**
+ * 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(), 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(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_post_spin_batch(fd, spin);
+}
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
new file mode 100644
index 0000000..79ead2c
--- /dev/null
+++ b/lib/igt_dummyload.h
@@ -0,0 +1,42 @@
+/*
+ * 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(int fd, int64_t ns, int engine, unsigned dep_handle);
+
+void igt_post_spin_batch(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] 39+ messages in thread

* [i-g-t PATCH v6 2/4] igt/gem_wait: Use new igt_spin_batch
  2016-11-14 18:24     ` (no subject) Abdiel Janulgue
  2016-11-14 18:24       ` [i-g-t PATCH v6 1/4] lib: add igt_dummyload Abdiel Janulgue
@ 2016-11-14 18:24       ` Abdiel Janulgue
  2016-11-14 18:24       ` [i-g-t PATCH v6 3/4] igt/kms_flip: " Abdiel Janulgue
  2016-11-14 18:24       ` [i-g-t PATCH v6 4/4] igt/kms_busy.c: " Abdiel Janulgue
  3 siblings, 0 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-14 18:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

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 | 125 ++++---------------------------------------------------
 1 file changed, 7 insertions(+), 118 deletions(-)

diff --git a/tests/gem_wait.c b/tests/gem_wait.c
index b4127de..785bb14 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,14 +63,6 @@ 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)
@@ -91,113 +71,26 @@ static void sigiter(int sig, siginfo_t *info, void *arg)
 #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(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 +108,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_post_spin_batch(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] 39+ messages in thread

* [i-g-t PATCH v6 3/4] igt/kms_flip: Use new igt_spin_batch
  2016-11-14 18:24     ` (no subject) Abdiel Janulgue
  2016-11-14 18:24       ` [i-g-t PATCH v6 1/4] lib: add igt_dummyload Abdiel Janulgue
  2016-11-14 18:24       ` [i-g-t PATCH v6 2/4] igt/gem_wait: Use new igt_spin_batch Abdiel Janulgue
@ 2016-11-14 18:24       ` Abdiel Janulgue
  2016-11-14 18:24       ` [i-g-t PATCH v6 4/4] igt/kms_busy.c: " Abdiel Janulgue
  3 siblings, 0 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-14 18:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

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 | 185 ++-----------------------------------------------------
 1 file changed, 4 insertions(+), 181 deletions(-)

diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index 2a9fe2e..79cb783 100644
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -191,109 +191,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 +235,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 +695,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] 39+ messages in thread

* [i-g-t PATCH v6 4/4] igt/kms_busy.c: Use new igt_spin_batch
  2016-11-14 18:24     ` (no subject) Abdiel Janulgue
                         ` (2 preceding siblings ...)
  2016-11-14 18:24       ` [i-g-t PATCH v6 3/4] igt/kms_flip: " Abdiel Janulgue
@ 2016-11-14 18:24       ` Abdiel Janulgue
  2016-11-15  8:45         ` Tomeu Vizoso
  3 siblings, 1 reply; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-14 18:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

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..d0fe412 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(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_post_spin_batch(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] 39+ messages in thread

* Re: [i-g-t PATCH v6 4/4] igt/kms_busy.c: Use new igt_spin_batch
  2016-11-14 18:24       ` [i-g-t PATCH v6 4/4] igt/kms_busy.c: " Abdiel Janulgue
@ 2016-11-15  8:45         ` Tomeu Vizoso
  2016-11-15 13:19           ` Abdiel Janulgue
  0 siblings, 1 reply; 39+ messages in thread
From: Tomeu Vizoso @ 2016-11-15  8:45 UTC (permalink / raw)
  To: Abdiel Janulgue; +Cc: Daniel Vetter, Intel Graphics Development

Hi Abdiel,

here running the whole of kms_busy causes all subtests after the first
one to be skipped due to:

Test requirement not met in function __real_main164, file
../../intel-gpu-tools/tests/kms_busy.c:195:
Test requirement: gem_has_ring(display.drm_fd, e->exec_id | e->flags)

If I run the subtests individually, the do get to run, so I guess
there's some issue with cleanup.

Btw, do you know why patchwork doesn't know about v6?

https://patchwork.freedesktop.org/series/15155/

I think it would be good to make sure that all commit messages contain
the why of the change, and a cover letter as the one generated by
git-send-email would be good to have, even if with very succinct
contents.

Thanks,

Tomeu

On 14 November 2016 at 19:24, Abdiel Janulgue
<abdiel.janulgue@linux.intel.com> wrote:
> 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..d0fe412 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(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_post_spin_batch(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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [i-g-t PATCH v6 1/4] lib: add igt_dummyload
  2016-11-14 18:24       ` [i-g-t PATCH v6 1/4] lib: add igt_dummyload Abdiel Janulgue
@ 2016-11-15 10:59         ` Tomeu Vizoso
  2016-11-15 11:08           ` Tomeu Vizoso
  2016-11-15 14:21           ` Abdiel Janulgue
  0 siblings, 2 replies; 39+ messages in thread
From: Tomeu Vizoso @ 2016-11-15 10:59 UTC (permalink / raw)
  To: Abdiel Janulgue; +Cc: Daniel Vetter, Intel Graphics Development

On 14 November 2016 at 19:24, Abdiel Janulgue
<abdiel.janulgue@linux.intel.com> 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
>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> 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                                | 276 +++++++++++++++++++++
>  lib/igt_dummyload.h                                |  42 ++++
>  5 files changed, 322 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..b934fd5
> --- /dev/null
> +++ b/lib/igt_dummyload.c
> @@ -0,0 +1,276 @@
> +/*
> + * 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 overtly long runtimes on some fast/slow platforms.

s/overtly/overly

> + * This library contains functionality to submit GPU workloads that should
> + * consume exactly a specific amount of time.
> + */
> +
> +#define NSEC_PER_SEC 1000000000L

Time to put this in a header in lib? With this series applied we would
have 7 separate definitions.

> +#define gettid() syscall(__NR_gettid)
> +#define sigev_notify_thread_id _sigev_un._tid

Guess this should be fine as well to be in a single place because IGT
knows what it's doing regarding TIDs?

> +#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 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;
> +}
> +
> +
> +static uint32_t *batch;

Maybe add a comment explaining why a global is needed?

> +
> +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 {
> +               igt_require(gem_has_ring(fd, engine));

There's gem_require_ring.

> +               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, 4096);

May be worth defining a constant so we don't repeat the same hardcoded
value so many times?

> +       batch = gem_mmap__gtt(fd, handle, 4096, PROT_WRITE);

Would it make sense to assert that batch is empty just in case?

> +       gem_set_domain(fd, handle,
> +                       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
> +
> +       if (nengine == 1 && dep_handle > 0) {

What if there's a dependency and no specific engine is passed? If
that's invalid, then an assert might be good.

> +               /* dummy write to dependency */
> +               fill_object(&obj[buf_count], dep_handle, NULL, 0);
> +               buf_count++;
> +
> +               fill_reloc(&relocs[reloc_count], dep_handle, i,
> +                          I915_GEM_DOMAIN_RENDER,
> +                          I915_GEM_DOMAIN_RENDER);
> +               batch[i++] = 0; /* reloc */
> +               reloc_count++;
> +               batch[i++] = MI_NOOP;
> +       }
> +
> +       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:
> + * @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_post_spin_batch() for post-processing.
> + *
> + * Returns:
> + * Structure with helper internal state for igt_post_spin_batch().
> + */
> +igt_spin_t igt_spin_batch(int fd, int64_t ns, int engine, unsigned dep_handle)
> +{
> +       timer_t timer;
> +       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);
> +
> +       if (ns < 1) {
> +               if (ns == 0) {

This block can be one level higher, and then you can have a condition
for ns < 0, which will then match the function docs.

> +                       *batch = MI_BATCH_BUFFER_END;
> +                       __sync_synchronize();
> +                       return (igt_spin_t){ handle, batch, 0};
> +               }
> +               return (igt_spin_t){ handle, batch, 0 };
> +       }
> +       timer = setup_batch_exit_timer(ns);
> +
> +       return (igt_spin_t){ handle, batch, timer };
> +}
> +
> +/**
> + * igt_post_spin_batch:
> + * @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_post_spin_batch(int fd, igt_spin_t arg)
> +{
> +       if (arg.handle == 0)
> +               return;
> +
> +       if (arg.timer > 0)
> +               timer_delete(arg.timer);
> +
> +       gem_close(fd, arg.handle);
> +       munmap(arg.batch, 4096);
> +}
> +
> +
> +/**
> + * 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(), 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(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_post_spin_batch(fd, spin);
> +}
> diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
> new file mode 100644
> index 0000000..79ead2c
> --- /dev/null
> +++ b/lib/igt_dummyload.h
> @@ -0,0 +1,42 @@
> +/*
> + * 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(int fd, int64_t ns, int engine, unsigned dep_handle);
> +
> +void igt_post_spin_batch(int fd, igt_spin_t arg);
> +
> +void igt_spin_batch_wait(int fd, int64_t ns, int engine, unsigned dep_handle);

Sorry about the bikeshedding at v6, but just in case you like the
idea: what about calling these functions igt_spin_batch_new() and
igt_spin_batch_free() as in igt_pipe_crc_new and igt_pipe_crc_free? Or
_alloc and _free, as with intel_batchbuffer.

I'm saying this because the first time I read igt_post_spin_batch I
thought it was about posting the batchbuffer, and all the
post-processing seems to just be regular cleanup.

Also, are you completely sure that always the point where the
batchbuffer is created is also the point where it has to be started?
Otherwise, a separate _start function would give that flexibility and
the API may be a bit more explicit.

Regards,

Tomeu

> +
> +
> +#endif /* __IGT_DUMMYLOAD_H__ */
> --
> 2.7.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [i-g-t PATCH v6 1/4] lib: add igt_dummyload
  2016-11-15 10:59         ` Tomeu Vizoso
@ 2016-11-15 11:08           ` Tomeu Vizoso
  2016-11-15 14:21           ` Abdiel Janulgue
  1 sibling, 0 replies; 39+ messages in thread
From: Tomeu Vizoso @ 2016-11-15 11:08 UTC (permalink / raw)
  To: Abdiel Janulgue; +Cc: Daniel Vetter, Intel Graphics Development

On 15 November 2016 at 11:59, Tomeu Vizoso <tomeu@tomeuvizoso.net> wrote:
> On 14 November 2016 at 19:24, Abdiel Janulgue
> <abdiel.janulgue@linux.intel.com> 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
>>
>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> 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                                | 276 +++++++++++++++++++++
>>  lib/igt_dummyload.h                                |  42 ++++
>>  5 files changed, 322 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..b934fd5
>> --- /dev/null
>> +++ b/lib/igt_dummyload.c
>> @@ -0,0 +1,276 @@
>> +/*
>> + * 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 overtly long runtimes on some fast/slow platforms.
>
> s/overtly/overly
>
>> + * This library contains functionality to submit GPU workloads that should
>> + * consume exactly a specific amount of time.
>> + */
>> +
>> +#define NSEC_PER_SEC 1000000000L
>
> Time to put this in a header in lib? With this series applied we would
> have 7 separate definitions.
>
>> +#define gettid() syscall(__NR_gettid)
>> +#define sigev_notify_thread_id _sigev_un._tid
>
> Guess this should be fine as well to be in a single place because IGT
> knows what it's doing regarding TIDs?
>
>> +#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 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;
>> +}
>> +
>> +
>> +static uint32_t *batch;
>
> Maybe add a comment explaining why a global is needed?
>
>> +
>> +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 {
>> +               igt_require(gem_has_ring(fd, engine));
>
> There's gem_require_ring.
>
>> +               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, 4096);
>
> May be worth defining a constant so we don't repeat the same hardcoded
> value so many times?
>
>> +       batch = gem_mmap__gtt(fd, handle, 4096, PROT_WRITE);
>
> Would it make sense to assert that batch is empty just in case?
>
>> +       gem_set_domain(fd, handle,
>> +                       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
>> +
>> +       if (nengine == 1 && dep_handle > 0) {
>
> What if there's a dependency and no specific engine is passed? If
> that's invalid, then an assert might be good.
>
>> +               /* dummy write to dependency */
>> +               fill_object(&obj[buf_count], dep_handle, NULL, 0);
>> +               buf_count++;
>> +
>> +               fill_reloc(&relocs[reloc_count], dep_handle, i,
>> +                          I915_GEM_DOMAIN_RENDER,
>> +                          I915_GEM_DOMAIN_RENDER);
>> +               batch[i++] = 0; /* reloc */
>> +               reloc_count++;
>> +               batch[i++] = MI_NOOP;
>> +       }
>> +
>> +       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:
>> + * @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_post_spin_batch() for post-processing.
>> + *
>> + * Returns:
>> + * Structure with helper internal state for igt_post_spin_batch().
>> + */
>> +igt_spin_t igt_spin_batch(int fd, int64_t ns, int engine, unsigned dep_handle)
>> +{
>> +       timer_t timer;
>> +       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);
>> +
>> +       if (ns < 1) {
>> +               if (ns == 0) {
>
> This block can be one level higher, and then you can have a condition
> for ns < 0, which will then match the function docs.
>
>> +                       *batch = MI_BATCH_BUFFER_END;
>> +                       __sync_synchronize();
>> +                       return (igt_spin_t){ handle, batch, 0};
>> +               }
>> +               return (igt_spin_t){ handle, batch, 0 };
>> +       }
>> +       timer = setup_batch_exit_timer(ns);
>> +
>> +       return (igt_spin_t){ handle, batch, timer };
>> +}
>> +
>> +/**
>> + * igt_post_spin_batch:
>> + * @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_post_spin_batch(int fd, igt_spin_t arg)
>> +{
>> +       if (arg.handle == 0)
>> +               return;
>> +
>> +       if (arg.timer > 0)
>> +               timer_delete(arg.timer);
>> +
>> +       gem_close(fd, arg.handle);
>> +       munmap(arg.batch, 4096);
>> +}
>> +
>> +
>> +/**
>> + * 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(), 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(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_post_spin_batch(fd, spin);
>> +}
>> diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
>> new file mode 100644
>> index 0000000..79ead2c
>> --- /dev/null
>> +++ b/lib/igt_dummyload.h
>> @@ -0,0 +1,42 @@
>> +/*
>> + * 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(int fd, int64_t ns, int engine, unsigned dep_handle);
>> +
>> +void igt_post_spin_batch(int fd, igt_spin_t arg);
>> +
>> +void igt_spin_batch_wait(int fd, int64_t ns, int engine, unsigned dep_handle);
>
> Sorry about the bikeshedding at v6, but just in case you like the
> idea: what about calling these functions igt_spin_batch_new() and
> igt_spin_batch_free() as in igt_pipe_crc_new and igt_pipe_crc_free? Or
> _alloc and _free, as with intel_batchbuffer.

Forgot to suggest returning a pointer to a new igt_spin_t struct in
_new() and freeing it in _free(), also because that's what will be
less surprising to people reading the code.

Regards,

Tomeu

> I'm saying this because the first time I read igt_post_spin_batch I
> thought it was about posting the batchbuffer, and all the
> post-processing seems to just be regular cleanup.
>
> Also, are you completely sure that always the point where the
> batchbuffer is created is also the point where it has to be started?
> Otherwise, a separate _start function would give that flexibility and
> the API may be a bit more explicit.
>
> Regards,
>
> Tomeu
>
>> +
>> +
>> +#endif /* __IGT_DUMMYLOAD_H__ */
>> --
>> 2.7.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [i-g-t PATCH v6 4/4] igt/kms_busy.c: Use new igt_spin_batch
  2016-11-15  8:45         ` Tomeu Vizoso
@ 2016-11-15 13:19           ` Abdiel Janulgue
  0 siblings, 0 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-15 13:19 UTC (permalink / raw)
  To: Tomeu Vizoso; +Cc: Daniel Vetter, Intel Graphics Development

Hi

On 15.11.2016 10:45, Tomeu Vizoso wrote:
> Hi Abdiel,
> 
> here running the whole of kms_busy causes all subtests after the first
> one to be skipped due to:
> 
> Test requirement not met in function __real_main164, file
> ../../intel-gpu-tools/tests/kms_busy.c:195:
> Test requirement: gem_has_ring(display.drm_fd, e->exec_id | e->flags)
> 
> If I run the subtests individually, the do get to run, so I guess
> there's some issue with cleanup.

The recursive batch with dependency bo works fine with BDW, SKL and up.
It's broken on HSW :( Found the problem, sending a fix soon.

Thanks for taking time to review this!

> 
> Btw, do you know why patchwork doesn't know about v6?
> 
> https://patchwork.freedesktop.org/series/15155/
> 
> I think it would be good to make sure that all commit messages contain
> the why of the change, and a cover letter as the one generated by
> git-send-email would be good to have, even if with very succinct
> contents.

Forgot to include the subject in git-send-email. Sorry about that...

> 
> Thanks,
> 
> Tomeu
> 
> On 14 November 2016 at 19:24, Abdiel Janulgue
> <abdiel.janulgue@linux.intel.com> wrote:
>> 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..d0fe412 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(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_post_spin_batch(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
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [i-g-t PATCH v6 1/4] lib: add igt_dummyload
  2016-11-15 10:59         ` Tomeu Vizoso
  2016-11-15 11:08           ` Tomeu Vizoso
@ 2016-11-15 14:21           ` Abdiel Janulgue
  1 sibling, 0 replies; 39+ messages in thread
From: Abdiel Janulgue @ 2016-11-15 14:21 UTC (permalink / raw)
  To: Tomeu Vizoso; +Cc: Daniel Vetter, Intel Graphics Development



On 15.11.2016 12:59, Tomeu Vizoso wrote:
> On 14 November 2016 at 19:24, Abdiel Janulgue
> <abdiel.janulgue@linux.intel.com> 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
>>
>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> 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                                | 276 +++++++++++++++++++++
>>  lib/igt_dummyload.h                                |  42 ++++
>>  5 files changed, 322 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..b934fd5
>> --- /dev/null
>> +++ b/lib/igt_dummyload.c
>> @@ -0,0 +1,276 @@
>> +/*
>> + * 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 overtly long runtimes on some fast/slow platforms.
> 
> s/overtly/overly
> 
>> + * This library contains functionality to submit GPU workloads that should
>> + * consume exactly a specific amount of time.
>> + */
>> +
>> +#define NSEC_PER_SEC 1000000000L
> 
> Time to put this in a header in lib? With this series applied we would
> have 7 separate definitions.
> 
>> +#define gettid() syscall(__NR_gettid)
>> +#define sigev_notify_thread_id _sigev_un._tid
> 
> Guess this should be fine as well to be in a single place because IGT
> knows what it's doing regarding TIDs?
> 
>> +#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 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;
>> +}
>> +
>> +
>> +static uint32_t *batch;
> 
> Maybe add a comment explaining why a global is needed?
> 
>> +
>> +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 {
>> +               igt_require(gem_has_ring(fd, engine));
> 
> There's gem_require_ring.
> 
>> +               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, 4096);
> 
> May be worth defining a constant so we don't repeat the same hardcoded
> value so many times?
> 
>> +       batch = gem_mmap__gtt(fd, handle, 4096, PROT_WRITE);
> 
> Would it make sense to assert that batch is empty just in case?
> 
>> +       gem_set_domain(fd, handle,
>> +                       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
>> +
>> +       if (nengine == 1 && dep_handle > 0) {
> 
> What if there's a dependency and no specific engine is passed? If
> that's invalid, then an assert might be good.
> 
>> +               /* dummy write to dependency */
>> +               fill_object(&obj[buf_count], dep_handle, NULL, 0);
>> +               buf_count++;
>> +
>> +               fill_reloc(&relocs[reloc_count], dep_handle, i,
>> +                          I915_GEM_DOMAIN_RENDER,
>> +                          I915_GEM_DOMAIN_RENDER);
>> +               batch[i++] = 0; /* reloc */
>> +               reloc_count++;
>> +               batch[i++] = MI_NOOP;
>> +       }
>> +
>> +       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:
>> + * @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_post_spin_batch() for post-processing.
>> + *
>> + * Returns:
>> + * Structure with helper internal state for igt_post_spin_batch().
>> + */
>> +igt_spin_t igt_spin_batch(int fd, int64_t ns, int engine, unsigned dep_handle)
>> +{
>> +       timer_t timer;
>> +       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);
>> +
>> +       if (ns < 1) {
>> +               if (ns == 0) {
> 
> This block can be one level higher, and then you can have a condition
> for ns < 0, which will then match the function docs.
> 
>> +                       *batch = MI_BATCH_BUFFER_END;
>> +                       __sync_synchronize();
>> +                       return (igt_spin_t){ handle, batch, 0};
>> +               }
>> +               return (igt_spin_t){ handle, batch, 0 };
>> +       }
>> +       timer = setup_batch_exit_timer(ns);
>> +
>> +       return (igt_spin_t){ handle, batch, timer };
>> +}
>> +
>> +/**
>> + * igt_post_spin_batch:
>> + * @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_post_spin_batch(int fd, igt_spin_t arg)
>> +{
>> +       if (arg.handle == 0)
>> +               return;
>> +
>> +       if (arg.timer > 0)
>> +               timer_delete(arg.timer);
>> +
>> +       gem_close(fd, arg.handle);
>> +       munmap(arg.batch, 4096);
>> +}
>> +
>> +
>> +/**
>> + * 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(), 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(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_post_spin_batch(fd, spin);
>> +}
>> diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
>> new file mode 100644
>> index 0000000..79ead2c
>> --- /dev/null
>> +++ b/lib/igt_dummyload.h
>> @@ -0,0 +1,42 @@
>> +/*
>> + * 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(int fd, int64_t ns, int engine, unsigned dep_handle);
>> +
>> +void igt_post_spin_batch(int fd, igt_spin_t arg);
>> +
>> +void igt_spin_batch_wait(int fd, int64_t ns, int engine, unsigned dep_handle);
> 
> Sorry about the bikeshedding at v6, but just in case you like the
> idea: what about calling these functions igt_spin_batch_new() and
> igt_spin_batch_free() as in igt_pipe_crc_new and igt_pipe_crc_free? Or
> _alloc and _free, as with intel_batchbuffer.
> 
> I'm saying this because the first time I read igt_post_spin_batch I
> thought it was about posting the batchbuffer, and all the
> post-processing seems to just be regular cleanup.

The api was patterned after igt_hang_ring and igt_post_hang_ring. The
post_hang in that aforementioned test case also does janitorial tasks.
But in any case, I don't mind postfixing this to _new and _free

> Also, are you completely sure that always the point where the
> batchbuffer is created is also the point where it has to be started?

I don't see any reason why not? igt_spin_batch asserts anyway when it
fails to make a recursive batch / the GPU is left in an idle state.

- Abdiel


> Otherwise, a separate _start function would give that flexibility and
> the API may be a bit more explicit.
> 
> Regards,
> 
> Tomeu
> 
>> +
>> +
>> +#endif /* __IGT_DUMMYLOAD_H__ */
>> --
>> 2.7.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2018-07-06 14:42 Christian König
  0 siblings, 0 replies; 39+ messages in thread
From: Christian König @ 2018-07-06 14:42 UTC (permalink / raw)
  To: intel-gfx

Next try of prework for unpinned DMA-buf operation.

Only send to intel-gfx to trigger unit tests on the following patches.

Christian.

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2018-07-05 10:38 rosdi ablatiff
  0 siblings, 0 replies; 39+ messages in thread
From: rosdi ablatiff @ 2018-07-05 10:38 UTC (permalink / raw)
  To: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #1.2: Type: text/html, Size: 1 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2017-01-16 16:28 Tony Whittam
  0 siblings, 0 replies; 39+ messages in thread
From: Tony Whittam @ 2017-01-16 16:28 UTC (permalink / raw)
  To: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2520 bytes --]

Hi everyone,

I don't know if this is too specialised for this list. Anyway, no harm in
asking the question :-)

*Preamble*
Build: Yocto from the Apollo Lake BSP release *gold, *
Hardware: Oxbow Hill Rev B CRB with Intel Atom E3950 and 4GB DDR3 RAM (one
SODIMM)
Build: core-image-sato-sdk
Installed on the onboard eMMC.
OpenCL: installed user space drivers from SRB4 https://software.intel.
com/file/533571/download

I'm currently evaluating the Apollo Lake platform as a candidate to run our
embedded application. We already have this application running on less
powerful ARM based Linux systems with Mali GPU using OpenCL 1.2. We're now
evaluating the E3950 as a faster alternative. To evaluate the application I
need OpenCL 1.2 or later.

To verify the OpenCL installation I have built and run the Intel demo apps:
CapsBasic and Bitonic Sort. CapsBasic sees two devices: CPU and GPU and
Bitonic sort can run its kernels correctly on both the CPU and the GPU.

*The issue*
Simply put, the application has

   - thread 1 (feeder): has a loop that feeds data into OpenCL and queues
   kernels
   - thread 2 (consumer): waits for results and reads output data.
   - an OpenCL Host command queue with out-of-order execution enabled

When I run my app and select the GPU OpenCL device, the feeder thread *stalls
inside a blocking call to clEnqueueMapBuffer(). *At this point only one
thing has been queued on the command queue: a buffer unmap command for a
different buffer. This unmap is waiting for an OpenCL event that will
indicate data ready to be processed.

In contrast, when I run my app and select the *CPU OpenCL *device, it works
perfectly.

Does anyone have any ideas on

   1. what might be causing this problem running with the GPU?
   2. how to debug this on the Yocto platform?

Best regards,

Tony

-- 
Tony Whittam
Rapt Touch

-- 
Confidentiality Notice: 

The information contained in this message, including any attachments 
hereto, may be confidential and is intended to be read only by the 
individual or entity to whom this message is addressed. If the reader of 
this message is not the intended recipient or an agent or designee of the 
intended recipient, please note that any review, use, disclosure or 
distribution of this message or its attachments, in any form, is strictly 
prohibited. If you have received this message in error, please immediately 
notify the sender and/or Rapt Touch Ltd via email at info@rapttouch.com and 
delete or destroy any copy of this message and its attachments.

[-- Attachment #1.2: Type: text/html, Size: 4121 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: (no subject)
  2015-06-17 11:04       ` Daniel Vetter
  2015-06-17 12:41         ` Jani Nikula
@ 2015-06-18 10:30         ` Dave Gordon
  1 sibling, 0 replies; 39+ messages in thread
From: Dave Gordon @ 2015-06-18 10:30 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On 17/06/15 12:04, Daniel Vetter wrote:
> On Fri, Jun 12, 2015 at 09:25:36PM +0100, Dave Gordon wrote:
>> Updated version split into two. The first tidies up the _ring_prepare()
>> functions and removes the corner case where we might have had to wait
>> twice; the second is a temporary workaround to solve a kernel OOPS that
>> can occur if logical_ring_begin is called while the ringbuffer is not
>> mapped because there's no current request.
>>
>> The latter will be superseded by the Anti-OLR patch series currently
>> in review. But this helps with GuC submission, which is better than
>> the execlist path at exposing the problematic case :(
> 
> Maintainer broken record: Lack of changelog makes it hard to figure out
> what changed and which patches are the latest version. Even more so when
> trying to catch up from vacation ...
> -Daniel

Oops, that wasn't ready to go to the mailing list, that was just
supposed to go to myself so I could test whether the changes I'd made to
my git-format-patch and git-send-email settings worked! Hence lack of
subject line :(

And the settings obviously /weren't/ right; apart from it going to the
list, it didn't have the proper "Organisation" header, which was the
thing I was trying to update, as well as setting up proper definitions
so I could write "git send-email --identity=external --to=myself ..."

I think I got them all sorted out before sending the GuC submission
sequence though :)

.Dave.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: (no subject)
  2015-06-17 11:04       ` Daniel Vetter
@ 2015-06-17 12:41         ` Jani Nikula
  2015-06-18 10:30         ` Dave Gordon
  1 sibling, 0 replies; 39+ messages in thread
From: Jani Nikula @ 2015-06-17 12:41 UTC (permalink / raw)
  To: Daniel Vetter, Dave Gordon; +Cc: intel-gfx

On Wed, 17 Jun 2015, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Fri, Jun 12, 2015 at 09:25:36PM +0100, Dave Gordon wrote:
>> Updated version split into two. The first tidies up the _ring_prepare()
>> functions and removes the corner case where we might have had to wait
>> twice; the second is a temporary workaround to solve a kernel OOPS that
>> can occur if logical_ring_begin is called while the ringbuffer is not
>> mapped because there's no current request.
>> 
>> The latter will be superseded by the Anti-OLR patch series currently
>> in review. But this helps with GuC submission, which is better than
>> the execlist path at exposing the problematic case :(
>
> Maintainer broken record: Lack of changelog makes it hard to figure out
> what changed and which patches are the latest version. Even more so when
> trying to catch up from vacation ...

Is it time we adopted Greg's <formletter> approach with copy-pasted
snippets from [1]...? See [2] for an example.

BR,
Jani.


[1] https://github.com/gregkh/gregkh-linux/blob/master/forms/patch_bot
[2] http://mid.gmane.org/20150612153842.GA12274@kroah.com

> -Daniel
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: (no subject)
  2015-06-12 20:25     ` (no subject) Dave Gordon
@ 2015-06-17 11:04       ` Daniel Vetter
  2015-06-17 12:41         ` Jani Nikula
  2015-06-18 10:30         ` Dave Gordon
  0 siblings, 2 replies; 39+ messages in thread
From: Daniel Vetter @ 2015-06-17 11:04 UTC (permalink / raw)
  To: Dave Gordon; +Cc: intel-gfx

On Fri, Jun 12, 2015 at 09:25:36PM +0100, Dave Gordon wrote:
> Updated version split into two. The first tidies up the _ring_prepare()
> functions and removes the corner case where we might have had to wait
> twice; the second is a temporary workaround to solve a kernel OOPS that
> can occur if logical_ring_begin is called while the ringbuffer is not
> mapped because there's no current request.
> 
> The latter will be superseded by the Anti-OLR patch series currently
> in review. But this helps with GuC submission, which is better than
> the execlist path at exposing the problematic case :(

Maintainer broken record: Lack of changelog makes it hard to figure out
what changed and which patches are the latest version. Even more so when
trying to catch up from vacation ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
  2015-06-12 17:09   ` [PATCH v2] Resolve issues with ringbuffer space management Dave Gordon
@ 2015-06-12 20:25     ` Dave Gordon
  2015-06-17 11:04       ` Daniel Vetter
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Gordon @ 2015-06-12 20:25 UTC (permalink / raw)
  To: intel-gfx

Updated version split into two. The first tidies up the _ring_prepare()
functions and removes the corner case where we might have had to wait
twice; the second is a temporary workaround to solve a kernel OOPS that
can occur if logical_ring_begin is called while the ringbuffer is not
mapped because there's no current request.

The latter will be superseded by the Anti-OLR patch series currently
in review. But this helps with GuC submission, which is better than
the execlist path at exposing the problematic case :(

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2015-04-14 10:10 Mika Kahola
  0 siblings, 0 replies; 39+ messages in thread
From: Mika Kahola @ 2015-04-14 10:10 UTC (permalink / raw)
  To: intel-gfx

This series is revised based on Jani's good comments.
In this series the patch which read out DP link training
parameters from VBT is discarded as based on the comments
that I received.

Files changed:
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
  2014-01-21 16:38 [PATCH] drm/i915: (VLV2) Fix the hotplug detection bits Todd Previte
@ 2014-01-23  4:22 ` Todd Previte
  0 siblings, 0 replies; 39+ messages in thread
From: Todd Previte @ 2014-01-23  4:22 UTC (permalink / raw)
  To: intel-gfx

Addresses the comments and feedback herein. VLV2 and gen4 have separate bit
definitions now. The correct bits are selected in gen4x_dp_detect() based on
the detected platform.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: (no subject)
  2013-12-30  2:29 Oravil Nair
@ 2014-01-07  7:32 ` Daniel Vetter
  0 siblings, 0 replies; 39+ messages in thread
From: Daniel Vetter @ 2014-01-07  7:32 UTC (permalink / raw)
  To: Oravil Nair; +Cc: intel-gfx

On Mon, Dec 30, 2013 at 07:59:49AM +0530, Oravil Nair wrote:
> Hi,
> 
> i915_gem_object_pin(), during i915 driver create, seems to write to the
> memory written by BIOS. Where can the start address be specified to
> allocate memory so that the memory written by BIOS is not overwritten at
> initialization?

I guess you want Jesse's patches to save the screen contents from the BIOS
modeset setup? But tbh I'm not clear at all what exactly you're talking
about.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2013-12-30  2:29 Oravil Nair
  2014-01-07  7:32 ` Daniel Vetter
  0 siblings, 1 reply; 39+ messages in thread
From: Oravil Nair @ 2013-12-30  2:29 UTC (permalink / raw)
  To: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 242 bytes --]

Hi,

i915_gem_object_pin(), during i915 driver create, seems to write to the
memory written by BIOS. Where can the start address be specified to
allocate memory so that the memory written by BIOS is not overwritten at
initialization?

Thanks

[-- Attachment #1.2: Type: text/html, Size: 331 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: (no subject)
       [not found] <CAEyVMbDjLwcDFrQ7y4UtGp7HOT1wi5MB2EWLGTuOdJCKDWsUew@mail.gmail.com>
@ 2013-04-03 15:46 ` Daniel Vetter
  0 siblings, 0 replies; 39+ messages in thread
From: Daniel Vetter @ 2013-04-03 15:46 UTC (permalink / raw)
  To: Dihan Wickremasuriya; +Cc: Michael Siracusa, intel-gfx, Jeff Faneuff


[-- Attachment #1.1: Type: text/plain, Size: 1354 bytes --]

Hi all,

Two things:
- Please _always_ include a public mailing list when reporting bugs, your
dear maintainer sometimes slacks off.
- We need to see the error_state before we can assess what kind of hang you
have (it's like gettting a SIGSEGV for a normal program, no two gpu hangs
are the same ...).

Cheers, Daniel

On Wed, Apr 3, 2013 at 5:42 PM, Dihan Wickremasuriya <
dwickremasuriya@rethinkrobotics.com> wrote:

> Hi Chris/Daniel,
>
> This is Dihan from Rethink Robotics and we were hoping you could help with
> the GPU hang problem in the i915 driver mentioned in bug #26345:
> https://bugs.freedesktop.org/show_bug.cgi?id=26345
>
> We are running into the same problem with the 3.8.5 kernel (which has the
> fix mentioned in comment #153 of the bug report) when running a Qt 5
> application in Gentoo. At times the entire X session would freeze. The
> x11-perf tests described in the bug report run without any issues though.
>
> Would you happen to know whether this is because of an issue in the driver
> that is not currently being addressed by the fix? I have attached the Xorg
> log, the dmesg output and i915_error_state from a hung session. Please let
> me know if you need any more info. Thanks in advance!
>
> Best regards,
> Dihan
>



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

[-- Attachment #1.2: Type: text/html, Size: 2095 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2012-07-19 20:00 Olivier Galibert
  0 siblings, 0 replies; 39+ messages in thread
From: Olivier Galibert @ 2012-07-19 20:00 UTC (permalink / raw)
  To: intel-gfx, mesa-dev

  Hi,

This is the second verion of the clipping/interpolation patches.

Main differences:
- I tried to take all of Paul's remarks into account
- I exploded the first patch in 4 independant ones
- I've added a patch to ensure that integers pass through unscathed

Patch 4/9 is (slightly) controversial.  There may be better ways to do
it, or at least more general ones.  But it's simple, it works, and it
allows to validate the other 8.  It's an easy one to revert if we
build an alternative.

Best,

  OG.
 
[PATCH 1/9] intel gen4-5: fix the vue view in the fs.
[PATCH 2/9] intel gen4-5: simplify the bfc copy in the sf.
[PATCH 3/9] intel gen4-5: fix GL_VERTEX_PROGRAM_TWO_SIDE selection.
[PATCH 4/9] intel gen4-5: Fix backface/frontface selection when one
[PATCH 5/9] intel gen4-5: Compute the interpolation status for every
[PATCH 6/9] intel gen4-5: Correctly setup the parameters in the sf.
[PATCH 7/9] intel gen4-5: Correctly handle flat vs. non-flat in the
[PATCH 8/9] intel gen4-5: Make noperspective clipping work.
[PATCH 9/9] intel gen4-5: Don't touch flatshaded values when

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2012-05-31 18:00 Muhammad Jamil
  0 siblings, 0 replies; 39+ messages in thread
From: Muhammad Jamil @ 2012-05-31 18:00 UTC (permalink / raw)
  To: e_wangi, intel-gfx, iswahyudiwardany, mail-noreply, sandyseteluk,
	irdiansyah27, afia_gra


Learn How to Make Money Online
http://3ftechnologies.com/http102dx-2.php?qohranknumber=245





__________________
  Why dont your juries hangmurderers?  Because theyre afraid the mans friends will shoot them inthe back, in the dark--and its just what they WOULD do. kaelah winfrith
Thu, 31 May 2012 19:00:33

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2012-04-12  0:55 Rodrigo Vivi
  0 siblings, 0 replies; 39+ messages in thread
From: Rodrigo Vivi @ 2012-04-12  0:55 UTC (permalink / raw)
  To: DRI Development; +Cc: Intel Graphics Development, Rodrigo Vivi

There are many bugs open on fd.o regarding missing modes that are supported on Windows and other closed source drivers.
>From EDID spec we can (might?) infer modes using GTF and CVT when monitor allows it trough range limited flag... obviously limiting by the range.
>From our code:
 * EDID spec says modes should be preferred in this order:
 * - preferred detailed mode
 * - other detailed modes from base block
 * - detailed modes from extension blocks
 * - CVT 3-byte code modes
 * - standard timing codes
 * - established timing codes
 * - modes inferred from GTF or CVT range information
 *
 * We get this pretty much right.

Not actually so right... We were inferring just using GTF... not CVT or even GTF2.
This patch not just add some common cvt modes but also allows some modes been inferred when using gtf2 as well.

Cheers,
Rodrigo.

>From 4b7a88d0d812583d850ca691d1ac491355230d11 Mon Sep 17 00:00:00 2001
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Date: Wed, 11 Apr 2012 15:36:31 -0300
Subject: [PATCH] drm/edid: Adding common CVT inferred modes when monitor
 allows range limited ones trough EDID.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/drm_edid.c       |   37 +++++++++++++-
 drivers/gpu/drm/drm_edid_modes.h |  101 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7ee7be1..3179572 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1020,17 +1020,50 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
 	return modes;
 }
 
+static int
+drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
+			struct detailed_timing *timing)
+{
+	int i, modes = 0;
+	struct drm_display_mode *newmode;
+	struct drm_device *dev = connector->dev;
+
+	for (i = 0; i < drm_num_cvt_inferred_modes; i++) {
+		if (mode_in_range(drm_cvt_inferred_modes + i, edid, timing)) {
+			newmode = drm_mode_duplicate(dev, &drm_cvt_inferred_modes[i]);
+			if (newmode) {
+				drm_mode_probed_add(connector, newmode);
+				modes++;
+			}
+		}
+	}
+
+	return modes;
+}
+
 static void
 do_inferred_modes(struct detailed_timing *timing, void *c)
 {
 	struct detailed_mode_closure *closure = c;
 	struct detailed_non_pixel *data = &timing->data.other_data;
-	int gtf = (closure->edid->features & DRM_EDID_FEATURE_DEFAULT_GTF);
+	int timing_level = standard_timing_level(closure->edid);
 
-	if (gtf && data->type == EDID_DETAIL_MONITOR_RANGE)
+	if (data->type == EDID_DETAIL_MONITOR_RANGE)
+	    switch (timing_level) {
+	    case LEVEL_DMT:
+		break;
+	    case LEVEL_GTF:
+	    case LEVEL_GTF2:
 		closure->modes += drm_gtf_modes_for_range(closure->connector,
 							  closure->edid,
 							  timing);
+		break;
+	    case LEVEL_CVT:
+		closure->modes += drm_cvt_modes_for_range(closure->connector,
+							  closure->edid,
+							  timing);
+		break;
+	    }
 }
 
 static int
diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
index a91ffb1..7e14a32 100644
--- a/drivers/gpu/drm/drm_edid_modes.h
+++ b/drivers/gpu/drm/drm_edid_modes.h
@@ -266,6 +266,107 @@ static const struct drm_display_mode drm_dmt_modes[] = {
 static const int drm_num_dmt_modes =
 	sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
 
+static const struct drm_display_mode drm_cvt_inferred_modes[] = {
+	/* 640x480@60Hz */
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 23750  640, 664,
+		   720, 800, 0, 480, 483, 487, 500, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 800x600@60Hz */
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 38250, 800, 832,
+		   912, 1024, 0, 600, 603, 607, 624, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 900x600@60Hz */
+	{ DRM_MODE("900x600", DRM_MODE_TYPE_DRIVER, 45250, 960, 992,
+		   1088, 1216, 0, 600, 603, 609, 624, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1024x576@60Hz */
+	{ DRM_MODE("1024x576", DRM_MODE_TYPE_DRIVER, 46500, 1024, 1064,
+		   1160, 1296, 0, 576, 579, 584, 599, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1024x768@60Hz */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 63500, 1024, 1072,
+		   1176, 1328, 0, 768, 771, 775, 798, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1152x864@60Hz */
+	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 81750, 1152, 1216,
+		   1336, 1520, 0, 864, 867, 871, 897, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x720@60Hz */
+	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74500, 1280, 1344,
+		   1472, 1664, 0, 720, 723, 728, 748, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x768@60Hz */
+	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
+		   1472, 1664, 0, 768, 771, 781, 798, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x800@60Hz */
+	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
+		   1480, 1680, 0, 800, 803, 809, 831, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x1024@60Hz */
+	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 109000, 1280, 1368,
+		   1496, 1712, 0, 1024, 1027, 1034, 1063, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1360x768@60Hz */
+	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 84750, 1360, 1432,
+		   1568, 1776, 0, 768, 771, 781, 798, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1366x768@60Hz */
+	{ DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 85250, 1368, 1440,
+		   1576, 1784, 0, 768, 771, 781, 798, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1440x900@60Hz */
+	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1528,
+		   1672, 1904, 0, 900, 903, 909, 934, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1400x1050@60Hz */
+	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
+		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1600x900@60Hz */
+	{ DRM_MODE("1600x900", DRM_MODE_TYPE_DRIVER, 118250, 1600, 1696,
+		   1856, 2112, 0, 900, 903, 908, 934, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1600x1200@60Hz */
+	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 161000, 1600, 1712,
+		   1880, 2160, 0, 1200, 1203, 1207, 1245, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1680x945@60Hz */
+	{ DRM_MODE("1680x945", DRM_MODE_TYPE_DRIVER, 130750, 1680, 1776,
+		   1952, 2224, 0, 945, 948, 953, 981, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1680x1050@60Hz */
+	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
+		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1920x1080@60Hz */
+	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 73000, 1920, 2048,
+		   2248, 2576, 0, 1080, 1083, 1088, 1120, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1920x1200@60Hz */
+	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
+		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1920x1440@60Hz */
+	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 233500, 1920, 2064,
+		   2264, 2608, 0, 1440, 1443, 1447, 1493, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2048x1152@60Hz */
+	{ DRM_MODE("2048x1152", DRM_MODE_TYPE_DRIVER, 197000, 2048, 2184,
+		   2400, 2752, 0, 1152, 1155, 1160, 1195, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2048x1536@60Hz */
+	{ DRM_MODE("2048x1536", DRM_MODE_TYPE_DRIVER, 272000, 2048, 2208,
+		   2424, 2800, 0, 1563, 1566, 1576, 1620, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 2560x1600@60Hz */
+	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2760,
+		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+};
+static const int drm_num_cvt_inferred_modes =
+	sizeof(drm_cvt_inferred_modes) / sizeof(struct drm_display_mode);
+
 static const struct drm_display_mode edid_est_modes[] = {
 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
 		   968, 1056, 0, 600, 601, 605, 628, 0,
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* (no subject)
@ 2012-04-08  2:26 Muhammad Jamil
  0 siblings, 0 replies; 39+ messages in thread
From: Muhammad Jamil @ 2012-04-08  2:26 UTC (permalink / raw)
  To: alia2426, intel-gfx, anggita_chaonk, embapoenya, support,
	semetgp, sandyseteluk


Make Income 0nline with revolutionary system
http://184.168.145.37/etdfgtim.php?pjtcamp=95

            Sun, 8 Apr 2012 3:25:59
______________
"Billy took his seat with the others around a golden oak table, with a microphone all his own." (c) jerald visszapattant

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2012-04-05  6:44 Muhammad Jamil
  0 siblings, 0 replies; 39+ messages in thread
From: Muhammad Jamil @ 2012-04-05  6:44 UTC (permalink / raw)
  To: intel-gfx, dianaoktavia81, ilham_syah, herman_suni,
	friends_confession, ashley_nn30, eddy_susanto96


Learn H0w T0 Earn M0ney 0nline N0w
http://residentialtreatmentcenter.net/coffegold.php?evynumber=91



            Thu, 5 Apr 2012 7:44:44
_________________________________
" You yell." (c) daelynn wulfgar

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2012-04-03 18:25 Muhammad Jamil
  0 siblings, 0 replies; 39+ messages in thread
From: Muhammad Jamil @ 2012-04-03 18:25 UTC (permalink / raw)
  To: embapoenya, intel-gfx, iswahyudiwardany, semetgp, support


[-- Attachment #1.1: Type: text/plain, Size: 109 bytes --]

http://www.signsandsites.com/wp-content/themes/duotone/nav21.php
Muhammad Jamil
Sumintar
4/3/2012 11:25:11 AM

[-- Attachment #1.2: Type: text/html, Size: 366 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2012-04-03 12:42 Muhammad Jamil
  0 siblings, 0 replies; 39+ messages in thread
From: Muhammad Jamil @ 2012-04-03 12:42 UTC (permalink / raw)
  To: rahman_lyk, ivoximoet, psamawa, friends_confession, cute_mommy77,
	intel-gfx, irdiansyah27


W0rking fr0m h0me Ieads t0 sh0cking m0ney resuIts!
http://jadehurtz.com/coffeemoney.php?apohgoto=64



            Tue, 3 Apr 2012 13:42:09
______________
"  So Tom took his goods out himself, and soughtemployers for Bert who did not know of this strain of poetry inhis nature" (c) britin wynton

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
  2011-04-14 18:13 forcewake v4 (now with spinlock) Ben Widawsky
@ 2011-04-14 18:13 ` Ben Widawsky
  0 siblings, 0 replies; 39+ messages in thread
From: Ben Widawsky @ 2011-04-14 18:13 UTC (permalink / raw)
  To: intel-gfx

GIT: [Intel-gfx] [PATCH 1/3] drm/i915: proper use of forcewake
GIT: [Intel-gfx] [PATCH 2/3] drm/i915: refcounts for forcewake
GIT: [Intel-gfx] [PATCH 3/3] drm/i915: userspace interface to the forcewake refcount

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
  2011-04-09 20:26 ` forcewake junk, part2 Ben Widawsky
@ 2011-04-09 20:26   ` Ben Widawsky
  0 siblings, 0 replies; 39+ messages in thread
From: Ben Widawsky @ 2011-04-09 20:26 UTC (permalink / raw)
  To: intel-gfx

GIT: [Intel-gfx] [PATCH 1/4] drm/i915: proper use of forcewake
GIT: [Intel-gfx] [PATCH 2/4] drm/i915: refcounts for forcewake
GIT: [Intel-gfx] [PATCH 3/4] drm/i915: userspace interface to the forcewake refcount
GIT: [Intel-gfx] [PATCH 4/4] drm/i915: optional fewer warning patch

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
@ 2011-04-07 21:32 Jesse Barnes
  0 siblings, 0 replies; 39+ messages in thread
From: Jesse Barnes @ 2011-04-07 21:32 UTC (permalink / raw)
  To: intel-gfx

These are some prep patches I'd like to get feedback on.  I've only
compile tested them so far (the actual hw support code this is for was
tested before the split), so testing would be appreciated as well.

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 39+ messages in thread

* (no subject)
  2010-11-10 18:47         ` Jesse Barnes
@ 2010-11-17 22:52           ` Thantry, Hariharan L
  0 siblings, 0 replies; 39+ messages in thread
From: Thantry, Hariharan L @ 2010-11-17 22:52 UTC (permalink / raw)
  To: intel-gfx

Hi folks,

I am a bit new to graphics, but had a few questions that I was hoping that someone could answer for me. I hope this is the right forum to ask these questions.
My interest is in seeing whether I can use the Intel integrated graphics part for non-graphics (GPGPU) work, while driving the display through another discrete card.
I have an Ironlake system (core setup with base Debian (no X-related packages), a basic PCI-E graphics card (NVIDIA NV37GL) and a 2.6.36 kernel with the following relevant config entries. 


CONFIG_AGP=y
CONFIG_AGP_AMD64=y
CONFIG_AGP_INTEL=y
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_VGA_SWITCHEROO is not set
CONFIG_DRM=m
CONFIG_DRM_KMS_HELPER=m
CONFIG_DRM_TTM=m
CONFIG_DRM_R128=m
CONFIG_DRM_I810=m
CONFIG_DRM_I830=m
CONFIG_DRM_I915=m
CONFIG_DRM_I915_KMS=y

I have libdrm & libva installed, and was hoping to use libdrm APIs to do some basic operations on the integrated graphics.

I can insmod the DRM & the DRM_KMS_HELPER module fine, but when trying to insert the I915 driver, I get a "no such device error", even though the module object exists.

lspci doesn't seem to return the Intel integrated graphics PCI device either.


00:00.0 Host bridge: Intel Corporation Auburndale/Havendale DRAM Controller (rev 02)
00:01.0 PCI bridge: Intel Corporation Auburndale/Havendale PCI Express x16 Root Port (rev 02)
00:16.0 Communication controller: Intel Corporation Ibex Peak HECI Controller (rev 06)
00:16.2 IDE interface: Intel Corporation Ibex Peak PT IDER Controller (rev 06)
00:16.3 Serial controller: Intel Corporation Ibex Peak KT Controller (rev 06)
00:19.0 Ethernet controller: Intel Corporation Device 10f0 (rev 06)
00:1a.0 USB Controller: Intel Corporation Ibex Peak USB2 Enhanced Host Controller (rev 06)
00:1b.0 Audio device: Intel Corporation Ibex Peak High Definition Audio (rev 06)
00:1d.0 USB Controller: Intel Corporation Ibex Peak USB2 Enhanced Host Controller (rev 06)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev a6)
00:1f.0 ISA bridge: Intel Corporation Ibex Peak LPC Interface Controller (rev 06)
00:1f.2 SATA controller: Intel Corporation Ibex Peak 6 port SATA AHCI Controller (rev 06)
00:1f.3 SMBus: Intel Corporation Ibex Peak SMBus Controller (rev 06)
01:00.0 VGA compatible controller: nVidia Corporation NV37GL [Quadro PCI-E Series] (rev a2)
02:02.0 Ethernet controller: Intel Corporation 82557/8/9/0/1 Ethernet Pro 100 (rev 08)

First off, is there a way for the Intel integrated graphics to appear in the list of PCI devices when it's not being used for driving the display?
Secondly, can I simply use the libdrm APIs to directly perform operations on the Intel integrated part? Does there exist any documentation describing the DRM APIs?
Finally, can I use the DRM APIs for using the GPU "media pipe" (architecturally different from the 3D graphics pipe)?

Thanks,
Hari

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2018-07-06 14:42 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-11 17:41 i-g-t dummyload/spin batch v5 Abdiel Janulgue
2016-11-11 17:41 ` [PATCH i-g-t v5 1/4] lib: add igt_dummyload Abdiel Janulgue
2016-11-11 16:16   ` Daniel Vetter
2016-11-14 18:24     ` (no subject) Abdiel Janulgue
2016-11-14 18:24       ` [i-g-t PATCH v6 1/4] lib: add igt_dummyload Abdiel Janulgue
2016-11-15 10:59         ` Tomeu Vizoso
2016-11-15 11:08           ` Tomeu Vizoso
2016-11-15 14:21           ` Abdiel Janulgue
2016-11-14 18:24       ` [i-g-t PATCH v6 2/4] igt/gem_wait: Use new igt_spin_batch Abdiel Janulgue
2016-11-14 18:24       ` [i-g-t PATCH v6 3/4] igt/kms_flip: " Abdiel Janulgue
2016-11-14 18:24       ` [i-g-t PATCH v6 4/4] igt/kms_busy.c: " Abdiel Janulgue
2016-11-15  8:45         ` Tomeu Vizoso
2016-11-15 13:19           ` Abdiel Janulgue
2016-11-11 17:41 ` [PATCH i-g-t v5 2/4] igt/gem_wait: " Abdiel Janulgue
2016-11-11 17:41 ` [PATCH i-g-t v5 3/4] igt/kms_flip: " Abdiel Janulgue
2016-11-11 17:41 ` [PATCH i-g-t v5 4/4] igt/kms_busy.c: " Abdiel Janulgue
  -- strict thread matches above, loose matches on Subject: below --
2018-07-06 14:42 (no subject) Christian König
2018-07-05 10:38 rosdi ablatiff
2017-01-16 16:28 Tony Whittam
2015-06-12 17:09 [PATCH 2/2] drm/i915: Rework order of operations in {__intel, logical}_ring_prepare() Dave Gordon
     [not found] ` <1433789441-8295-1-git-send-email-david.s.gordon@intel.com>
2015-06-12 17:09   ` [PATCH v2] Resolve issues with ringbuffer space management Dave Gordon
2015-06-12 20:25     ` (no subject) Dave Gordon
2015-06-17 11:04       ` Daniel Vetter
2015-06-17 12:41         ` Jani Nikula
2015-06-18 10:30         ` Dave Gordon
2015-04-14 10:10 Mika Kahola
2014-01-21 16:38 [PATCH] drm/i915: (VLV2) Fix the hotplug detection bits Todd Previte
2014-01-23  4:22 ` (no subject) Todd Previte
2013-12-30  2:29 Oravil Nair
2014-01-07  7:32 ` Daniel Vetter
     [not found] <CAEyVMbDjLwcDFrQ7y4UtGp7HOT1wi5MB2EWLGTuOdJCKDWsUew@mail.gmail.com>
2013-04-03 15:46 ` Daniel Vetter
2012-07-19 20:00 Olivier Galibert
2012-05-31 18:00 Muhammad Jamil
2012-04-12  0:55 Rodrigo Vivi
2012-04-08  2:26 Muhammad Jamil
2012-04-05  6:44 Muhammad Jamil
2012-04-03 18:25 Muhammad Jamil
2012-04-03 12:42 Muhammad Jamil
2011-04-14 18:13 forcewake v4 (now with spinlock) Ben Widawsky
2011-04-14 18:13 ` (no subject) Ben Widawsky
2011-04-08 17:47 forcewake junk, RFC, RFT(test) Ben Widawsky
2011-04-09 20:26 ` forcewake junk, part2 Ben Widawsky
2011-04-09 20:26   ` (no subject) Ben Widawsky
2011-04-07 21:32 Jesse Barnes
2010-11-09  9:17 [PATCH] drm/i915/ringbuffer: set force wake bit before reading ring register Zou Nan hai
2010-11-09  9:17 ` Zou, Nanhai
2010-11-09 10:50   ` Chris Wilson
2010-11-10  0:36     ` Zou, Nanhai
2010-11-10  7:54       ` Chris Wilson
2010-11-10 18:47         ` Jesse Barnes
2010-11-17 22:52           ` (no subject) Thantry, Hariharan L

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).