From cfbd09d6a64eea63a935ad72908bbc36be8b6724 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 30 Sep 2016 13:41:30 +0100 Subject: igt/vgem: Add a basic test for handling of module unload We found a bug where a dmabuf did not keep the module alive (and so when i915 tried to use it later, it exploded). Signed-off-by: Chris Wilson --- tests/vgem_basic.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'tests/vgem_basic.c') diff --git a/tests/vgem_basic.c b/tests/vgem_basic.c index 591973d0..263ea5f0 100644 --- a/tests/vgem_basic.c +++ b/tests/vgem_basic.c @@ -188,6 +188,7 @@ static void test_dmabuf_fence(int fd) igt_assert(!prime_busy(dmabuf, false)); igt_assert(!prime_busy(dmabuf, true)); + close(dmabuf); gem_close(fd, bo.handle); } @@ -212,7 +213,9 @@ static void test_dmabuf_fence_before(int fd) igt_assert(!prime_busy(dmabuf, false)); igt_assert(!prime_busy(dmabuf, true)); + close(dmabuf); gem_close(fd, bo.handle); + vgem_create(fd, &bo); fence = vgem_fence_attach(fd, &bo, VGEM_FENCE_WRITE); @@ -224,6 +227,7 @@ static void test_dmabuf_fence_before(int fd) igt_assert(!prime_busy(dmabuf, false)); igt_assert(!prime_busy(dmabuf, true)); + close(dmabuf); gem_close(fd, bo.handle); } @@ -284,6 +288,79 @@ static void test_debugfs_read(int fd) close(dir); } +static int module_unload(void) +{ + return system("/sbin/modprobe -s -r vgem"); +} + +static void test_unload(void) +{ + struct vgem_bo bo; + int vgem, dmabuf; + uint32_t *ptr; + + igt_require(module_unload() == 0); + + vgem = __drm_open_driver(DRIVER_VGEM); + igt_assert(vgem != -1); + + /* The driver should stop the module from unloading */ + igt_assert_f(module_unload() != 0, + "open(//dev/vgem) should keep the module alive\n"); + + bo.width = 1024; + bo.height = 1; + bo.bpp = 32; + vgem_create(vgem, &bo); + close(vgem); + + /* Closing the driver should clear all normal references */ + igt_assert_f(module_unload() == 0, + "No open(/dev/vgem), should be able to unload\n"); + + vgem = __drm_open_driver(DRIVER_VGEM); + igt_assert(vgem != -1); + bo.width = 1024; + bo.height = 1; + bo.bpp = 32; + vgem_create(vgem, &bo); + dmabuf = prime_handle_to_fd(vgem, bo.handle); + close(vgem); + + /* A dmabuf should prevent module unload. */ + igt_assert_f(module_unload() != 0, + "A dmabuf should keep the module alive\n"); + + close(dmabuf); + igt_assert_f(module_unload() == 0, + "No open dmabuf, should be able to unload\n"); + + vgem = __drm_open_driver(DRIVER_VGEM); + igt_assert(vgem != -1); + bo.width = 1024; + bo.height = 1; + bo.bpp = 32; + vgem_create(vgem, &bo); + dmabuf = prime_handle_to_fd_for_mmap(vgem, bo.handle); + close(vgem); + + ptr = mmap(NULL, bo.size, PROT_WRITE, MAP_SHARED, dmabuf, 0); + igt_assert(ptr != MAP_FAILED); + close(dmabuf); + + /* Although closed, the mmap should keep the dmabuf/module alive */ + igt_assert_f(module_unload() != 0, + "A mmap should keep the module alive\n"); + + for (int page = 0; page < bo.size >> 12; page++) + ptr[1024*page + page%1024] = page; + + /* And finally we should have no more uses on the module. */ + munmap(ptr, bo.size); + igt_assert_f(module_unload() == 0, + "No open mmap, should be able to unload\n"); +} + static bool has_prime_export(int fd) { uint64_t value; @@ -298,6 +375,9 @@ igt_main { int fd = -1; + igt_subtest("unload") + test_unload(); + igt_fixture { fd = drm_open_driver(DRIVER_VGEM); } -- cgit v1.2.3