From patchwork Wed Aug 14 22:37:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 11094687 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 670FB1398 for ; Wed, 14 Aug 2019 22:37:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 576B427FA1 for ; Wed, 14 Aug 2019 22:37:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4B869287B6; Wed, 14 Aug 2019 22:37:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9835927FA1 for ; Wed, 14 Aug 2019 22:37:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 40CFF89AD2; Wed, 14 Aug 2019 22:37:35 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (mail.fireflyinternet.com [109.228.58.192]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2DBDE89AD2; Wed, 14 Aug 2019 22:37:34 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 18129508-1500050 for multiple; Wed, 14 Aug 2019 23:37:28 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Wed, 14 Aug 2019 23:37:26 +0100 Message-Id: <20190814223726.31338-1-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20190814222549.31154-1-chris@chris-wilson.co.uk> References: <20190814222549.31154-1-chris@chris-wilson.co.uk> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t] i915/gem_userptr_blit: Shoot down a shared mmap_gtt(userptr) X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org, Daniel Vetter Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP 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 Cc: Daniel Vetter --- 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")