[Intel-gfx] [PATCH i-g-t 1/2] lib/igt_aux: Polish docs for igt_interruptible

Daniel Vetter daniel.vetter at ffwll.ch
Wed May 11 16:49:33 UTC 2016


- Give __ prefix to internal funcstion and structs, only
  igt_interruptible is used by tests.

- Move docs to igt_interruptible and adjust.

- Explain more clearly how the timeout is getting doubled each
  iteration until no more interruptions happen. Also rename the
  argument to give it a more meaningful name in the docs.

- Link from other functions to this one for cross-referencing.

- Rename to igt_do_interruptible to make it clearer it's a loop,
  inspired by do {} while () loops.

Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
---
 lib/igt_aux.c                | 37 ++++++++-----------------------------
 lib/igt_aux.h                | 29 +++++++++++++++++++++++++----
 tests/gem_concurrent_all.c   |  4 ++--
 tests/gem_ctx_switch.c       |  2 +-
 tests/gem_exec_flush.c       |  8 ++++----
 tests/gem_exec_whisper.c     |  2 +-
 tests/gem_ringfill.c         |  2 +-
 tests/gem_softpin.c          |  6 +++---
 tests/prime_mmap_coherency.c |  2 +-
 9 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index 68c9fba1628b..caf6dede20df 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -84,7 +84,7 @@
 #define gettid() syscall(__NR_gettid)
 #define sigev_notify_thread_id _sigev_un._tid
 
-static struct __igt_sigiter {
+static struct __igt_sigiter_global {
 	pid_t tid;
 	timer_t timer;
 	struct timespec offset;
@@ -159,7 +159,7 @@ sig_ioctl(int fd, unsigned long request, void *arg)
 	return ret ? -1 : 0;
 }
 
-static bool igt_sigiter_start(struct igt_sigiter *iter, bool enable)
+static bool igt_sigiter_start(struct __igt_sigiter *iter, bool enable)
 {
 	/* Note that until we can automatically clean up on failed/skipped
 	 * tests, we cannot assume the state of the igt_ioctl indirection.
@@ -218,7 +218,7 @@ static bool igt_sigiter_start(struct igt_sigiter *iter, bool enable)
 	return true;
 }
 
-static bool igt_sigiter_stop(struct igt_sigiter *iter, bool enable)
+static bool igt_sigiter_stop(struct __igt_sigiter *iter, bool enable)
 {
 	if (enable) {
 		struct sigaction act;
@@ -240,32 +240,7 @@ static bool igt_sigiter_stop(struct igt_sigiter *iter, bool enable)
 	return false;
 }
 
-/**
- * igt_sigiter_continue:
- * @iter: the control struct
- * @enable: a boolean as to whether or not we want to enable interruptions
- *
- * Provides control flow such that all drmIoctl() (strictly igt_ioctl())
- * within the loop are forcibly injected with signals (SIGRTMIN).
- *
- * This is useful to exercise ioctl error paths, at least where those can be
- * exercises by interrupting blocking waits, like stalling for the gpu.
- *
- * igt_sigiter_continue() returns false when it has detected that it
- * cannot inject any more signals in the ioctls from previous runs.
- *
- * Typical usage is
- * 	struct igt_sigiter iter = {};
- * 	while (igt_sigiter_continue(&iter, test_flags & TEST_INTERRUPTIBLE))
- * 		do_test();
- *
- * This is condensed into the igt_interruptible() macro.
- *
- * Note that since this overloads the igt_ioctl(), this method is not useful
- * for widespread signal injection, for example providing coverage of
- * pagefaults. To interrupt everything, see igt_fork_signal_helper().
- */
-bool igt_sigiter_continue(struct igt_sigiter *iter, bool enable)
+bool __igt_sigiter_continue(struct __igt_sigiter *iter, bool enable)
 {
 	if (iter->pass++ == 0)
 		return igt_sigiter_start(iter, enable);
@@ -329,6 +304,10 @@ static void sig_handler(int i)
  *
  * In tests with subtests this function can be called outside of failure
  * catching code blocks like #igt_fixture or #igt_subtest.
+ *
+ * Note that this just spews signals at the current process unconditionally and
+ * hence incurs quite a bit of overhead. For a more focuses approach, with less
+ * overhead, look at the #igt_interruptible code block macro.
  */
 void igt_fork_signal_helper(void)
 {
diff --git a/lib/igt_aux.h b/lib/igt_aux.h
index f66de7216411..f13ab0bc5604 100644
--- a/lib/igt_aux.h
+++ b/lib/igt_aux.h
@@ -43,13 +43,34 @@ void igt_stop_signal_helper(void);
 void igt_fork_hang_detector(int fd);
 void igt_stop_hang_detector(void);
 
-struct igt_sigiter {
+struct __igt_sigiter {
 	unsigned pass;
 };
 
-bool igt_sigiter_continue(struct igt_sigiter *iter, bool interrupt);
-#define igt_interruptible(E) \
-	for (struct igt_sigiter iter__={}; igt_sigiter_continue(&iter__, (E)); )
+bool __igt_sigiter_continue(struct __igt_sigiter *iter, bool interrupt);
+
+/**
+ * igt_do_interruptible:
+ * @enable: enable igt_ioctl interrupting or not
+ *
+ * Provides control flow such that all drmIoctl() (strictly igt_ioctl())
+ * within the loop are forcibly injected with signals (SIGRTMIN).
+ *
+ * This is useful to exercise ioctl error paths, at least where those can be
+ * exercises by interrupting blocking waits, like stalling for the gpu.
+ *
+ * The code block attached to this macro is run in a loop with doubling the
+ * interrupt timeout on each ioctl for every run, until no ioctl gets
+ * interrupted any more. The starting timeout is taken to be the signal deliver
+ * latency, measured at runtime. This way the any ioctls called from this code
+ * block should be exaustively tested for all signal interruption paths.
+ *
+ * Note that since this overloads the igt_ioctl(), this method is not useful
+ * for widespread signal injection, for example providing coverage of
+ * pagefaults. To interrupt everything, see igt_fork_signal_helper().
+ */
+#define igt_do_interruptible(enable) \
+	for (struct __igt_sigiter iter__={}; __igt_sigiter_continue(&iter__, (enable)); )
 
 #define igt_timeout(T) \
 	for (struct timespec t__={}; igt_seconds_elapsed(&t__) < (T); )
diff --git a/tests/gem_concurrent_all.c b/tests/gem_concurrent_all.c
index c0af60d4ab5e..48aa4fa289b4 100644
--- a/tests/gem_concurrent_all.c
+++ b/tests/gem_concurrent_all.c
@@ -1294,7 +1294,7 @@ static void run_interruptible(struct buffers *buffers,
 			      do_hang do_hang_func)
 {
 	pass = 0;
-	igt_interruptible(true)
+	igt_do_interruptible(true)
 		do_test_func(buffers, do_copy_func, do_hang_func);
 	igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
 }
@@ -1340,7 +1340,7 @@ static void __run_forked(struct buffers *buffers,
 		buffers_reset(buffers, true);
 		buffers_create(buffers);
 
-		igt_interruptible(interrupt) {
+		igt_do_interruptible(interrupt) {
 			for (pass = 0; pass < loops; pass++)
 				do_test_func(buffers,
 					     do_copy_func,
diff --git a/tests/gem_ctx_switch.c b/tests/gem_ctx_switch.c
index 004ba227fd3f..3af2f3574a62 100644
--- a/tests/gem_ctx_switch.c
+++ b/tests/gem_ctx_switch.c
@@ -116,7 +116,7 @@ static void single(int fd, uint32_t handle,
 
 		clock_gettime(CLOCK_MONOTONIC, &start);
 		do {
-			igt_interruptible(flags & INTERRUPTIBLE) {
+			igt_do_interruptible(flags & INTERRUPTIBLE) {
 				for (int loop = 0; loop < 1024; loop++) {
 					execbuf.rsvd1 = contexts[loop % 64];
 					reloc.presumed_offset = 0;
diff --git a/tests/gem_exec_flush.c b/tests/gem_exec_flush.c
index 705ef84941ec..f61b5b36034e 100644
--- a/tests/gem_exec_flush.c
+++ b/tests/gem_exec_flush.c
@@ -216,7 +216,7 @@ overwrite:
 
 			if (flags & SET_DOMAIN) {
 				unsigned domain = flags & WC ? I915_GEM_DOMAIN_GTT : I915_GEM_DOMAIN_CPU;
-				igt_interruptible(flags & INTERRUPTIBLE)
+				igt_do_interruptible(flags & INTERRUPTIBLE)
 					gem_set_domain(fd, obj[0].handle,
 						       domain, (flags & WRITE) ? domain : 0);
 
@@ -230,7 +230,7 @@ overwrite:
 			} else if (flags & KERNEL) {
 				uint32_t val;
 
-				igt_interruptible(flags & INTERRUPTIBLE)
+				igt_do_interruptible(flags & INTERRUPTIBLE)
 					gem_read(fd, obj[0].handle,
 						 i*sizeof(uint32_t),
 						 &val, sizeof(val));
@@ -242,13 +242,13 @@ overwrite:
 
 				if (flags & WRITE) {
 					val = 0xdeadbeef;
-					igt_interruptible(flags & INTERRUPTIBLE)
+					igt_do_interruptible(flags & INTERRUPTIBLE)
 						gem_write(fd, obj[0].handle,
 							  i*sizeof(uint32_t),
 							  &val, sizeof(val));
 				}
 			} else {
-				igt_interruptible(flags & INTERRUPTIBLE)
+				igt_do_interruptible(flags & INTERRUPTIBLE)
 					gem_sync(fd, obj[0].handle);
 
 				if (!(flags & (BEFORE | COHERENT)) &&
diff --git a/tests/gem_exec_whisper.c b/tests/gem_exec_whisper.c
index 8db475e2bc41..7aba7de68fd8 100644
--- a/tests/gem_exec_whisper.c
+++ b/tests/gem_exec_whisper.c
@@ -225,7 +225,7 @@ static void whisper(int fd, unsigned engine, unsigned flags)
 		gem_write(fd, batches[n].handle, 0, batch, sizeof(batch));
 	}
 
-	igt_interruptible(flags & INTERRUPTIBLE) {
+	igt_do_interruptible(flags & INTERRUPTIBLE) {
 		for (pass = 0; pass < 1024; pass++) {
 			uint64_t offset;
 
diff --git a/tests/gem_ringfill.c b/tests/gem_ringfill.c
index 52192d9b5286..ef764ba6e202 100644
--- a/tests/gem_ringfill.c
+++ b/tests/gem_ringfill.c
@@ -75,7 +75,7 @@ static void fill_ring(int fd,
 	 * doing this, we aren't likely to with this test.
 	 */
 	igt_debug("Executing execbuf %d times\n", 128*1024/(8*4));
-	igt_interruptible(flags & INTERRUPTIBLE) {
+	igt_do_interruptible(flags & INTERRUPTIBLE) {
 		for (int i = 0; i < 128*1024 / (8 * 4); i++)
 			gem_execbuf(fd, execbuf);
 	}
diff --git a/tests/gem_softpin.c b/tests/gem_softpin.c
index 1a9ef02bebe4..434570e3eadf 100644
--- a/tests/gem_softpin.c
+++ b/tests/gem_softpin.c
@@ -492,7 +492,7 @@ igt_main
 	igt_subtest("noreloc")
 		test_noreloc(fd, NOSLEEP);
 	igt_subtest("noreloc-interruptible")
-		igt_interruptible(true) test_noreloc(fd, NOSLEEP);
+		igt_do_interruptible(true) test_noreloc(fd, NOSLEEP);
 	igt_subtest("noreloc-S3")
 		test_noreloc(fd, SUSPEND);
 	igt_subtest("noreloc-S4")
@@ -500,9 +500,9 @@ igt_main
 
 	for (int signal = 0; signal <= 1; signal++) {
 		igt_subtest_f("evict-active%s", signal ? "-interruptible" : "")
-			igt_interruptible(signal) test_evict_active(fd);
+			igt_do_interruptible(signal) test_evict_active(fd);
 		igt_subtest_f("evict-snoop%s", signal ? "-interruptible" : "")
-			igt_interruptible(signal) test_evict_snoop(fd);
+			igt_do_interruptible(signal) test_evict_snoop(fd);
 	}
 	igt_subtest("evict-hang")
 		test_evict_hang(fd);
diff --git a/tests/prime_mmap_coherency.c b/tests/prime_mmap_coherency.c
index 5cacdc5d870c..45571c418ddd 100644
--- a/tests/prime_mmap_coherency.c
+++ b/tests/prime_mmap_coherency.c
@@ -277,7 +277,7 @@ static void test_ioctl_errors(void)
 		}
 
 		igt_fork(child, num_children)
-			igt_interruptible(true) blit_and_cmp();
+			igt_do_interruptible(true) blit_and_cmp();
 		igt_waitchildren();
 	}
 }
-- 
2.8.1



More information about the Intel-gfx mailing list