[igt-dev] [PATCH i-g-t] i915/gem_close_race: Mix in a contexts and a small delay to closure

Ruhl, Michael J michael.j.ruhl at intel.com
Wed Jul 1 12:39:22 UTC 2020


>-----Original Message-----
>From: Chris Wilson <chris at chris-wilson.co.uk>
>Sent: Tuesday, June 30, 2020 5:25 PM
>To: intel-gfx at lists.freedesktop.org
>Cc: igt-dev at lists.freedesktop.org; Chris Wilson <chris at chris-wilson.co.uk>;
>Ruhl, Michael J <michael.j.ruhl at intel.com>
>Subject: [PATCH i-g-t] i915/gem_close_race: Mix in a contexts and a small
>delay to closure
>
>Keep the old handles in a small ring so that we build up a small amount
>of pressure for i915_gem_close_object() and throw in a few concurrent
>contexts so we have to process an obj->lut_list containing more than one
>element. And to make sure the list is truly long enough to schedule,
>start leaking the contexts.
>
>Note that the only correctness check is that the selfcopy doesn't
>explode; the challenge would be to prove that the old handles are no
>longer accessible via the execbuf lut. However, this is sufficient to
>make sure we at least hit the interruptible spinlock used by
>close-objects.
>
>Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
>Cc: Michael J. Ruhl <michael.j.ruhl at intel.com>
>---
> tests/i915/gem_close_race.c | 68 +++++++++++++++++++++++++++++-------
>-
> 1 file changed, 53 insertions(+), 15 deletions(-)
>
>diff --git a/tests/i915/gem_close_race.c b/tests/i915/gem_close_race.c
>index db570e8fd..4b72d353c 100644
>--- a/tests/i915/gem_close_race.c
>+++ b/tests/i915/gem_close_race.c
>@@ -55,7 +55,7 @@ static bool has_64bit_relocations;
>
> #define sigev_notify_thread_id _sigev_un._tid
>
>-static void selfcopy(int fd, uint32_t handle, int loops)
>+static void selfcopy(int fd, uint32_t ctx, uint32_t handle, int loops)
> {
> 	struct drm_i915_gem_relocation_entry reloc[2];
> 	struct drm_i915_gem_exec_object2 gem_exec[2];
>@@ -113,6 +113,7 @@ static void selfcopy(int fd, uint32_t handle, int loops)
> 	execbuf.batch_len = (b - buf) * sizeof(*b);
> 	if (HAS_BLT_RING(devid))
> 		execbuf.flags |= I915_EXEC_BLT;
>+	execbuf.rsvd1 = ctx;
>
> 	memset(&gem_pwrite, 0, sizeof(gem_pwrite));
> 	gem_pwrite.handle = create.handle;
>@@ -135,7 +136,7 @@ static uint32_t load(int fd)
> 	if (handle == 0)
> 		return 0;
>
>-	selfcopy(fd, handle, 100);
>+	selfcopy(fd, 0, handle, 100);
> 	return handle;
> }
>
>@@ -165,14 +166,19 @@ static void crashme_now(int sig)
> #define usec(x) (1000*(x))
> #define msec(x) usec(1000*(x))
>
>-static void threads(int timeout)
>+static void thread(int fd, struct drm_gem_open name,
>+		   int timeout, unsigned int flags)
>+#define CONTEXTS 0x1
> {
> 	struct sigevent sev;
> 	struct sigaction act;
>-	struct drm_gem_open name;
> 	struct itimerspec its;
>+	uint32_t *history;
>+#define N_HISTORY (256)
> 	timer_t timer;
>-	int fd;
>+
>+	history = malloc(sizeof(*history) * N_HISTORY);
>+	igt_assert(history);
>
> 	memset(&act, 0, sizeof(act));
> 	act.sa_handler = crashme_now;
>@@ -184,28 +190,57 @@ static void threads(int timeout)
> 	sev.sigev_signo = SIGRTMIN;
> 	igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
>
>-	fd = drm_open_driver(DRIVER_INTEL);
>-	name.name = gem_flink(fd, gem_create(fd, OBJECT_SIZE));
>-
> 	igt_until_timeout(timeout) {
>-		crashme.fd = drm_open_driver(DRIVER_INTEL);
>+		unsigned int n = 0;
>+
>+		memset(history, 0, sizeof(*history) * N_HISTORY);
>+
>+		crashme.fd = gem_reopen_driver(fd);
>
> 		memset(&its, 0, sizeof(its));
>-		its.it_value.tv_nsec = msec(1) + (rand() % msec(10));
>+		its.it_value.tv_nsec = msec(1) + (rand() % msec(150));
> 		igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
>
> 		do {
>-			if (drmIoctl(crashme.fd, DRM_IOCTL_GEM_OPEN,
>&name))
>+			uint32_t ctx = 0;
>+
>+			if (drmIoctl(crashme.fd,
>+				     DRM_IOCTL_GEM_OPEN,
>+				     &name))
> 				break;
>
>-			selfcopy(crashme.fd, name.handle, 100);
>-			drmIoctl(crashme.fd, DRM_IOCTL_GEM_CLOSE,
>&name.handle);
>+			if (flags & CONTEXTS)
>+				__gem_context_create(crashme.fd, &ctx);
>+
>+			selfcopy(crashme.fd, ctx, name.handle, 1);
>+
>+			ctx = history[n % N_HISTORY];

Ahh this 'ctx' isn't really a context, it an unclosed handle.

So the difference is that you keep around N_HISTORY open handles and
the associated contexts (if requested) until the test is done.

And 256 is enough history?  Any concerns with faster CPU/GPUs?

Looks like a good way to stress things.

Reviewed-by: Michael J. Ruhl <michael.j.ruhl at intel.com>

M


>+			if (ctx)
>+				drmIoctl(crashme.fd,
>+					 DRM_IOCTL_GEM_CLOSE,
>+					 &ctx);
>+			history[n % N_HISTORY] = name.handle;
>+			n++;
> 		} while (1);
>
> 		close(crashme.fd);
> 	}
>
> 	timer_delete(timer);
>+	free(history);
>+}
>+
>+static void threads(int timeout, unsigned int flags)
>+{
>+	struct drm_gem_open name;
>+	int fd;
>+
>+	fd = drm_open_driver(DRIVER_INTEL);
>+	name.name = gem_flink(fd, gem_create(fd, OBJECT_SIZE));
>+
>+	igt_fork(child, sysconf(_SC_NPROCESSORS_ONLN))
>+		thread(fd, name, timeout, flags);
>+	igt_waitchildren();
>
> 	gem_quiescent_gpu(fd);
> 	close(fd);
>@@ -233,7 +268,7 @@ igt_main
> 	}
>
> 	igt_subtest("basic-threads")
>-		threads(1);
>+		threads(1, 0);
>
> 	igt_subtest("process-exit") {
> 		igt_fork(child, 768)
>@@ -241,8 +276,11 @@ igt_main
> 		igt_waitchildren();
> 	}
>
>+	igt_subtest("contexts")
>+		threads(30, CONTEXTS);
>+
> 	igt_subtest("gem-close-race")
>-		threads(150);
>+		threads(150, 0);
>
> 	igt_fixture
> 	    igt_stop_hang_detector();
>--
>2.27.0



More information about the igt-dev mailing list