Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Cc: igt-dev@lists.freedesktop.org
Subject: [igt-dev] [PATCH i-g-t] i915/gem_userptr_blit: Shoot down a shared mmap_gtt(userptr)
Date: Wed, 14 Aug 2019 23:37:26 +0100	[thread overview]
Message-ID: <20190814223726.31338-1-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <20190814222549.31154-1-chris@chris-wilson.co.uk>

Establish a userptr and inherit it to many children with fresh mm. Into
each child mm, mmap_gtt the userptr handle so that they are many
different vma in the i_mapping tree pointing back to the userptr. Then
proceed to munmap that and force us to revoke all the mmaps.

Daniel discovered that from the unmap in the parent, we will call
i915_vma_revoke_mmaps() on all the child mappings, which in turn should
call mmu_notifier_invalidate_range -- ostensibly recursing from the
outer mmu_notifier_invalidate_range of the munamp.

v2: Invoke userptr in each child for more mmu-notifiers

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 tests/i915/gem_userptr_blits.c | 86 ++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
index 5f7770c93..f08616146 100644
--- a/tests/i915/gem_userptr_blits.c
+++ b/tests/i915/gem_userptr_blits.c
@@ -1613,6 +1613,89 @@ static void test_unmap(int fd, int expected)
 		gem_close(fd, bo[i]);
 }
 
+static int count_sigbus(void *ptr, size_t len)
+{
+	struct sigaction sigact, orig_sigact;
+
+	memset(&sigact, 0, sizeof(sigact));
+	sigact.sa_sigaction = sigbus;
+	sigact.sa_flags = SA_SIGINFO;
+	igt_assert(sigaction(SIGBUS, &sigact, &orig_sigact) == 0);
+
+	sigbus_start = (unsigned long)ptr;
+	sigbus_cnt = 0;
+	memset(ptr, 0, len);
+
+	sigaction(SIGBUS, &orig_sigact, NULL);
+	return sigbus_cnt;
+}
+
+static void test_unmap_shared(int i915)
+{
+	const int num_child = 64;
+	struct {
+		void *base;
+		uint32_t *gtt;
+		uint32_t bo;
+	} t[2];
+
+	igt_require(gem_has_llc(i915));
+
+	for (int i = 0; i < ARRAY_SIZE(t); i++) {
+		t[i].base = mmap(NULL, sizeof(linear), PROT_READ | PROT_WRITE,
+			       MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+		igt_assert(t[i].base != MAP_FAILED);
+		igt_require(__gem_userptr(i915, t[i].base, sizeof(linear),
+					  0, userptr_flags, &t[i].bo) == 0);
+
+		t[i].gtt = gem_mmap__gtt(i915, t[i].bo,
+					 sizeof(linear), PROT_WRITE);
+		*t[i].gtt = i;
+	}
+
+	igt_fork(child, num_child) {
+		uint32_t *ptr;
+
+		/* First attach our own user pointer to prep the mmu notifier */
+		ptr = mmap(NULL, sizeof(linear), PROT_READ | PROT_WRITE,
+			   MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+		igt_assert(ptr != MAP_FAILED);
+		igt_require(__gem_userptr(i915, ptr, sizeof(linear),
+					  0, userptr_flags, ptr) == 0);
+
+		ptr = gem_mmap__gtt(i915, t[0].bo, sizeof(linear), PROT_WRITE);
+		ptr[child] = 1;
+
+		ptr = gem_mmap__gtt(i915, t[1].bo, sizeof(linear), PROT_WRITE);
+		while (READ_ONCE(*ptr) == 1)
+			usleep(10 * 1000);
+
+		ptr = gem_mmap__gtt(i915, t[0].bo, sizeof(linear), PROT_WRITE);
+		igt_assert(count_sigbus(ptr, 1) > 0);
+	}
+
+	/* busy wait for all children to instantiate their mmap */
+	for (int child = 0; child < num_child; child++) {
+		while (READ_ONCE(t[0].gtt[child]) == 0)
+			;
+	}
+
+	/* shoot it down! */
+	munmap(t[0].base, sizeof(linear));
+
+	/* check our aim was true */
+	igt_assert(count_sigbus(t[0].gtt, 1) > 0);
+
+	*t[1].gtt = 0;
+	igt_waitchildren();
+
+	for (int i = 0; i < ARRAY_SIZE(t); i++) {
+		gem_close(i915, t[i].bo);
+		munmap(t[i].gtt, sizeof(linear));
+		munmap(t[i].base, sizeof(linear));
+	}
+}
+
 static void test_unmap_after_close(int fd)
 {
 	char *ptr, *bo_ptr;
@@ -2006,6 +2089,9 @@ igt_main_args("c:", NULL, help_str, opt_handler, NULL)
 		igt_subtest("sync-unmap-after-close")
 			test_unmap_after_close(fd);
 
+		igt_subtest("sync-unmap-shared")
+			test_unmap_shared(fd);
+
 		igt_subtest("stress-mm")
 			test_stress_mm(fd);
 		igt_subtest("stress-purge")
-- 
2.23.0.rc1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2019-08-14 22:37 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-14 22:25 [igt-dev] [PATCH i-g-t] i915/gem_userptr_blit: Shoot down a shared mmap_gtt(userptr) Chris Wilson
2019-08-14 22:37 ` Chris Wilson [this message]
2019-08-14 23:30 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
2019-08-14 23:33 ` [igt-dev] ✓ Fi.CI.BAT: success for i915/gem_userptr_blit: Shoot down a shared mmap_gtt(userptr) (rev2) Patchwork
2019-08-15 15:46 ` [igt-dev] ✓ Fi.CI.IGT: success for i915/gem_userptr_blit: Shoot down a shared mmap_gtt(userptr) Patchwork
2019-08-15 16:23 ` [igt-dev] ✓ Fi.CI.IGT: success for i915/gem_userptr_blit: Shoot down a shared mmap_gtt(userptr) (rev2) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190814223726.31338-1-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox