diff options
-rw-r--r-- | lib/igt_aux.h | 2 | ||||
-rw-r--r-- | lib/intel_os.c | 53 | ||||
-rw-r--r-- | tests/gem_concurrent_all.c | 68 |
3 files changed, 85 insertions, 38 deletions
diff --git a/lib/igt_aux.h b/lib/igt_aux.h index 95028665..82bd5962 100644 --- a/lib/igt_aux.h +++ b/lib/igt_aux.h @@ -86,6 +86,8 @@ uint64_t intel_get_avail_ram_mb(void); uint64_t intel_get_total_ram_mb(void); uint64_t intel_get_total_swap_mb(void); +int __intel_check_memory(uint32_t count, uint64_t size, unsigned mode, + uint64_t *out_required, uint64_t *out_total); void intel_require_memory(uint32_t count, uint64_t size, unsigned mode); #define CHECK_RAM 0x1 #define CHECK_SWAP 0x2 diff --git a/lib/intel_os.c b/lib/intel_os.c index 06361f4c..64e37222 100644 --- a/lib/intel_os.c +++ b/lib/intel_os.c @@ -192,6 +192,38 @@ intel_get_total_swap_mb(void) return retval / (1024*1024); } +int __intel_check_memory(uint32_t count, uint64_t size, unsigned mode, + uint64_t *out_required, uint64_t *out_total) +{ +/* rough estimate of how many bytes the kernel requires to track each object */ +#define KERNEL_BO_OVERHEAD 512 + uint64_t required, total; + + required = count; + required *= size + KERNEL_BO_OVERHEAD; + required = ALIGN(required, 4096); + + igt_debug("Checking %'u surfaces of size %'llu bytes (total %'llu) against %s%s\n", + count, (long long)size, (long long)required, + mode & (CHECK_RAM | CHECK_SWAP) ? "RAM" : "", + mode & CHECK_SWAP ? " + swap": ""); + + total = 0; + if (mode & (CHECK_RAM | CHECK_SWAP)) + total += intel_get_avail_ram_mb(); + if (mode & CHECK_SWAP) + total += intel_get_total_swap_mb(); + total *= 1024 * 1024; + + if (out_required) + *out_required = required; + + if (out_total) + *out_total = total; + + return required < total; +} + /** * intel_require_memory: * @count: number of surfaces that will be created @@ -217,27 +249,10 @@ intel_get_total_swap_mb(void) */ void intel_require_memory(uint32_t count, uint64_t size, unsigned mode) { -/* rough estimate of how many bytes the kernel requires to track each object */ -#define KERNEL_BO_OVERHEAD 512 uint64_t required, total; - required = count; - required *= size + KERNEL_BO_OVERHEAD; - required = ALIGN(required, 4096); - - igt_debug("Checking %'u surfaces of size %'llu bytes (total %'llu) against %s%s\n", - count, (long long)size, (long long)required, - mode & (CHECK_RAM | CHECK_SWAP) ? "RAM" : "", - mode & CHECK_SWAP ? " + swap": ""); - - total = 0; - if (mode & (CHECK_RAM | CHECK_SWAP)) - total += intel_get_avail_ram_mb(); - if (mode & CHECK_SWAP) - total += intel_get_total_swap_mb(); - total *= 1024 * 1024; - - igt_skip_on_f(total <= required, + igt_skip_on_f(!__intel_check_memory(count, size, mode, + &required, &total), "Estimated that we need %'llu bytes for the test, but only have %'llu bytes available (%s%s)\n", (long long)required, (long long)total, mode & (CHECK_RAM | CHECK_SWAP) ? "RAM" : "", diff --git a/tests/gem_concurrent_all.c b/tests/gem_concurrent_all.c index 558b9c13..a7db23cb 100644 --- a/tests/gem_concurrent_all.c +++ b/tests/gem_concurrent_all.c @@ -155,9 +155,9 @@ static bool can_create_stolen(void) static drm_intel_bo * (*create_func)(drm_intel_bufmgr *bufmgr, uint64_t size); -static void create_cpu_require(void) +static bool create_cpu_require(void) { - igt_require(create_func != create_stolen_bo); + return create_func != create_stolen_bo; } static drm_intel_bo * @@ -375,7 +375,7 @@ gpu_cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height, drm_intel_bo * const struct access_mode { const char *name; - void (*require)(void); + bool (*require)(void); void (*set_bo)(drm_intel_bo *bo, uint32_t val, int w, int h); void (*cmp_bo)(drm_intel_bo *bo, uint32_t val, int w, int h, drm_intel_bo *tmp); drm_intel_bo *(*create_bo)(drm_intel_bufmgr *bufmgr, int width, int height); @@ -1321,24 +1321,22 @@ run_basic_modes(const char *prefix, } static void -run_modes(const char *style, const struct access_mode *mode) +run_modes(const char *style, const struct access_mode *mode, unsigned allow_mem) { - if (mode->require) - mode->require(); - - igt_debug("%s: using 2x%d buffers, each 1MiB\n", style, num_buffers); - intel_require_memory(2*num_buffers, 1024*1024, CHECK_RAM); + if (mode->require && !mode->require()) + return; - if (all) { - run_basic_modes(style, mode, "", run_single); + igt_debug("%s: using 2x%d buffers, each 1MiB\n", + style, num_buffers); + if (!__intel_check_memory(2*num_buffers, 1024*1024, allow_mem, + NULL, NULL)) + return; - igt_fork_signal_helper(); - run_basic_modes(style, mode, "-interruptible", run_interruptible); - igt_stop_signal_helper(); - } + run_basic_modes(style, mode, "", run_single); + run_basic_modes(style, mode, "-forked", run_forked); igt_fork_signal_helper(); - run_basic_modes(style, mode, "-forked", run_forked); + run_basic_modes(style, mode, "-interruptible", run_interruptible); run_basic_modes(style, mode, "-bomb", run_bomb); igt_stop_signal_helper(); } @@ -1355,6 +1353,8 @@ igt_main { "stolen-", create_stolen_bo, can_create_stolen }, { NULL, NULL } }, *c; + uint64_t pin_sz = 0; + void *pinned = NULL; int i; igt_skip_on_simulation(); @@ -1381,7 +1381,7 @@ igt_main if (c->require()) { snprintf(name, sizeof(name), "%s%s", c->name, "small"); for (i = 0; i < ARRAY_SIZE(access_modes); i++) - run_modes(name, &access_modes[i]); + run_modes(name, &access_modes[i], CHECK_RAM); } igt_fixture { @@ -1391,7 +1391,7 @@ igt_main if (c->require()) { snprintf(name, sizeof(name), "%s%s", c->name, "thrash"); for (i = 0; i < ARRAY_SIZE(access_modes); i++) - run_modes(name, &access_modes[i]); + run_modes(name, &access_modes[i], CHECK_RAM); } igt_fixture { @@ -1401,7 +1401,37 @@ igt_main if (c->require()) { snprintf(name, sizeof(name), "%s%s", c->name, "full"); for (i = 0; i < ARRAY_SIZE(access_modes); i++) - run_modes(name, &access_modes[i]); + run_modes(name, &access_modes[i], CHECK_RAM); + } + + igt_fixture { + num_buffers = gem_mappable_aperture_size() / (1024 * 1024); + pin_sz = intel_get_avail_ram_mb() - num_buffers; + + igt_debug("Pinning %ld MiB\n", pin_sz); + pin_sz *= 1024 * 1024; + + if (posix_memalign(&pinned, 4096, pin_sz) || + mlock(pinned, pin_sz) || + madvise(pinned, pin_sz, MADV_DONTFORK)) { + free(pinned); + pinned = NULL; + } + igt_require(pinned); + } + + if (c->require()) { + snprintf(name, sizeof(name), "%s%s", c->name, "swap"); + for (i = 0; i < ARRAY_SIZE(access_modes); i++) + run_modes(name, &access_modes[i], CHECK_RAM | CHECK_SWAP); + } + + igt_fixture { + if (pinned) { + munlock(pinned, pin_sz); + free(pinned); + pinned = NULL; + } } } } |