[Intel-gfx] [PATCH igt v2] igt/pm_rps: Replace arbitrary HIGH_LOAD blit with a busyspin

Chris Wilson chris at chris-wilson.co.uk
Mon Dec 4 10:43:55 UTC 2017


Using a blit + sleep does not guarantee generating a high enough load to
keep the GPU busy, a busyspin does. Replace the blit at high load with a
continuous series spins and low load with a mix of spin and sleep.

v2: Maintain a limited queue depth

References: https://bugs.freedesktop.org/show_bug.cgi?id=104060
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 tests/pm_rps.c | 164 +++++++++++----------------------------------------------
 1 file changed, 32 insertions(+), 132 deletions(-)

diff --git a/tests/pm_rps.c b/tests/pm_rps.c
index cc94813e..57633c54 100644
--- a/tests/pm_rps.c
+++ b/tests/pm_rps.c
@@ -26,7 +26,6 @@
  *
  */
 
-#include "igt.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -37,7 +36,8 @@
 #include <time.h>
 #include <sys/wait.h>
 
-#include "intel_bufmgr.h"
+#include "igt.h"
+#include "igt_dummyload.h"
 
 IGT_TEST_DESCRIPTION("Render P-States tests - verify GPU frequency changes");
 
@@ -181,15 +181,9 @@ enum load {
 };
 
 static struct load_helper {
-	int devid;
-	int has_ppgtt;
-	drm_intel_bufmgr *bufmgr;
-	struct intel_batchbuffer *batch;
-	drm_intel_bo *target_buffer;
 	enum load load;
 	bool exit;
 	struct igt_helper_process igt_proc;
-	drm_intel_bo *src, *dst;
 } lh;
 
 static void load_helper_signal_handler(int sig)
@@ -201,29 +195,6 @@ static void load_helper_signal_handler(int sig)
 		lh.exit = true;
 }
 
-static void emit_store_dword_imm(uint32_t val)
-{
-	int cmd;
-	struct intel_batchbuffer *batch = lh.batch;
-
-	cmd = MI_STORE_DWORD_IMM;
-	if (!lh.has_ppgtt)
-		cmd |= MI_MEM_VIRTUAL;
-
-	BEGIN_BATCH(4, 0); /* just ignore the reloc we emit and count dwords */
-	OUT_BATCH(cmd);
-	if (batch->gen >= 8) {
-		OUT_RELOC(lh.target_buffer, I915_GEM_DOMAIN_INSTRUCTION,
-			  I915_GEM_DOMAIN_INSTRUCTION, 0);
-	} else {
-		OUT_BATCH(0); /* reserved */
-		OUT_RELOC(lh.target_buffer, I915_GEM_DOMAIN_INSTRUCTION,
-			  I915_GEM_DOMAIN_INSTRUCTION, 0);
-	}
-	OUT_BATCH(val);
-	ADVANCE_BATCH();
-}
-
 #define LOAD_HELPER_PAUSE_USEC 500
 #define LOAD_HELPER_BO_SIZE (16*1024*1024)
 static void load_helper_set_load(enum load load)
@@ -252,69 +223,51 @@ static void load_helper_run(enum load load)
 	lh.load = load;
 
 	igt_fork_helper(&lh.igt_proc) {
-		const uint32_t bbe = MI_BATCH_BUFFER_END;
-		struct drm_i915_gem_exec_object2 object;
-		struct drm_i915_gem_execbuffer2 execbuf;
-		uint32_t fences[3];
-		uint32_t val = 0;
+		igt_spin_t *spin[2] = {};
+		uint32_t handle;
 
 		signal(SIGUSR1, load_helper_signal_handler);
 		signal(SIGUSR2, load_helper_signal_handler);
 
-		fences[0] = gem_create(drm_fd, 4096);
-		gem_write(drm_fd, fences[0], 0,  &bbe, sizeof(bbe));
-		fences[1] = gem_create(drm_fd, 4096);
-		gem_write(drm_fd, fences[1], 0,  &bbe, sizeof(bbe));
-		fences[2] = gem_create(drm_fd, 4096);
-		gem_write(drm_fd, fences[2], 0,  &bbe, sizeof(bbe));
-
-		memset(&execbuf, 0, sizeof(execbuf));
-		execbuf.buffers_ptr = (uintptr_t)&object;
-		execbuf.buffer_count = 1;
-		if (intel_gen(lh.devid) >= 6)
-			execbuf.flags = I915_EXEC_BLT;
-
 		igt_debug("Applying %s load...\n", lh.load ? "high" : "low");
 
 		while (!lh.exit) {
-			memset(&object, 0, sizeof(object));
-			object.handle = fences[val%3];
-
-			while (gem_bo_busy(drm_fd, object.handle))
+			if (spin[0]) {
+				handle = spin[0]->handle;
+				igt_spin_batch_end(spin[0]);
+				while (gem_bo_busy(drm_fd, handle))
+					usleep(100);
+				igt_spin_batch_free(drm_fd, spin[0]);
 				usleep(100);
+			}
+			spin[0] = spin[1];
+			spin[lh.load == HIGH] =
+				igt_spin_batch_new(drm_fd, 0, 0, 0);
+		}
 
-			if (lh.load == HIGH)
-				intel_copy_bo(lh.batch, lh.dst, lh.src,
-					      LOAD_HELPER_BO_SIZE);
-
-			emit_store_dword_imm(val);
-			intel_batchbuffer_flush_on_ring(lh.batch,
-                                                        I915_EXEC_BLT);
-			val++;
-
-			gem_execbuf(drm_fd, &execbuf);
-
-			/* Lower the load by pausing after every submitted
-			 * write. */
-			if (lh.load == LOW)
-				usleep(LOAD_HELPER_PAUSE_USEC);
+		if (spin[0]) {
+			handle = spin[0]->handle;
+			igt_spin_batch_end(spin[0]);
+		}
+		if (spin[1]) {
+			handle = spin[1]->handle;
+			igt_spin_batch_end(spin[1]);
 		}
 
 		/* Wait for completion without boosting */
 		usleep(1000);
-		while (gem_bo_busy(drm_fd, lh.target_buffer->handle))
+		while (gem_bo_busy(drm_fd, handle))
 			usleep(1000);
 
-		igt_debug("load helper sent %u dword writes\n", val);
-		gem_close(drm_fd, fences[0]);
-		gem_close(drm_fd, fences[1]);
-		gem_close(drm_fd, fences[2]);
-
-		/* Idle/boost logic is tied with request retirement.
+		/*
+		 * Idle/boost logic is tied with request retirement.
 		 * Speed up detection of idle state and ensure deboost
 		 * after removing load.
 		 */
 		igt_drop_caches_set(drm_fd, DROP_RETIRE);
+
+		igt_spin_batch_free(drm_fd, spin[1]);
+		igt_spin_batch_free(drm_fd, spin[0]);
 	}
 }
 
