From patchwork Thu Dec 6 10:55:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 10715593 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 14B2B13AF for ; Thu, 6 Dec 2018 10:55:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 03E3F2D939 for ; Thu, 6 Dec 2018 10:55:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EC6122D340; Thu, 6 Dec 2018 10:55:45 +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 7D44B2D340 for ; Thu, 6 Dec 2018 10:55:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1D6A66E579; Thu, 6 Dec 2018 10:55:44 +0000 (UTC) X-Original-To: Intel-gfx@lists.freedesktop.org Delivered-To: Intel-gfx@lists.freedesktop.org Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by gabe.freedesktop.org (Postfix) with ESMTPS id B907E6E57B; Thu, 6 Dec 2018 10:55:42 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Dec 2018 02:55:42 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,322,1539673200"; d="scan'208";a="105323057" Received: from segorov-mobl2.ccr.corp.intel.com (HELO localhost.localdomain) ([10.252.6.223]) by fmsmga007.fm.intel.com with ESMTP; 06 Dec 2018 02:55:40 -0800 From: Tvrtko Ursulin To: igt-dev@lists.freedesktop.org Date: Thu, 6 Dec 2018 10:55:38 +0000 Message-Id: <20181206105538.7150-1-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181206105219.7041-1-tvrtko.ursulin@linux.intel.com> References: <20181206105219.7041-1-tvrtko.ursulin@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFT i-g-t v2] tests/gem_shrink: Background, direct and OOM shrinker plus userptr tests 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: Intel-gfx@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Tvrtko Ursulin ... Signed-off-by: Tvrtko Ursulin --- tests/i915/gem_shrink.c | 213 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) diff --git a/tests/i915/gem_shrink.c b/tests/i915/gem_shrink.c index c8e05814ee70..acc12efed15e 100644 --- a/tests/i915/gem_shrink.c +++ b/tests/i915/gem_shrink.c @@ -26,6 +26,9 @@ * * Exercise the shrinker by overallocating GEM objects */ +#include +#include +#include #include "igt.h" #include "igt_gt.h" @@ -366,6 +369,210 @@ static void reclaim(unsigned engine, int timeout) close(fd); } +static unsigned long get_meminfo(const char *info, const char *tag) +{ + const char *str; + unsigned long val; + + str = strstr(info, tag); + if (str && sscanf(str + strlen(tag), " %lu", &val) == 1) + return val >> 10; + + igt_warn("Unrecognised /proc/meminfo field: '%s'\n", tag); + return 0; +} + +static unsigned long get_avail_ram_mb(void) +{ + int fd; + int ret; + char buf[4096]; + unsigned long ram; + + fd = open("/proc/meminfo", O_RDONLY); + igt_assert_fd(fd); + + ret = read(fd, buf, sizeof(buf)); + igt_assert(ret >= 0); + + close(fd); + + ram = get_meminfo(buf, "MemAvailable:"); + ram += get_meminfo(buf, "Buffers:"); + ram += get_meminfo(buf, "Cached:"); + ram += get_meminfo(buf, "SwapCached:"); + + return ram; +} + +struct test { +#define TEST_BO (1) +#define TEST_USERPTR (2) + unsigned int flags; + int fd; +}; + +static uint32_t __get_pages(int fd, unsigned long alloc) +{ + uint32_t handle = gem_create(fd, alloc); + + gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, 0); + gem_madvise(fd, handle, I915_MADV_DONTNEED); + + return handle; +} + +struct test_obj { + void *ptr; + uint32_t handle; +}; + +static void +__get_userptr(int fd, struct test_obj *obj, unsigned long sz) +{ + struct local_i915_gem_userptr userptr = { }; + void *ptr; + + igt_assert_eq(sz & 4095, 0); + + ptr = mmap(NULL, sz, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(ptr != MAP_FAILED); + + userptr.user_size = sz; + userptr.user_ptr = to_user_pointer(ptr); + do_ioctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr); + + gem_set_domain(fd, userptr.handle, I915_GEM_DOMAIN_GTT, 0); + + obj->ptr = ptr; + obj->handle = userptr.handle; +} + +#define PAGE_SIZE 4096 +static void *mempressure(void *arg) +{ + struct test_obj *list = NULL; + struct test *test = arg; + const unsigned int sz_mb = 2; + const unsigned int sz = sz_mb << 20; + unsigned int n = 0, max = 0; + unsigned int blocks; + + while (true) { + unsigned long ram_mb = get_avail_ram_mb(); + + if (!list) { + blocks = ram_mb / sz_mb; + list = calloc(blocks, sizeof(*list)); + igt_assert(list); + } else if (ram_mb < 256) { + blocks = max + 1; + } + + if (list[n].ptr || list[n].handle) { + if (test->flags & TEST_BO) + gem_close(test->fd, list[n].handle); + else + munmap(list[n].ptr, sz); + } + + if (test->flags & TEST_BO) { + list[n].handle = __get_pages(test->fd, sz); + } else if (test->flags & TEST_USERPTR) { + __get_userptr(test->fd, &list[n], sz); + } else { + list[n].ptr = mmap(NULL, sz, PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(list[n].ptr != MAP_FAILED); + + madvise(list[n].ptr, sz, MADV_HUGEPAGE); + + for (size_t page = 0; page < sz; page += PAGE_SIZE) + *(volatile uint32_t *)((unsigned char *)list[n].ptr + page) = 0; + } + + if (n > max) + max = n; + + n++; + + if (n >= blocks) + n = 0; + } + + return NULL; +} + +static void oom_adjust(const char *score) +{ + int fd; + + fd = open("/proc/self/oom_score_adj", O_WRONLY); + igt_assert_fd(fd); + igt_assert(write(fd, score, sizeof(score)) == sizeof(score)); + close(fd); +} + +static void trigger_oom(void) +{ + const char *cmd = "f"; + int fd; + + fd = open("/proc/sysrq-trigger", O_WRONLY); + igt_assert_fd(fd); + igt_assert(write(fd, cmd, sizeof(cmd)) == sizeof(cmd)); + close(fd); +} + +static void reclaim_oom(unsigned int flags) +{ + unsigned int count = 0; + + igt_assert_eq(__builtin_popcount(flags), 1); + + oom_adjust("-1000"); + + do { + struct igt_helper_process gem_child = { }; + struct igt_helper_process mem_child = { }; + + igt_debug("Iteration %u...\n", ++count); + + igt_fork_helper(&mem_child) { + struct test mem = { }; + + oom_adjust("500"); + mempressure(&mem); + } + + igt_fork_helper(&gem_child) { + struct test gem = { .flags = flags }; + + oom_adjust("500"); + + gem.fd = drm_open_driver(DRIVER_INTEL); + igt_require_gem(gem.fd); + + mempressure(&gem); + + close(gem.fd); + } + + for (unsigned long ram_mb = 0; + (ram_mb = get_avail_ram_mb()) > 512;) { + igt_debug("[%u] %lu free mb\n", count, ram_mb); + sleep(1); + } + + trigger_oom(); + + sleep(1); + + igt_stop_helper(&mem_child); + igt_stop_helper(&gem_child); + } while (count < 5); +} + igt_main { const struct test { @@ -432,6 +639,12 @@ igt_main igt_subtest("reclaim") reclaim(I915_EXEC_DEFAULT, 2); + igt_subtest("two-reclaims-and-oom") + reclaim_oom(TEST_BO); + + igt_subtest("two-reclaims-and-oom-userptr") + reclaim_oom(TEST_USERPTR); + for(const struct test *t = tests; t->name; t++) { for(const struct mode *m = modes; m->suffix; m++) { igt_subtest_f("%s%s", t->name, m->suffix)