public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [RFT i-g-t 1/2] tests/gem_shrink: Background, direct and OOM shrinker plus userptr tests
Date: Fri,  7 Dec 2018 10:14:53 +0000	[thread overview]
Message-ID: <20181207101453.25199-1-tvrtko.ursulin@linux.intel.com> (raw)
In-Reply-To: <20181207085929.24365-1-tvrtko.ursulin@linux.intel.com>

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

...

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 lib/igt_core.c          |  18 ++++
 lib/igt_core.h          |   1 +
 tests/i915/gem_shrink.c | 213 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 232 insertions(+)

diff --git a/lib/igt_core.c b/lib/igt_core.c
index 64883d6402af..d8fa0c83e279 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -1680,6 +1680,24 @@ void igt_stop_helper(struct igt_helper_process *proc)
 	assert(helper_was_alive(proc, status));
 }
 
+/**
+ * igt_try_stop_helper:
+ * @proc: #igt_helper_process structure
+ *
+ * Terminates a helper process if it is still running.
+ */
+void igt_try_stop_helper(struct igt_helper_process *proc)
+{
+	int status;
+
+	/* failure here means the pid is already dead and so waiting is safe */
+	kill(proc->pid, proc->use_SIGKILL ? SIGKILL : SIGTERM);
+
+	status = igt_wait_helper(proc);
+	if (!helper_was_alive(proc, status))
+		igt_debug("Helper died too early with status=%d\n", status);
+}
+
 static void children_exit_handler(int sig)
 {
 	int status;
diff --git a/lib/igt_core.h b/lib/igt_core.h
index 6f8c3852a686..beec34667524 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -795,6 +795,7 @@ bool __igt_fork_helper(struct igt_helper_process *proc);
 	for (; __igt_fork_helper(proc); exit(0))
 int igt_wait_helper(struct igt_helper_process *proc);
 void igt_stop_helper(struct igt_helper_process *proc);
+void igt_try_stop_helper(struct igt_helper_process *proc);
 
 /* exit handler code */
 
diff --git a/tests/i915/gem_shrink.c b/tests/i915/gem_shrink.c
index c8e05814ee70..0071c1ae21ff 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #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 = { .use_SIGKILL = true };
+		struct igt_helper_process mem_child = { .use_SIGKILL = true };
+
+		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_try_stop_helper(&mem_child);
+		igt_try_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)
-- 
2.19.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2018-12-07 10:14 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-07  8:59 [igt-dev] [RFT i-g-t 1/2] tests/gem_shrink: Background, direct and OOM shrinker plus userptr tests Tvrtko Ursulin
2018-12-07  8:59 ` [Intel-gfx] [RFT i-g-t 2/2] intel-ci: Unblack list the new tests?? Tvrtko Ursulin
2018-12-07  9:24 ` [igt-dev] ✗ Fi.CI.BAT: failure for series starting with [RFT,i-g-t,1/2] tests/gem_shrink: Background, direct and OOM shrinker plus userptr tests Patchwork
2018-12-07 10:14 ` Tvrtko Ursulin [this message]
2018-12-07 10:17   ` [igt-dev] [Intel-gfx] [RFT i-g-t 1/2] " Chris Wilson
2018-12-07 10:28     ` Tvrtko Ursulin
2018-12-07 14:04   ` Tvrtko Ursulin
2018-12-07 14:06     ` [igt-dev] " Chris Wilson
2018-12-07 14:13       ` Tvrtko Ursulin
2018-12-07 10:41 ` [igt-dev] ✓ Fi.CI.BAT: success for series starting with [RFT,i-g-t,1/2] tests/gem_shrink: Background, direct and OOM shrinker plus userptr tests (rev2) Patchwork
2018-12-07 15:25 ` [igt-dev] ✓ Fi.CI.BAT: success for series starting with [RFT,i-g-t,1/2] tests/gem_shrink: Background, direct and OOM shrinker plus userptr tests (rev3) Patchwork
2018-12-07 15:56 ` [igt-dev] ✓ Fi.CI.IGT: success for series starting with [RFT,i-g-t,1/2] tests/gem_shrink: Background, direct and OOM shrinker plus userptr tests (rev2) Patchwork
2018-12-07 22:19 ` [igt-dev] ✓ Fi.CI.IGT: success for series starting with [RFT,i-g-t,1/2] tests/gem_shrink: Background, direct and OOM shrinker plus userptr tests (rev3) 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=20181207101453.25199-1-tvrtko.ursulin@linux.intel.com \
    --to=tvrtko.ursulin@linux.intel.com \
    --cc=Intel-gfx@lists.freedesktop.org \
    --cc=igt-dev@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