@@ -324,54 +277,6 @@ static void load_helper_stop(void)
 	igt_assert(igt_wait_helper(&lh.igt_proc) == 0);
 }
 
-static void load_helper_init(void)
-{
-	lh.devid = intel_get_drm_devid(drm_fd);
-	lh.has_ppgtt = gem_uses_ppgtt(drm_fd);
-
-	/* MI_STORE_DATA can only use GTT address on gen4+/g33 and needs
-	 * snoopable mem on pre-gen6. Hence load-helper only works on gen6+, but
-	 * that's also all we care about for the rps testcase*/
-	igt_assert(intel_gen(lh.devid) >= 6);
-	lh.bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
-	igt_assert(lh.bufmgr);
-
-	drm_intel_bufmgr_gem_enable_reuse(lh.bufmgr);
-
-	lh.batch = intel_batchbuffer_alloc(lh.bufmgr, lh.devid);
-	igt_assert(lh.batch);
-
-	lh.target_buffer = drm_intel_bo_alloc(lh.bufmgr, "target bo",
-					      4096, 4096);
-	igt_assert(lh.target_buffer);
-
-	lh.dst = drm_intel_bo_alloc(lh.bufmgr, "dst bo",
-				    LOAD_HELPER_BO_SIZE, 4096);
-	igt_assert(lh.dst);
-	lh.src = drm_intel_bo_alloc(lh.bufmgr, "src bo",
-				    LOAD_HELPER_BO_SIZE, 4096);
-	igt_assert(lh.src);
-}
-
-static void load_helper_deinit(void)
-{
-	if (lh.igt_proc.running)
-		load_helper_stop();
-
-	if (lh.target_buffer)
-		drm_intel_bo_unreference(lh.target_buffer);
-	if (lh.src)
-		drm_intel_bo_unreference(lh.src);
-	if (lh.dst)
-		drm_intel_bo_unreference(lh.dst);
-
-	if (lh.batch)
-		intel_batchbuffer_free(lh.batch);
-
-	if (lh.bufmgr)
-		drm_intel_bufmgr_destroy(lh.bufmgr);
-}
-
 static void do_load_gpu(void)
 {
 	load_helper_run(LOW);
@@ -582,13 +487,8 @@ static void boost_freq(int fd, int *boost_freqs)
 {
 	int64_t timeout = 1;
 	igt_spin_t *load;
-	unsigned int engine;
 
-	/* Put boost on the same engine as low load */
-	engine = I915_EXEC_RENDER;
-	if (intel_gen(lh.devid) >= 6)
-		engine = I915_EXEC_BLT;
-	load = igt_spin_batch_new(fd, 0, engine, 0);
+	load = igt_spin_batch_new(fd, 0, 0, 0);
 	/* Waiting will grant us a boost to maximum */
 	gem_wait(fd, load->handle, &timeout);
 
@@ -655,7 +555,9 @@ static void pm_rps_exit_handler(int sig)
 		writeval(sysfs_files[MAX].filp, origfreqs[MAX]);
 	}
 
-	load_helper_deinit();
+	if (lh.igt_proc.running)
+		load_helper_stop();
+
 	close(drm_fd);
 }
 
@@ -691,8 +593,6 @@ igt_main
 		read_freqs(origfreqs);
 
 		igt_install_exit_handler(pm_rps_exit_handler);
-
-		load_helper_init();
 	}
 
 	igt_subtest("basic-api")
-- 
2.15.1



More information about the Intel-gfx mailing list