From patchwork Fri May 25 07:28:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10426497 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 87685602D8 for ; Fri, 25 May 2018 07:29:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E1FB2954C for ; Fri, 25 May 2018 07:29:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1082729567; Fri, 25 May 2018 07:29:07 +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 74DD82954C for ; Fri, 25 May 2018 07:29:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C70956E8AE; Fri, 25 May 2018 07:29:05 +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 47B146E8AE; Fri, 25 May 2018 07:29:04 +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 11835811-1500050 for multiple; Fri, 25 May 2018 08:28:53 +0100 Received: by haswell.alporthouse.com (sSMTP sendmail emulation); Fri, 25 May 2018 08:28:53 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Fri, 25 May 2018 08:28:52 +0100 Message-Id: <20180525072852.12378-1-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.17.0 X-Originating-IP: 78.156.65.138 X-Country: code=GB country="United Kingdom" ip=78.156.65.138 Subject: [Intel-gfx] [PATCH i-g-t v2] tests/drv_suspend: Suspend under memory pressure 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, Tomi Sarvela MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Recently we discovered that we have a race between swapping and suspend in our resume path (we might be trying to page in an object after disabling the block devices). Let's try to exercise that by exhausting all of system memory before suspend. v2: Explicitly share the large memory area on forking to avoid running out of memory inside the suspend helpers (for they fork!) References: https://bugs.freedesktop.org/show_bug.cgi?id=106640 Signed-off-by: Chris Wilson Cc: Tomi Sarvela Reviewed-by: Antonio Argenziano --- lib/igt_core.c | 34 ++++++++++++++++------------ lib/igt_core.h | 1 + tests/drv_suspend.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 14 deletions(-) diff --git a/lib/igt_core.c b/lib/igt_core.c index e292ca24c..804ce4578 100644 --- a/lib/igt_core.c +++ b/lib/igt_core.c @@ -1756,20 +1756,7 @@ void igt_child_done(pid_t pid) test_children[i] = test_children[i + 1]; } -/** - * igt_waitchildren: - * - * Wait for all children forked with igt_fork. - * - * The magic here is that exit codes from children will be correctly propagated - * to the main thread, including the relevant exit code if a child thread failed. - * Of course if multiple children failed with different exit codes the resulting - * exit code will be non-deterministic. - * - * Note that igt_skip() will not be forwarded, feature tests need to be done - * before spawning threads with igt_fork(). - */ -void igt_waitchildren(void) +int __igt_waitchildren(void) { int err = 0; int count; @@ -1815,6 +1802,25 @@ void igt_waitchildren(void) } num_test_children = 0; + return err; +} + +/** + * igt_waitchildren: + * + * Wait for all children forked with igt_fork. + * + * The magic here is that exit codes from children will be correctly propagated + * to the main thread, including the relevant exit code if a child thread failed. + * Of course if multiple children failed with different exit codes the resulting + * exit code will be non-deterministic. + * + * Note that igt_skip() will not be forwarded, feature tests need to be done + * before spawning threads with igt_fork(). + */ +void igt_waitchildren(void) +{ + int err = __igt_waitchildren(); if (err) igt_fail(err); } diff --git a/lib/igt_core.h b/lib/igt_core.h index 3d7b787b2..6d4260403 100644 --- a/lib/igt_core.h +++ b/lib/igt_core.h @@ -742,6 +742,7 @@ bool __igt_fork(void); for (int child = 0; child < (num_children); child++) \ for (; __igt_fork(); exit(0)) void igt_child_done(pid_t pid); +int __igt_waitchildren(void); void igt_waitchildren(void); void igt_waitchildren_timeout(int seconds, const char *reason); diff --git a/tests/drv_suspend.c b/tests/drv_suspend.c index 2e39f20ae..9a9ff2005 100644 --- a/tests/drv_suspend.c +++ b/tests/drv_suspend.c @@ -160,6 +160,57 @@ test_sysfs_reader(bool hibernate) igt_stop_helper(&reader); } +static void +test_shrink(int fd, unsigned int mode) +{ + uint64_t *can_mlock, pin; + + gem_quiescent_gpu(fd); + intel_purge_vm_caches(fd); + + pin = (intel_get_total_ram_mb() + 1) << 20; + + igt_debug("Total memory %'"PRIu64" B (%'"PRIu64" MiB)\n", + pin, pin >> 20); + can_mlock = mmap(NULL, pin, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + igt_require(can_mlock != MAP_FAILED); + + /* Lock all the system memory, forcing the driver into swap and OOM */ + for (uint64_t inc = 64 << 20; inc >= 4 << 10; inc >>= 1) { + igt_debug("Testing+ %'"PRIu64" B (%'"PRIu64" MiB)\n", + *can_mlock, *can_mlock >> 20); + + igt_fork(child, 1) { + for (uint64_t bytes = *can_mlock; + bytes <= pin; + bytes += inc) { + if (mlock(can_mlock, bytes)) + break; + + *can_mlock = bytes; + __sync_synchronize(); + } + } + __igt_waitchildren(); + } + + intel_purge_vm_caches(fd); + + igt_require(*can_mlock > 64 << 20); + *can_mlock -= 64 << 20; + + igt_debug("Locking %'"PRIu64" B (%'"PRIu64" MiB)\n", + *can_mlock, *can_mlock >> 20); + igt_assert(!mlock(can_mlock, *can_mlock)); + igt_info("Locked %'"PRIu64" B (%'"PRIu64" MiB)\n", + *can_mlock, *can_mlock >> 20); + + intel_purge_vm_caches(fd); + igt_system_suspend_autoresume(mode, SUSPEND_TEST_NONE); + + munmap(can_mlock, pin); +} + static void test_forcewake(int fd, bool hibernate) { @@ -199,6 +250,9 @@ igt_main igt_subtest("sysfs-reader") test_sysfs_reader(false); + igt_subtest("shrink") + test_shrink(fd, SUSPEND_STATE_MEM); + igt_subtest("forcewake") test_forcewake(fd, false);