Quoting Tvrtko Ursulin (2019-01-07 18:22:44) > From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> > > A set of subtests which exercises different paths to our shrinker code > (including the OOM killer) in predictable and reasonable time budget. > > v2: > * Fix blacklist regexp. (Petri Latvala) > > v3: > * Skip userptr test if not userptr support. > > Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> > --- > lib/igt_core.c | 19 ++ > lib/igt_core.h | 1 + > tests/i915/gem_shrink.c | 401 ++++++++++++++++++++++++++ > tests/intel-ci/blacklist.txt | 2 +- > tests/intel-ci/fast-feedback.testlist | 3 + > 5 files changed, 425 insertions(+), 1 deletion(-) > > diff --git a/lib/igt_core.c b/lib/igt_core.c > index 50d6008f6c82..351da0b4e020 100644 > --- a/lib/igt_core.c > +++ b/lib/igt_core.c > @@ -1685,6 +1685,25 @@ 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 and returns true, or false > + * if the process wasn't running. > + */ > +bool 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); > + > + return helper_was_alive(proc, status); > +} > + > static void children_exit_handler(int sig) > { > int status; > diff --git a/lib/igt_core.h b/lib/igt_core.h > index 6f8c3852a686..ed5ceebf1205 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); > +bool 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..3d48cbebc2f9 100644 > --- a/tests/i915/gem_shrink.c > +++ b/tests/i915/gem_shrink.c > @@ -26,6 +26,10 @@ > * > * Exercise the shrinker by overallocating GEM objects > */ > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <sys/wait.h> > +#include <fcntl.h> > > #include "igt.h" > #include "igt_gt.h" > @@ -366,6 +370,378 @@ 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); Only needs DOMAIN_CPU for us to call get_pages() and then avoids excessive clflushing on !llc. (mempressure path, so I'm not sure if you want to argue about exercising the clflush paths against mempressure. I'd hope gem_shrink already covers that elsewhere...) > + gem_madvise(fd, handle, I915_MADV_DONTNEED); > + > + return handle; > +} > +/* > + * Use a specific way of using up memory until we are below a certain threshold. > + */ > +static void *mempressure(void *arg) > +{ > + const unsigned int free_threshold_mb = 256; > + 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; > + > + for (;;) { > + unsigned long ram_mb = get_avail_ram_mb(); ... > + /* > + * Allocate memory blocks and record the current working set > + * size. > + */ > + if (test->flags & TEST_BO) { > + list[n].handle = __get_pages(test->fd, sz); Under discussion is that in using gem_create() our bo are accounted by Cached: in /proc/meminfo. That is we never _appear_ to decrease avail_ram_mb when for TEST_BO. One hack for drm-tip (since we now mark shmemfs objects as unevictable) would be to use ram -= get_meminfo(buf, "Unevictable:"); -Chris _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx