summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-01-07 11:19:26 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2016-01-19 14:03:15 +0000
commit42291f25100cd01653b3fb3a2a1fbe6975e9c1bf (patch)
tree614482a391de4afb27c02780f24ee58c93300d2e
parent51e965f299284b3c9b96ac5e384ddeb22bd8d1fd (diff)
gem_concurrent_blit: Don't call igt_require() outside of a subtest/fixture
gem_concurrent_blit tries to ensure that it doesn't try and run a test that would grind the system to a halt, i.e. unexpectedly cause swap thrashing. It currently calls intel_require_memory(), but outside of the subtest (as the tests use fork, it cannot do requirement testing within the test children) - but intel_require_memory() calls igt_require() and triggers and abort. Wrapping that initial require within an igt_fixture() stops the abort(), but also prevents any further testing. This patch restructures the requirement checking to ordinary conditions, which though allowing the test to run, also prevents listing of subtests on machines which cannot handle them.
-rw-r--r--lib/igt_aux.h2
-rw-r--r--lib/intel_os.c53
-rw-r--r--tests/gem_concurrent_all.c68
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;
+ }
}
}
}