[igt-dev] [PATCH i-g-t] tests/gem_exec_alignment.c: Update to be completable in a rational time.

Dominik Grzegorzek dominik.grzegorzek at intel.com
Wed Feb 12 09:14:01 UTC 2020


Updated subtest many, that was unusable due to long the time of execution. 
For that purpose number of used execobjs was limited basing on timeout.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek at intel.com>
Cc: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
 
---
 tests/i915/gem_exec_alignment.c | 109 +++++++++++++++++++++++++++-----
 1 file changed, 93 insertions(+), 16 deletions(-)

diff --git a/tests/i915/gem_exec_alignment.c b/tests/i915/gem_exec_alignment.c
index a10571c9..a851e001 100644
--- a/tests/i915/gem_exec_alignment.c
+++ b/tests/i915/gem_exec_alignment.c
@@ -36,8 +36,11 @@
 #include <errno.h>
 #include <sys/stat.h>
 #include <sys/time.h>
+#include <signal.h>
 #include "drm.h"
 
+#define TIMEOUT 1
+
 IGT_TEST_DESCRIPTION("Exercises the basic execbuffer using object alignments");
 
 static uint32_t find_last_bit(uint64_t x)
@@ -65,13 +68,54 @@ static uint32_t file_max(void)
 	return max;
 }
 
+static bool was_timed_out;
+static struct timespec start;
+static void alignment_alarm_handler(int signal)
+{
+	igt_debug("alignment test timed out!\n");
+
+	/**
+	 * If ioctl was't interrupted immidiatelly after reaching signal
+	 * that means kernel is not interaptible.
+	 */
+	if (start.tv_sec - TIMEOUT > 1)
+		igt_debug("is kernel interuptible? %s\n",
+			  (start.tv_sec - TIMEOUT > 1) ? "no" : "yes");
+	was_timed_out = true;
+
+}
+
+static void alignment_set_timeout(unsigned int seconds)
+{
+	struct sigaction sa;
+
+	sa.sa_handler = alignment_alarm_handler;
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = 0;
+	was_timed_out = false;
+
+	if (seconds != 0)
+		sigaction(SIGALRM, &sa, NULL);
+
+	alarm(seconds);
+}
+
+static inline void alignment_reset_timeout(void)
+{
+	sigaction(SIGALRM, NULL, NULL);
+	alarm(0);
+}
+
 static void many(int fd)
 {
 	uint32_t bbe = MI_BATCH_BUFFER_END;
 	struct drm_i915_gem_exec_object2 *execobj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	uint64_t gtt_size, ram_size;
-	uint64_t alignment, max_alignment, count, i;
+	uint64_t alignment, max_alignment, count, max_count, curr_count, i;
+	struct timespec now;
+	double prev = 0, time;
+	int ret;
 
 	gtt_size = gem_aperture_size(fd);
 	if (!gem_uses_full_ppgtt(fd))
@@ -86,7 +130,7 @@ static void many(int fd)
 		max_alignment = 4096;
 	else
 		max_alignment = 1ull << (max_alignment - 1);
-	count = gtt_size / max_alignment / 2;
+	max_count = count = gtt_size / max_alignment / 2;
 
 	igt_info("gtt_size=%lld MiB, max-alignment=%lld, count=%lld\n",
 		 (long long)gtt_size/1024/1024,
@@ -111,28 +155,61 @@ static void many(int fd)
 	execbuf.buffers_ptr = to_user_pointer(execobj);
 	execbuf.buffer_count = count + 1;
 	igt_require(__gem_execbuf(fd, &execbuf) == 0);
-
+	/*
+	 * Due to the high complexity of searching holes in virtual memory,
+	 * number of objects has to be limited. The algorithm for each alignment
+	 * performs execbuffer multiple times and doubles number of objects
+	 * in every iteration till timeout is reached.
+	 **/
 	for (alignment = 4096; alignment < gtt_size; alignment <<= 1) {
-		for (i = 0; i < count; i++)
-			execobj[i].alignment = alignment;
+		alignment_set_timeout(TIMEOUT);
+		clock_gettime(CLOCK_MONOTONIC, &start);
+
 		if (alignment > max_alignment) {
 			uint64_t factor = alignment / max_alignment;
-			execbuf.buffer_count = 2*count / factor;
+			max_count = 2 * count / factor;
+		}
+
+		for (i = 0; i < count; i++)
+			execobj[i].alignment = alignment;
+
+		for (curr_count = 1; curr_count < max_count; curr_count <<= 1) {
+
+			execbuf.buffer_count = curr_count;
 			execbuf.buffers_ptr =
 				to_user_pointer(execobj + count - execbuf.buffer_count + 1);
-		}
 
-		igt_debug("testing %lld x alignment=%#llx [%db]\n",
-			  (long long)execbuf.buffer_count - 1,
-			  (long long)alignment,
-			  find_last_bit(alignment)-1);
-		gem_execbuf(fd, &execbuf);
-		for(i = count - execbuf.buffer_count + 1; i < count; i++) {
-			igt_assert_eq_u64(execobj[i].alignment, alignment);
-			igt_assert_eq_u64(execobj[i].offset % alignment, 0);
+			igt_debug("testing %lld x alignment=%#llx [%db]\n",
+				  (long long)execbuf.buffer_count,
+				  (long long)alignment,
+				  find_last_bit(alignment)-1);
+			ret = __gem_execbuf(fd, &execbuf);
+			if (curr_count << 1 >= max_count)
+				alignment_reset_timeout();
+
+			clock_gettime(CLOCK_MONOTONIC, &now);
+			time = igt_time_elapsed(&start, &now);
+
+			if (ret == 0)
+				for (i = count - execbuf.buffer_count + 1; i < count; i++) {
+					igt_assert_eq_u64(execobj[i].alignment, alignment);
+					igt_assert_eq_u64(execobj[i].offset % alignment, 0);
+				}
+
+			if (ret != EINTR)
+				igt_assert_eq(ret, 0);
+
+			/* A way to avoid probable timeout */
+			if ((time - prev) * 4 > TIMEOUT - time || was_timed_out) {
+				igt_debug("more objects will hit the timeout, "
+					  "go to next alignment\n");
+				break;
+			}
+			prev = time;
 		}
+		prev = 0;
 	}
-
+	alignment_reset_timeout();
 	for (i = 0; i < count; i++)
 		gem_close(fd, execobj[i].handle);
 	gem_close(fd, execobj[i].handle);
-- 
2.20.1

--------------------------------------------------------------------

Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek
przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by
others is strictly prohibited.


More information about the igt-dev mailing list