diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2020-11-10 00:07:06 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2020-11-10 02:09:44 +0000 |
commit | 441383287ddc51b582bb7ae7040fae81084597d9 (patch) | |
tree | 17c3d75d58c6b70c4a0e4bc0ab0f02c924767c14 /tests/i915/gem_userptr_blits.c | |
parent | 63a36b65f78111bbc0c23d23600d139d89a6f637 (diff) |
i915/gem_userptr_blits: Exercise vma-merges
Inspect the impact of modifying neighbouring vma to an active userptr.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Diffstat (limited to 'tests/i915/gem_userptr_blits.c')
-rw-r--r-- | tests/i915/gem_userptr_blits.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c index 67380dad..7ab86ace 100644 --- a/tests/i915/gem_userptr_blits.c +++ b/tests/i915/gem_userptr_blits.c @@ -697,6 +697,115 @@ static void test_nohangcheck_hostile(int i915) close(i915); } +static size_t hugepagesize(void) +{ +#define LINE "Hugepagesize:" + size_t sz = 2 << 20; + char *line = NULL; + size_t len = 0; + FILE *file; + + file = fopen("/proc/meminfo", "r"); + if (!file) + return sz; + + while (getline(&line, &len, file) > 0) { + if (strncmp(line, LINE, strlen(LINE))) + continue; + + if (sscanf(line + strlen(LINE), "%zu", &sz) == 1) { + sz <<= 10; + igt_debug("Found huge page size: %lu\n", sz); + } + break; + } + free(line); + fclose(file); + + return sz; +#undef LINE +} + +static void test_vma_merge(int i915) +{ + const size_t sz = 2 * hugepagesize(); + igt_spin_t *spin; + uint32_t handle; + void *addr; + + addr = mmap(NULL, sz, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + + gem_userptr(i915, addr + sz / 2, 4096, 0, userptr_flags, &handle); + + spin = igt_spin_new(i915, .dependency = handle, .flags = IGT_SPIN_FENCE_OUT); + igt_assert(gem_bo_busy(i915, handle)); + + for (size_t x = 0; x < sz; x += 4096) { + if (x == sz / 2) + continue; + + igt_assert(mmap(addr + x, 4096, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED | MAP_ANON, -1, 0) != + MAP_FAILED); + } + + igt_spin_end(spin); + gem_close(i915, handle); + + munmap(addr, sz); + + gem_sync(i915, spin->handle); + igt_assert_eq(sync_fence_status(spin->out_fence), 1); + igt_spin_free(i915, spin); +} + +static void test_huge_split(int i915) +{ + const size_t sz = 2 * hugepagesize(); + unsigned int flags = MFD_HUGETLB | MFD_HUGE_2MB; + igt_spin_t *spin; + uint32_t handle; + void *addr; + + do { + int memfd; + + memfd = memfd_create("huge", flags); + igt_require(memfd != -1); + igt_require(ftruncate(memfd, sz) == 0); + + addr = mmap(NULL, sz, PROT_WRITE, MAP_SHARED, memfd, 0); + close(memfd); + if (addr != MAP_FAILED) + break; + + igt_require(flags); + flags = 0; + } while (1); + madvise(addr, sz, MADV_HUGEPAGE); + + gem_userptr(i915, addr + sz / 2 - 4096, 8192, 0, userptr_flags, &handle); + spin = igt_spin_new(i915, .dependency = handle, .flags = IGT_SPIN_FENCE_OUT); + igt_assert(gem_bo_busy(i915, handle)); + + igt_assert(mmap(addr, 4096, PROT_READ, + MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0) != + MAP_FAILED); + igt_assert(mmap(addr + sz - 4096, 4096, PROT_READ, + MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0) != + MAP_FAILED); + + igt_spin_end(spin); + gem_close(i915, handle); + + munmap(addr, sz); + + gem_sync(i915, spin->handle); + igt_assert_eq(sync_fence_status(spin->out_fence), 1); + igt_spin_free(i915, spin); +} + static int test_access_control(int fd) { /* CAP_SYS_ADMIN is needed for UNSYNCHRONIZED mappings. */ @@ -2530,6 +2639,12 @@ igt_main_args("c:", NULL, help_str, opt_handler, NULL) igt_subtest("nohangcheck") test_nohangcheck_hostile(fd); + + igt_subtest("vma-merge") + test_vma_merge(fd); + + igt_subtest("huge-split") + test_huge_split(fd); } igt_subtest("access-control") |