summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-12-21 08:34:02 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2018-03-15 10:52:37 +0000
commit24389b1041558553b85449f10bafe917be19aa28 (patch)
tree2c134166a43e66e05da5665cd4c52313fc9897fc
parent51287f3cedcb2751fd9bb88e5665dbe09dbed420 (diff)
igt/syncobj: Stress handle->fd/close
Dave found a bug where creating and closing an fd twice from the syncobj would lead to a crash. In addition to explicitly testing for a previous bug, include a stress test that covers a few more permutations of the create/close pattern to see if can uncover a race in future. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Dave Airlie <airlied@redhat.com>
-rw-r--r--tests/syncobj_basic.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/tests/syncobj_basic.c b/tests/syncobj_basic.c
index 44769d3b..6cfe1413 100644
--- a/tests/syncobj_basic.c
+++ b/tests/syncobj_basic.c
@@ -177,6 +177,43 @@ test_valid_cycle(int fd)
syncobj_destroy(fd, second_handle);
}
+static void
+stress_close_race(int fd, int timeout_ms)
+{
+ const unsigned int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
+ uint32_t handle;
+ int *done;
+
+ handle = syncobj_create(fd, 0);
+ done = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+
+ igt_fork(child, 2*ncpus + 1) {
+ const unsigned int sz = 5*child + 1;
+ int syncobj[sz];
+
+ for (unsigned int i = 0; i < sz; i++)
+ syncobj[i] = syncobj_handle_to_fd(fd, handle, 0);
+
+ do {
+ igt_permute_array(syncobj, sz, igt_exchange_int);
+ for (unsigned int i = 0; i < sz; i++) {
+ close(syncobj[i]);
+ syncobj[i] =
+ syncobj_handle_to_fd(fd, handle, 0);
+ }
+ } while (!*done);
+
+ for (unsigned int i = 0; i < sz; i++)
+ close(syncobj[i]);
+ }
+ usleep(timeout_ms * 1000);
+ *done = 1;
+ igt_waitchildren();
+
+ munmap(done, 4096);
+ syncobj_destroy(fd, handle);
+}
+
static bool has_syncobj(int fd)
{
uint64_t value;
@@ -231,4 +268,6 @@ igt_main
igt_subtest("test-valid-cycle")
test_valid_cycle(fd);
+ igt_subtest("stress-close-race")
+ stress_close_race(fd, 1000);
}