xref: /aosp_15_r20/external/igt-gpu-tools/tests/syncobj_wait.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2017 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  */
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
25*d83cc019SAndroid Build Coastguard Worker #include "sw_sync.h"
26*d83cc019SAndroid Build Coastguard Worker #include "igt_syncobj.h"
27*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
28*d83cc019SAndroid Build Coastguard Worker #include <time.h>
29*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
30*d83cc019SAndroid Build Coastguard Worker #include <pthread.h>
31*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
32*d83cc019SAndroid Build Coastguard Worker #include "drm.h"
33*d83cc019SAndroid Build Coastguard Worker #include <strings.h>
34*d83cc019SAndroid Build Coastguard Worker 
35*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Tests for the drm sync object wait API");
36*d83cc019SAndroid Build Coastguard Worker 
37*d83cc019SAndroid Build Coastguard Worker /* One tenth of a second */
38*d83cc019SAndroid Build Coastguard Worker #define SHORT_TIME_NSEC 100000000ull
39*d83cc019SAndroid Build Coastguard Worker 
40*d83cc019SAndroid Build Coastguard Worker #define NSECS_PER_SEC 1000000000ull
41*d83cc019SAndroid Build Coastguard Worker 
42*d83cc019SAndroid Build Coastguard Worker static uint64_t
gettime_ns(void)43*d83cc019SAndroid Build Coastguard Worker gettime_ns(void)
44*d83cc019SAndroid Build Coastguard Worker {
45*d83cc019SAndroid Build Coastguard Worker 	struct timespec current;
46*d83cc019SAndroid Build Coastguard Worker 	clock_gettime(CLOCK_MONOTONIC, &current);
47*d83cc019SAndroid Build Coastguard Worker 	return (uint64_t)current.tv_sec * NSECS_PER_SEC + current.tv_nsec;
48*d83cc019SAndroid Build Coastguard Worker }
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker static void
sleep_nsec(uint64_t time_nsec)51*d83cc019SAndroid Build Coastguard Worker sleep_nsec(uint64_t time_nsec)
52*d83cc019SAndroid Build Coastguard Worker {
53*d83cc019SAndroid Build Coastguard Worker 	struct timespec t;
54*d83cc019SAndroid Build Coastguard Worker 	t.tv_sec = time_nsec / NSECS_PER_SEC;
55*d83cc019SAndroid Build Coastguard Worker 	t.tv_nsec = time_nsec % NSECS_PER_SEC;
56*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(nanosleep(&t, NULL), 0);
57*d83cc019SAndroid Build Coastguard Worker }
58*d83cc019SAndroid Build Coastguard Worker 
59*d83cc019SAndroid Build Coastguard Worker static uint64_t
short_timeout(void)60*d83cc019SAndroid Build Coastguard Worker short_timeout(void)
61*d83cc019SAndroid Build Coastguard Worker {
62*d83cc019SAndroid Build Coastguard Worker 	return gettime_ns() + SHORT_TIME_NSEC;
63*d83cc019SAndroid Build Coastguard Worker }
64*d83cc019SAndroid Build Coastguard Worker 
65*d83cc019SAndroid Build Coastguard Worker static int
syncobj_attach_sw_sync(int fd,uint32_t handle)66*d83cc019SAndroid Build Coastguard Worker syncobj_attach_sw_sync(int fd, uint32_t handle)
67*d83cc019SAndroid Build Coastguard Worker {
68*d83cc019SAndroid Build Coastguard Worker 	struct drm_syncobj_handle;
69*d83cc019SAndroid Build Coastguard Worker 	int timeline, fence;
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker 	timeline = sw_sync_timeline_create();
72*d83cc019SAndroid Build Coastguard Worker 	fence = sw_sync_timeline_create_fence(timeline, 1);
73*d83cc019SAndroid Build Coastguard Worker 	syncobj_import_sync_file(fd, handle, fence);
74*d83cc019SAndroid Build Coastguard Worker 	close(fence);
75*d83cc019SAndroid Build Coastguard Worker 
76*d83cc019SAndroid Build Coastguard Worker 	return timeline;
77*d83cc019SAndroid Build Coastguard Worker }
78*d83cc019SAndroid Build Coastguard Worker 
79*d83cc019SAndroid Build Coastguard Worker static void
syncobj_trigger(int fd,uint32_t handle)80*d83cc019SAndroid Build Coastguard Worker syncobj_trigger(int fd, uint32_t handle)
81*d83cc019SAndroid Build Coastguard Worker {
82*d83cc019SAndroid Build Coastguard Worker 	int timeline = syncobj_attach_sw_sync(fd, handle);
83*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(timeline, 1);
84*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
85*d83cc019SAndroid Build Coastguard Worker }
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker static timer_t
set_timer(void (* cb)(union sigval),void * ptr,int i,uint64_t nsec)88*d83cc019SAndroid Build Coastguard Worker set_timer(void (*cb)(union sigval), void *ptr, int i, uint64_t nsec)
89*d83cc019SAndroid Build Coastguard Worker {
90*d83cc019SAndroid Build Coastguard Worker         timer_t timer;
91*d83cc019SAndroid Build Coastguard Worker         struct sigevent sev;
92*d83cc019SAndroid Build Coastguard Worker         struct itimerspec its;
93*d83cc019SAndroid Build Coastguard Worker 
94*d83cc019SAndroid Build Coastguard Worker         memset(&sev, 0, sizeof(sev));
95*d83cc019SAndroid Build Coastguard Worker         sev.sigev_notify = SIGEV_THREAD;
96*d83cc019SAndroid Build Coastguard Worker 	if (ptr)
97*d83cc019SAndroid Build Coastguard Worker 		sev.sigev_value.sival_ptr = ptr;
98*d83cc019SAndroid Build Coastguard Worker 	else
99*d83cc019SAndroid Build Coastguard Worker 		sev.sigev_value.sival_int = i;
100*d83cc019SAndroid Build Coastguard Worker         sev.sigev_notify_function = cb;
101*d83cc019SAndroid Build Coastguard Worker         igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
102*d83cc019SAndroid Build Coastguard Worker 
103*d83cc019SAndroid Build Coastguard Worker         memset(&its, 0, sizeof(its));
104*d83cc019SAndroid Build Coastguard Worker         its.it_value.tv_sec = nsec / NSEC_PER_SEC;
105*d83cc019SAndroid Build Coastguard Worker         its.it_value.tv_nsec = nsec % NSEC_PER_SEC;
106*d83cc019SAndroid Build Coastguard Worker         igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
107*d83cc019SAndroid Build Coastguard Worker 
108*d83cc019SAndroid Build Coastguard Worker 	return timer;
109*d83cc019SAndroid Build Coastguard Worker }
110*d83cc019SAndroid Build Coastguard Worker 
111*d83cc019SAndroid Build Coastguard Worker struct fd_handle_pair {
112*d83cc019SAndroid Build Coastguard Worker 	int fd;
113*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
114*d83cc019SAndroid Build Coastguard Worker };
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker static void
timeline_inc_func(union sigval sigval)117*d83cc019SAndroid Build Coastguard Worker timeline_inc_func(union sigval sigval)
118*d83cc019SAndroid Build Coastguard Worker {
119*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(sigval.sival_int, 1);
120*d83cc019SAndroid Build Coastguard Worker }
121*d83cc019SAndroid Build Coastguard Worker 
122*d83cc019SAndroid Build Coastguard Worker static void
syncobj_trigger_free_pair_func(union sigval sigval)123*d83cc019SAndroid Build Coastguard Worker syncobj_trigger_free_pair_func(union sigval sigval)
124*d83cc019SAndroid Build Coastguard Worker {
125*d83cc019SAndroid Build Coastguard Worker 	struct fd_handle_pair *pair = sigval.sival_ptr;
126*d83cc019SAndroid Build Coastguard Worker 	syncobj_trigger(pair->fd, pair->handle);
127*d83cc019SAndroid Build Coastguard Worker 	free(pair);
128*d83cc019SAndroid Build Coastguard Worker }
129*d83cc019SAndroid Build Coastguard Worker 
130*d83cc019SAndroid Build Coastguard Worker static timer_t
syncobj_trigger_delayed(int fd,uint32_t syncobj,uint64_t nsec)131*d83cc019SAndroid Build Coastguard Worker syncobj_trigger_delayed(int fd, uint32_t syncobj, uint64_t nsec)
132*d83cc019SAndroid Build Coastguard Worker {
133*d83cc019SAndroid Build Coastguard Worker 	struct fd_handle_pair *pair = malloc(sizeof(*pair));
134*d83cc019SAndroid Build Coastguard Worker 
135*d83cc019SAndroid Build Coastguard Worker 	pair->fd = fd;
136*d83cc019SAndroid Build Coastguard Worker 	pair->handle = syncobj;
137*d83cc019SAndroid Build Coastguard Worker 
138*d83cc019SAndroid Build Coastguard Worker 	return set_timer(syncobj_trigger_free_pair_func, pair, 0, nsec);
139*d83cc019SAndroid Build Coastguard Worker }
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker static void
test_wait_bad_flags(int fd)142*d83cc019SAndroid Build Coastguard Worker test_wait_bad_flags(int fd)
143*d83cc019SAndroid Build Coastguard Worker {
144*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_wait wait = { 0 };
145*d83cc019SAndroid Build Coastguard Worker 	wait.flags = 0xdeadbeef;
146*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_wait(fd, &wait), -EINVAL);
147*d83cc019SAndroid Build Coastguard Worker }
148*d83cc019SAndroid Build Coastguard Worker 
149*d83cc019SAndroid Build Coastguard Worker static void
test_wait_zero_handles(int fd)150*d83cc019SAndroid Build Coastguard Worker test_wait_zero_handles(int fd)
151*d83cc019SAndroid Build Coastguard Worker {
152*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_wait wait = { 0 };
153*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_wait(fd, &wait), -EINVAL);
154*d83cc019SAndroid Build Coastguard Worker }
155*d83cc019SAndroid Build Coastguard Worker 
156*d83cc019SAndroid Build Coastguard Worker static void
test_wait_illegal_handle(int fd)157*d83cc019SAndroid Build Coastguard Worker test_wait_illegal_handle(int fd)
158*d83cc019SAndroid Build Coastguard Worker {
159*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_wait wait = { 0 };
160*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = 0;
161*d83cc019SAndroid Build Coastguard Worker 
162*d83cc019SAndroid Build Coastguard Worker 	wait.count_handles = 1;
163*d83cc019SAndroid Build Coastguard Worker 	wait.handles = to_user_pointer(&handle);
164*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_wait(fd, &wait), -ENOENT);
165*d83cc019SAndroid Build Coastguard Worker }
166*d83cc019SAndroid Build Coastguard Worker 
167*d83cc019SAndroid Build Coastguard Worker static void
test_reset_zero_handles(int fd)168*d83cc019SAndroid Build Coastguard Worker test_reset_zero_handles(int fd)
169*d83cc019SAndroid Build Coastguard Worker {
170*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_array array = { 0 };
171*d83cc019SAndroid Build Coastguard Worker 	int ret;
172*d83cc019SAndroid Build Coastguard Worker 
173*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array);
174*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == -1 && errno ==  EINVAL);
175*d83cc019SAndroid Build Coastguard Worker }
176*d83cc019SAndroid Build Coastguard Worker 
177*d83cc019SAndroid Build Coastguard Worker static void
test_reset_illegal_handle(int fd)178*d83cc019SAndroid Build Coastguard Worker test_reset_illegal_handle(int fd)
179*d83cc019SAndroid Build Coastguard Worker {
180*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_array array = { 0 };
181*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = 0;
182*d83cc019SAndroid Build Coastguard Worker 	int ret;
183*d83cc019SAndroid Build Coastguard Worker 
184*d83cc019SAndroid Build Coastguard Worker 	array.count_handles = 1;
185*d83cc019SAndroid Build Coastguard Worker 	array.handles = to_user_pointer(&handle);
186*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array);
187*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == -1 && errno == ENOENT);
188*d83cc019SAndroid Build Coastguard Worker }
189*d83cc019SAndroid Build Coastguard Worker 
190*d83cc019SAndroid Build Coastguard Worker static void
test_reset_one_illegal_handle(int fd)191*d83cc019SAndroid Build Coastguard Worker test_reset_one_illegal_handle(int fd)
192*d83cc019SAndroid Build Coastguard Worker {
193*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_array array = { 0 };
194*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobjs[3];
195*d83cc019SAndroid Build Coastguard Worker 	int ret;
196*d83cc019SAndroid Build Coastguard Worker 
197*d83cc019SAndroid Build Coastguard Worker 	syncobjs[0] = syncobj_create(fd, LOCAL_SYNCOBJ_CREATE_SIGNALED);
198*d83cc019SAndroid Build Coastguard Worker 	syncobjs[1] = 0;
199*d83cc019SAndroid Build Coastguard Worker 	syncobjs[2] = syncobj_create(fd, LOCAL_SYNCOBJ_CREATE_SIGNALED);
200*d83cc019SAndroid Build Coastguard Worker 
201*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[0], 1, 0, 0), 0);
202*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[2], 1, 0, 0), 0);
203*d83cc019SAndroid Build Coastguard Worker 
204*d83cc019SAndroid Build Coastguard Worker 	array.count_handles = 3;
205*d83cc019SAndroid Build Coastguard Worker 	array.handles = to_user_pointer(syncobjs);
206*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array);
207*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == -1 && errno == ENOENT);
208*d83cc019SAndroid Build Coastguard Worker 
209*d83cc019SAndroid Build Coastguard Worker 	/* Assert that we didn't actually reset anything */
210*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[0], 1, 0, 0), 0);
211*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[2], 1, 0, 0), 0);
212*d83cc019SAndroid Build Coastguard Worker 
213*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[0]);
214*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[2]);
215*d83cc019SAndroid Build Coastguard Worker }
216*d83cc019SAndroid Build Coastguard Worker 
217*d83cc019SAndroid Build Coastguard Worker static void
test_reset_bad_pad(int fd)218*d83cc019SAndroid Build Coastguard Worker test_reset_bad_pad(int fd)
219*d83cc019SAndroid Build Coastguard Worker {
220*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_array array = { 0 };
221*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = 0;
222*d83cc019SAndroid Build Coastguard Worker 	int ret;
223*d83cc019SAndroid Build Coastguard Worker 
224*d83cc019SAndroid Build Coastguard Worker 	array.pad = 0xdeadbeef;
225*d83cc019SAndroid Build Coastguard Worker 	array.count_handles = 1;
226*d83cc019SAndroid Build Coastguard Worker 	array.handles = to_user_pointer(&handle);
227*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array);
228*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == -1 && errno == EINVAL);
229*d83cc019SAndroid Build Coastguard Worker }
230*d83cc019SAndroid Build Coastguard Worker 
231*d83cc019SAndroid Build Coastguard Worker static void
test_signal_zero_handles(int fd)232*d83cc019SAndroid Build Coastguard Worker test_signal_zero_handles(int fd)
233*d83cc019SAndroid Build Coastguard Worker {
234*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_array array = { 0 };
235*d83cc019SAndroid Build Coastguard Worker 	int ret;
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array);
238*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == -1 && errno == EINVAL);
239*d83cc019SAndroid Build Coastguard Worker }
240*d83cc019SAndroid Build Coastguard Worker 
241*d83cc019SAndroid Build Coastguard Worker static void
test_signal_illegal_handle(int fd)242*d83cc019SAndroid Build Coastguard Worker test_signal_illegal_handle(int fd)
243*d83cc019SAndroid Build Coastguard Worker {
244*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_array array = { 0 };
245*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = 0;
246*d83cc019SAndroid Build Coastguard Worker 	int ret;
247*d83cc019SAndroid Build Coastguard Worker 
248*d83cc019SAndroid Build Coastguard Worker 	array.count_handles = 1;
249*d83cc019SAndroid Build Coastguard Worker 	array.handles = to_user_pointer(&handle);
250*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array);
251*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == -1 && errno == ENOENT);
252*d83cc019SAndroid Build Coastguard Worker }
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker static void
test_signal_one_illegal_handle(int fd)255*d83cc019SAndroid Build Coastguard Worker test_signal_one_illegal_handle(int fd)
256*d83cc019SAndroid Build Coastguard Worker {
257*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_array array = { 0 };
258*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobjs[3];
259*d83cc019SAndroid Build Coastguard Worker 	int ret;
260*d83cc019SAndroid Build Coastguard Worker 
261*d83cc019SAndroid Build Coastguard Worker 	syncobjs[0] = syncobj_create(fd, 0);
262*d83cc019SAndroid Build Coastguard Worker 	syncobjs[1] = 0;
263*d83cc019SAndroid Build Coastguard Worker 	syncobjs[2] = syncobj_create(fd, 0);
264*d83cc019SAndroid Build Coastguard Worker 
265*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[0], 1, 0, 0), -EINVAL);
266*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[2], 1, 0, 0), -EINVAL);
267*d83cc019SAndroid Build Coastguard Worker 
268*d83cc019SAndroid Build Coastguard Worker 	array.count_handles = 3;
269*d83cc019SAndroid Build Coastguard Worker 	array.handles = to_user_pointer(syncobjs);
270*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array);
271*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == -1 && errno == ENOENT);
272*d83cc019SAndroid Build Coastguard Worker 
273*d83cc019SAndroid Build Coastguard Worker 	/* Assert that we didn't actually reset anything */
274*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[0], 1, 0, 0), -EINVAL);
275*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[2], 1, 0, 0), -EINVAL);
276*d83cc019SAndroid Build Coastguard Worker 
277*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[0]);
278*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[2]);
279*d83cc019SAndroid Build Coastguard Worker }
280*d83cc019SAndroid Build Coastguard Worker 
281*d83cc019SAndroid Build Coastguard Worker static void
test_signal_bad_pad(int fd)282*d83cc019SAndroid Build Coastguard Worker test_signal_bad_pad(int fd)
283*d83cc019SAndroid Build Coastguard Worker {
284*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_array array = { 0 };
285*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = 0;
286*d83cc019SAndroid Build Coastguard Worker 	int ret;
287*d83cc019SAndroid Build Coastguard Worker 
288*d83cc019SAndroid Build Coastguard Worker 	array.pad = 0xdeadbeef;
289*d83cc019SAndroid Build Coastguard Worker 	array.count_handles = 1;
290*d83cc019SAndroid Build Coastguard Worker 	array.handles = to_user_pointer(&handle);
291*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array);
292*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret == -1 && errno ==  EINVAL);
293*d83cc019SAndroid Build Coastguard Worker }
294*d83cc019SAndroid Build Coastguard Worker 
295*d83cc019SAndroid Build Coastguard Worker #define WAIT_FOR_SUBMIT		(1 << 0)
296*d83cc019SAndroid Build Coastguard Worker #define WAIT_ALL		(1 << 1)
297*d83cc019SAndroid Build Coastguard Worker #define WAIT_UNSUBMITTED	(1 << 2)
298*d83cc019SAndroid Build Coastguard Worker #define WAIT_SUBMITTED		(1 << 3)
299*d83cc019SAndroid Build Coastguard Worker #define WAIT_SIGNALED		(1 << 4)
300*d83cc019SAndroid Build Coastguard Worker #define WAIT_FLAGS_MAX		(1 << 5) - 1
301*d83cc019SAndroid Build Coastguard Worker 
302*d83cc019SAndroid Build Coastguard Worker static uint32_t
flags_for_test_flags(uint32_t test_flags)303*d83cc019SAndroid Build Coastguard Worker flags_for_test_flags(uint32_t test_flags)
304*d83cc019SAndroid Build Coastguard Worker {
305*d83cc019SAndroid Build Coastguard Worker 	uint32_t flags = 0;
306*d83cc019SAndroid Build Coastguard Worker 
307*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & WAIT_FOR_SUBMIT)
308*d83cc019SAndroid Build Coastguard Worker 		flags |= LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
309*d83cc019SAndroid Build Coastguard Worker 
310*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & WAIT_ALL)
311*d83cc019SAndroid Build Coastguard Worker 		flags |= LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_ALL;
312*d83cc019SAndroid Build Coastguard Worker 
313*d83cc019SAndroid Build Coastguard Worker 	return flags;
314*d83cc019SAndroid Build Coastguard Worker }
315*d83cc019SAndroid Build Coastguard Worker 
316*d83cc019SAndroid Build Coastguard Worker static void
test_single_wait(int fd,uint32_t test_flags,int expect)317*d83cc019SAndroid Build Coastguard Worker test_single_wait(int fd, uint32_t test_flags, int expect)
318*d83cc019SAndroid Build Coastguard Worker {
319*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobj = syncobj_create(fd, 0);
320*d83cc019SAndroid Build Coastguard Worker 	uint32_t flags = flags_for_test_flags(test_flags);
321*d83cc019SAndroid Build Coastguard Worker 	int timeline = -1;
322*d83cc019SAndroid Build Coastguard Worker 
323*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & (WAIT_SUBMITTED | WAIT_SIGNALED))
324*d83cc019SAndroid Build Coastguard Worker 		timeline = syncobj_attach_sw_sync(fd, syncobj);
325*d83cc019SAndroid Build Coastguard Worker 
326*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & WAIT_SIGNALED)
327*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(timeline, 1);
328*d83cc019SAndroid Build Coastguard Worker 
329*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, flags), expect);
330*d83cc019SAndroid Build Coastguard Worker 
331*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, short_timeout(),
332*d83cc019SAndroid Build Coastguard Worker 				       flags), expect);
333*d83cc019SAndroid Build Coastguard Worker 
334*d83cc019SAndroid Build Coastguard Worker 	if (expect != -ETIME) {
335*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, UINT64_MAX,
336*d83cc019SAndroid Build Coastguard Worker 					       flags), expect);
337*d83cc019SAndroid Build Coastguard Worker 	}
338*d83cc019SAndroid Build Coastguard Worker 
339*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobj);
340*d83cc019SAndroid Build Coastguard Worker 	if (timeline != -1)
341*d83cc019SAndroid Build Coastguard Worker 		close(timeline);
342*d83cc019SAndroid Build Coastguard Worker }
343*d83cc019SAndroid Build Coastguard Worker 
344*d83cc019SAndroid Build Coastguard Worker static void
test_wait_delayed_signal(int fd,uint32_t test_flags)345*d83cc019SAndroid Build Coastguard Worker test_wait_delayed_signal(int fd, uint32_t test_flags)
346*d83cc019SAndroid Build Coastguard Worker {
347*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobj = syncobj_create(fd, 0);
348*d83cc019SAndroid Build Coastguard Worker 	uint32_t flags = flags_for_test_flags(test_flags);
349*d83cc019SAndroid Build Coastguard Worker 	int timeline = -1;
350*d83cc019SAndroid Build Coastguard Worker 	timer_t timer;
351*d83cc019SAndroid Build Coastguard Worker 
352*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & WAIT_FOR_SUBMIT) {
353*d83cc019SAndroid Build Coastguard Worker 		timer = syncobj_trigger_delayed(fd, syncobj, SHORT_TIME_NSEC);
354*d83cc019SAndroid Build Coastguard Worker 	} else {
355*d83cc019SAndroid Build Coastguard Worker 		timeline = syncobj_attach_sw_sync(fd, syncobj);
356*d83cc019SAndroid Build Coastguard Worker 		timer = set_timer(timeline_inc_func, NULL,
357*d83cc019SAndroid Build Coastguard Worker 				  timeline, SHORT_TIME_NSEC);
358*d83cc019SAndroid Build Coastguard Worker 	}
359*d83cc019SAndroid Build Coastguard Worker 
360*d83cc019SAndroid Build Coastguard Worker 	igt_assert(syncobj_wait(fd, &syncobj, 1,
361*d83cc019SAndroid Build Coastguard Worker 				gettime_ns() + SHORT_TIME_NSEC * 2,
362*d83cc019SAndroid Build Coastguard Worker 				flags, NULL));
363*d83cc019SAndroid Build Coastguard Worker 
364*d83cc019SAndroid Build Coastguard Worker 	timer_delete(timer);
365*d83cc019SAndroid Build Coastguard Worker 
366*d83cc019SAndroid Build Coastguard Worker 	if (timeline != -1)
367*d83cc019SAndroid Build Coastguard Worker 		close(timeline);
368*d83cc019SAndroid Build Coastguard Worker 
369*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobj);
370*d83cc019SAndroid Build Coastguard Worker }
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker static void
test_reset_unsignaled(int fd)373*d83cc019SAndroid Build Coastguard Worker test_reset_unsignaled(int fd)
374*d83cc019SAndroid Build Coastguard Worker {
375*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobj = syncobj_create(fd, 0);
376*d83cc019SAndroid Build Coastguard Worker 
377*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, 0), -EINVAL);
378*d83cc019SAndroid Build Coastguard Worker 
379*d83cc019SAndroid Build Coastguard Worker 	syncobj_reset(fd, &syncobj, 1);
380*d83cc019SAndroid Build Coastguard Worker 
381*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, 0), -EINVAL);
382*d83cc019SAndroid Build Coastguard Worker 
383*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobj);
384*d83cc019SAndroid Build Coastguard Worker }
385*d83cc019SAndroid Build Coastguard Worker 
386*d83cc019SAndroid Build Coastguard Worker static void
test_reset_signaled(int fd)387*d83cc019SAndroid Build Coastguard Worker test_reset_signaled(int fd)
388*d83cc019SAndroid Build Coastguard Worker {
389*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobj = syncobj_create(fd, 0);
390*d83cc019SAndroid Build Coastguard Worker 
391*d83cc019SAndroid Build Coastguard Worker 	syncobj_trigger(fd, syncobj);
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, 0), 0);
394*d83cc019SAndroid Build Coastguard Worker 
395*d83cc019SAndroid Build Coastguard Worker 	syncobj_reset(fd, &syncobj, 1);
396*d83cc019SAndroid Build Coastguard Worker 
397*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, 0), -EINVAL);
398*d83cc019SAndroid Build Coastguard Worker 
399*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobj);
400*d83cc019SAndroid Build Coastguard Worker }
401*d83cc019SAndroid Build Coastguard Worker 
402*d83cc019SAndroid Build Coastguard Worker static void
test_reset_multiple_signaled(int fd)403*d83cc019SAndroid Build Coastguard Worker test_reset_multiple_signaled(int fd)
404*d83cc019SAndroid Build Coastguard Worker {
405*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobjs[3];
406*d83cc019SAndroid Build Coastguard Worker 	int i;
407*d83cc019SAndroid Build Coastguard Worker 
408*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
409*d83cc019SAndroid Build Coastguard Worker 		syncobjs[i] = syncobj_create(fd, 0);
410*d83cc019SAndroid Build Coastguard Worker 		syncobj_trigger(fd, syncobjs[i]);
411*d83cc019SAndroid Build Coastguard Worker 	}
412*d83cc019SAndroid Build Coastguard Worker 
413*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, syncobjs, 3, 0, 0), 0);
414*d83cc019SAndroid Build Coastguard Worker 
415*d83cc019SAndroid Build Coastguard Worker 	syncobj_reset(fd, syncobjs, 3);
416*d83cc019SAndroid Build Coastguard Worker 
417*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
418*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(syncobj_wait_err(fd, &syncobjs[i], 1,
419*d83cc019SAndroid Build Coastguard Worker 					       0, 0), -EINVAL);
420*d83cc019SAndroid Build Coastguard Worker 		syncobj_destroy(fd, syncobjs[i]);
421*d83cc019SAndroid Build Coastguard Worker 	}
422*d83cc019SAndroid Build Coastguard Worker }
423*d83cc019SAndroid Build Coastguard Worker 
424*d83cc019SAndroid Build Coastguard Worker static void
reset_and_trigger_func(union sigval sigval)425*d83cc019SAndroid Build Coastguard Worker reset_and_trigger_func(union sigval sigval)
426*d83cc019SAndroid Build Coastguard Worker {
427*d83cc019SAndroid Build Coastguard Worker 	struct fd_handle_pair *pair = sigval.sival_ptr;
428*d83cc019SAndroid Build Coastguard Worker 	syncobj_reset(pair->fd, &pair->handle, 1);
429*d83cc019SAndroid Build Coastguard Worker 	syncobj_trigger(pair->fd, pair->handle);
430*d83cc019SAndroid Build Coastguard Worker }
431*d83cc019SAndroid Build Coastguard Worker 
432*d83cc019SAndroid Build Coastguard Worker static void
test_reset_during_wait_for_submit(int fd)433*d83cc019SAndroid Build Coastguard Worker test_reset_during_wait_for_submit(int fd)
434*d83cc019SAndroid Build Coastguard Worker {
435*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobj = syncobj_create(fd, 0);
436*d83cc019SAndroid Build Coastguard Worker 	uint32_t flags = LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
437*d83cc019SAndroid Build Coastguard Worker 	struct fd_handle_pair pair;
438*d83cc019SAndroid Build Coastguard Worker 	timer_t timer;
439*d83cc019SAndroid Build Coastguard Worker 
440*d83cc019SAndroid Build Coastguard Worker 	pair.fd = fd;
441*d83cc019SAndroid Build Coastguard Worker 	pair.handle = syncobj;
442*d83cc019SAndroid Build Coastguard Worker 	timer = set_timer(reset_and_trigger_func, &pair, 0, SHORT_TIME_NSEC);
443*d83cc019SAndroid Build Coastguard Worker 
444*d83cc019SAndroid Build Coastguard Worker 	/* A reset should be a no-op even if we're in the middle of a wait */
445*d83cc019SAndroid Build Coastguard Worker 	igt_assert(syncobj_wait(fd, &syncobj, 1,
446*d83cc019SAndroid Build Coastguard Worker 				gettime_ns() + SHORT_TIME_NSEC * 2,
447*d83cc019SAndroid Build Coastguard Worker 				flags, NULL));
448*d83cc019SAndroid Build Coastguard Worker 
449*d83cc019SAndroid Build Coastguard Worker 	timer_delete(timer);
450*d83cc019SAndroid Build Coastguard Worker 
451*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobj);
452*d83cc019SAndroid Build Coastguard Worker }
453*d83cc019SAndroid Build Coastguard Worker 
454*d83cc019SAndroid Build Coastguard Worker static void
test_signal(int fd)455*d83cc019SAndroid Build Coastguard Worker test_signal(int fd)
456*d83cc019SAndroid Build Coastguard Worker {
457*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobj = syncobj_create(fd, 0);
458*d83cc019SAndroid Build Coastguard Worker 	uint32_t flags = LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
459*d83cc019SAndroid Build Coastguard Worker 
460*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, 0), -EINVAL);
461*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, flags), -ETIME);
462*d83cc019SAndroid Build Coastguard Worker 
463*d83cc019SAndroid Build Coastguard Worker 	syncobj_signal(fd, &syncobj, 1);
464*d83cc019SAndroid Build Coastguard Worker 
465*d83cc019SAndroid Build Coastguard Worker 	igt_assert(syncobj_wait(fd, &syncobj, 1, 0, 0, NULL));
466*d83cc019SAndroid Build Coastguard Worker 	igt_assert(syncobj_wait(fd, &syncobj, 1, 0, flags, NULL));
467*d83cc019SAndroid Build Coastguard Worker 
468*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobj);
469*d83cc019SAndroid Build Coastguard Worker }
470*d83cc019SAndroid Build Coastguard Worker 
471*d83cc019SAndroid Build Coastguard Worker static void
test_multi_wait(int fd,uint32_t test_flags,int expect)472*d83cc019SAndroid Build Coastguard Worker test_multi_wait(int fd, uint32_t test_flags, int expect)
473*d83cc019SAndroid Build Coastguard Worker {
474*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobjs[3];
475*d83cc019SAndroid Build Coastguard Worker 	uint32_t tflag, flags;
476*d83cc019SAndroid Build Coastguard Worker 	int i, fidx, timeline;
477*d83cc019SAndroid Build Coastguard Worker 
478*d83cc019SAndroid Build Coastguard Worker 	syncobjs[0] = syncobj_create(fd, 0);
479*d83cc019SAndroid Build Coastguard Worker 	syncobjs[1] = syncobj_create(fd, 0);
480*d83cc019SAndroid Build Coastguard Worker 	syncobjs[2] = syncobj_create(fd, 0);
481*d83cc019SAndroid Build Coastguard Worker 
482*d83cc019SAndroid Build Coastguard Worker 	flags = flags_for_test_flags(test_flags);
483*d83cc019SAndroid Build Coastguard Worker 	test_flags &= ~(WAIT_ALL | WAIT_FOR_SUBMIT);
484*d83cc019SAndroid Build Coastguard Worker 
485*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
486*d83cc019SAndroid Build Coastguard Worker 		fidx = ffs(test_flags) - 1;
487*d83cc019SAndroid Build Coastguard Worker 		tflag = (1 << fidx);
488*d83cc019SAndroid Build Coastguard Worker 
489*d83cc019SAndroid Build Coastguard Worker 		if (test_flags & ~tflag)
490*d83cc019SAndroid Build Coastguard Worker 			test_flags &= ~tflag;
491*d83cc019SAndroid Build Coastguard Worker 
492*d83cc019SAndroid Build Coastguard Worker 		if (tflag & (WAIT_SUBMITTED | WAIT_SIGNALED))
493*d83cc019SAndroid Build Coastguard Worker 			timeline = syncobj_attach_sw_sync(fd, syncobjs[i]);
494*d83cc019SAndroid Build Coastguard Worker 		if (tflag & WAIT_SIGNALED)
495*d83cc019SAndroid Build Coastguard Worker 			sw_sync_timeline_inc(timeline, 1);
496*d83cc019SAndroid Build Coastguard Worker 	}
497*d83cc019SAndroid Build Coastguard Worker 
498*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, syncobjs, 3, 0, flags), expect);
499*d83cc019SAndroid Build Coastguard Worker 
500*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(syncobj_wait_err(fd, syncobjs, 3, short_timeout(),
501*d83cc019SAndroid Build Coastguard Worker 				       flags), expect);
502*d83cc019SAndroid Build Coastguard Worker 
503*d83cc019SAndroid Build Coastguard Worker 	if (expect != -ETIME) {
504*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(syncobj_wait_err(fd, syncobjs, 3, UINT64_MAX,
505*d83cc019SAndroid Build Coastguard Worker 					       flags), expect);
506*d83cc019SAndroid Build Coastguard Worker 	}
507*d83cc019SAndroid Build Coastguard Worker 
508*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[0]);
509*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[1]);
510*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[2]);
511*d83cc019SAndroid Build Coastguard Worker }
512*d83cc019SAndroid Build Coastguard Worker 
513*d83cc019SAndroid Build Coastguard Worker struct wait_thread_data {
514*d83cc019SAndroid Build Coastguard Worker 	int fd;
515*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_wait wait;
516*d83cc019SAndroid Build Coastguard Worker };
517*d83cc019SAndroid Build Coastguard Worker 
518*d83cc019SAndroid Build Coastguard Worker static void *
wait_thread_func(void * data)519*d83cc019SAndroid Build Coastguard Worker wait_thread_func(void *data)
520*d83cc019SAndroid Build Coastguard Worker {
521*d83cc019SAndroid Build Coastguard Worker 	struct wait_thread_data *wait = data;
522*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_wait(wait->fd, &wait->wait), 0);
523*d83cc019SAndroid Build Coastguard Worker 	return NULL;
524*d83cc019SAndroid Build Coastguard Worker }
525*d83cc019SAndroid Build Coastguard Worker 
526*d83cc019SAndroid Build Coastguard Worker static void
test_wait_snapshot(int fd,uint32_t test_flags)527*d83cc019SAndroid Build Coastguard Worker test_wait_snapshot(int fd, uint32_t test_flags)
528*d83cc019SAndroid Build Coastguard Worker {
529*d83cc019SAndroid Build Coastguard Worker 	struct wait_thread_data wait = { 0 };
530*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobjs[2];
531*d83cc019SAndroid Build Coastguard Worker 	int timelines[3] = { -1, -1, -1 };
532*d83cc019SAndroid Build Coastguard Worker 	pthread_t thread;
533*d83cc019SAndroid Build Coastguard Worker 
534*d83cc019SAndroid Build Coastguard Worker 	syncobjs[0] = syncobj_create(fd, 0);
535*d83cc019SAndroid Build Coastguard Worker 	syncobjs[1] = syncobj_create(fd, 0);
536*d83cc019SAndroid Build Coastguard Worker 
537*d83cc019SAndroid Build Coastguard Worker 	if (!(test_flags & WAIT_FOR_SUBMIT)) {
538*d83cc019SAndroid Build Coastguard Worker 		timelines[0] = syncobj_attach_sw_sync(fd, syncobjs[0]);
539*d83cc019SAndroid Build Coastguard Worker 		timelines[1] = syncobj_attach_sw_sync(fd, syncobjs[1]);
540*d83cc019SAndroid Build Coastguard Worker 	}
541*d83cc019SAndroid Build Coastguard Worker 
542*d83cc019SAndroid Build Coastguard Worker 	wait.fd = fd;
543*d83cc019SAndroid Build Coastguard Worker 	wait.wait.handles = to_user_pointer(syncobjs);
544*d83cc019SAndroid Build Coastguard Worker 	wait.wait.count_handles = 2;
545*d83cc019SAndroid Build Coastguard Worker 	wait.wait.timeout_nsec = short_timeout();
546*d83cc019SAndroid Build Coastguard Worker 	wait.wait.flags = flags_for_test_flags(test_flags);
547*d83cc019SAndroid Build Coastguard Worker 
548*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(pthread_create(&thread, NULL, wait_thread_func, &wait), 0);
549*d83cc019SAndroid Build Coastguard Worker 
550*d83cc019SAndroid Build Coastguard Worker 	sleep_nsec(SHORT_TIME_NSEC / 5);
551*d83cc019SAndroid Build Coastguard Worker 
552*d83cc019SAndroid Build Coastguard Worker 	/* Try to fake the kernel out by triggering or partially triggering
553*d83cc019SAndroid Build Coastguard Worker 	 * the first fence.
554*d83cc019SAndroid Build Coastguard Worker 	 */
555*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & WAIT_ALL) {
556*d83cc019SAndroid Build Coastguard Worker 		/* If it's WAIT_ALL, actually trigger it */
557*d83cc019SAndroid Build Coastguard Worker 		if (timelines[0] == -1)
558*d83cc019SAndroid Build Coastguard Worker 			syncobj_trigger(fd, syncobjs[0]);
559*d83cc019SAndroid Build Coastguard Worker 		else
560*d83cc019SAndroid Build Coastguard Worker 			sw_sync_timeline_inc(timelines[0], 1);
561*d83cc019SAndroid Build Coastguard Worker 	} else if (test_flags & WAIT_FOR_SUBMIT) {
562*d83cc019SAndroid Build Coastguard Worker 		timelines[0] = syncobj_attach_sw_sync(fd, syncobjs[0]);
563*d83cc019SAndroid Build Coastguard Worker 	}
564*d83cc019SAndroid Build Coastguard Worker 
565*d83cc019SAndroid Build Coastguard Worker 	sleep_nsec(SHORT_TIME_NSEC / 5);
566*d83cc019SAndroid Build Coastguard Worker 
567*d83cc019SAndroid Build Coastguard Worker 	/* Then reset it */
568*d83cc019SAndroid Build Coastguard Worker 	syncobj_reset(fd, &syncobjs[0], 1);
569*d83cc019SAndroid Build Coastguard Worker 
570*d83cc019SAndroid Build Coastguard Worker 	sleep_nsec(SHORT_TIME_NSEC / 5);
571*d83cc019SAndroid Build Coastguard Worker 
572*d83cc019SAndroid Build Coastguard Worker 	/* Then "submit" it in a way that will never trigger.  This way, if
573*d83cc019SAndroid Build Coastguard Worker 	 * the kernel picks up on the new fence (it shouldn't), we'll get a
574*d83cc019SAndroid Build Coastguard Worker 	 * timeout.
575*d83cc019SAndroid Build Coastguard Worker 	 */
576*d83cc019SAndroid Build Coastguard Worker 	timelines[2] = syncobj_attach_sw_sync(fd, syncobjs[0]);
577*d83cc019SAndroid Build Coastguard Worker 
578*d83cc019SAndroid Build Coastguard Worker 	sleep_nsec(SHORT_TIME_NSEC / 5);
579*d83cc019SAndroid Build Coastguard Worker 
580*d83cc019SAndroid Build Coastguard Worker 	/* Now trigger the second fence to complete the wait */
581*d83cc019SAndroid Build Coastguard Worker 
582*d83cc019SAndroid Build Coastguard Worker 	if (timelines[1] == -1)
583*d83cc019SAndroid Build Coastguard Worker 		syncobj_trigger(fd, syncobjs[1]);
584*d83cc019SAndroid Build Coastguard Worker 	else
585*d83cc019SAndroid Build Coastguard Worker 		sw_sync_timeline_inc(timelines[1], 1);
586*d83cc019SAndroid Build Coastguard Worker 
587*d83cc019SAndroid Build Coastguard Worker 	pthread_join(thread, NULL);
588*d83cc019SAndroid Build Coastguard Worker 
589*d83cc019SAndroid Build Coastguard Worker 	if (!(test_flags & WAIT_ALL))
590*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(wait.wait.first_signaled, 1);
591*d83cc019SAndroid Build Coastguard Worker 
592*d83cc019SAndroid Build Coastguard Worker 	close(timelines[0]);
593*d83cc019SAndroid Build Coastguard Worker 	close(timelines[1]);
594*d83cc019SAndroid Build Coastguard Worker 	close(timelines[2]);
595*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[0]);
596*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobjs[1]);
597*d83cc019SAndroid Build Coastguard Worker }
598*d83cc019SAndroid Build Coastguard Worker 
599*d83cc019SAndroid Build Coastguard Worker /* The numbers 0-7, each repeated 5x and shuffled. */
600*d83cc019SAndroid Build Coastguard Worker static const unsigned shuffled_0_7_x4[] = {
601*d83cc019SAndroid Build Coastguard Worker 	2, 0, 6, 1, 1, 4, 5, 2, 0, 7, 1, 7, 6, 3, 4, 5,
602*d83cc019SAndroid Build Coastguard Worker 	0, 2, 7, 3, 5, 4, 0, 6, 7, 3, 2, 5, 6, 1, 4, 3,
603*d83cc019SAndroid Build Coastguard Worker };
604*d83cc019SAndroid Build Coastguard Worker 
605*d83cc019SAndroid Build Coastguard Worker enum syncobj_stage {
606*d83cc019SAndroid Build Coastguard Worker 	STAGE_UNSUBMITTED,
607*d83cc019SAndroid Build Coastguard Worker 	STAGE_SUBMITTED,
608*d83cc019SAndroid Build Coastguard Worker 	STAGE_SIGNALED,
609*d83cc019SAndroid Build Coastguard Worker 	STAGE_RESET,
610*d83cc019SAndroid Build Coastguard Worker 	STAGE_RESUBMITTED,
611*d83cc019SAndroid Build Coastguard Worker };
612*d83cc019SAndroid Build Coastguard Worker 
613*d83cc019SAndroid Build Coastguard Worker static void
test_wait_complex(int fd,uint32_t test_flags)614*d83cc019SAndroid Build Coastguard Worker test_wait_complex(int fd, uint32_t test_flags)
615*d83cc019SAndroid Build Coastguard Worker {
616*d83cc019SAndroid Build Coastguard Worker 	struct wait_thread_data wait = { 0 };
617*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobjs[8];
618*d83cc019SAndroid Build Coastguard Worker 	enum syncobj_stage stage[8];
619*d83cc019SAndroid Build Coastguard Worker 	int i, j, timelines[8];
620*d83cc019SAndroid Build Coastguard Worker 	uint32_t first_signaled = -1, num_signaled = 0;
621*d83cc019SAndroid Build Coastguard Worker 	pthread_t thread;
622*d83cc019SAndroid Build Coastguard Worker 
623*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 8; i++) {
624*d83cc019SAndroid Build Coastguard Worker 		stage[i] = STAGE_UNSUBMITTED;
625*d83cc019SAndroid Build Coastguard Worker 		syncobjs[i] = syncobj_create(fd, 0);
626*d83cc019SAndroid Build Coastguard Worker 	}
627*d83cc019SAndroid Build Coastguard Worker 
628*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & WAIT_FOR_SUBMIT) {
629*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < 8; i++)
630*d83cc019SAndroid Build Coastguard Worker 			timelines[i] = -1;
631*d83cc019SAndroid Build Coastguard Worker 	} else {
632*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < 8; i++)
633*d83cc019SAndroid Build Coastguard Worker 			timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i]);
634*d83cc019SAndroid Build Coastguard Worker 	}
635*d83cc019SAndroid Build Coastguard Worker 
636*d83cc019SAndroid Build Coastguard Worker 	wait.fd = fd;
637*d83cc019SAndroid Build Coastguard Worker 	wait.wait.handles = to_user_pointer(syncobjs);
638*d83cc019SAndroid Build Coastguard Worker 	wait.wait.count_handles = 2;
639*d83cc019SAndroid Build Coastguard Worker 	wait.wait.timeout_nsec = gettime_ns() + NSECS_PER_SEC;
640*d83cc019SAndroid Build Coastguard Worker 	wait.wait.flags = flags_for_test_flags(test_flags);
641*d83cc019SAndroid Build Coastguard Worker 
642*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(pthread_create(&thread, NULL, wait_thread_func, &wait), 0);
643*d83cc019SAndroid Build Coastguard Worker 
644*d83cc019SAndroid Build Coastguard Worker 	sleep_nsec(NSECS_PER_SEC / 50);
645*d83cc019SAndroid Build Coastguard Worker 
646*d83cc019SAndroid Build Coastguard Worker 	num_signaled = 0;
647*d83cc019SAndroid Build Coastguard Worker 	for (j = 0; j < ARRAY_SIZE(shuffled_0_7_x4); j++) {
648*d83cc019SAndroid Build Coastguard Worker 		i = shuffled_0_7_x4[j];
649*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lt(i, ARRAY_SIZE(syncobjs));
650*d83cc019SAndroid Build Coastguard Worker 
651*d83cc019SAndroid Build Coastguard Worker 		switch (stage[i]++) {
652*d83cc019SAndroid Build Coastguard Worker 		case STAGE_UNSUBMITTED:
653*d83cc019SAndroid Build Coastguard Worker 			/* We need to submit attach a fence */
654*d83cc019SAndroid Build Coastguard Worker 			if (!(test_flags & WAIT_FOR_SUBMIT)) {
655*d83cc019SAndroid Build Coastguard Worker 				/* We had to attach one up-front */
656*d83cc019SAndroid Build Coastguard Worker 				igt_assert_neq(timelines[i], -1);
657*d83cc019SAndroid Build Coastguard Worker 				break;
658*d83cc019SAndroid Build Coastguard Worker 			}
659*d83cc019SAndroid Build Coastguard Worker 			timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i]);
660*d83cc019SAndroid Build Coastguard Worker 			break;
661*d83cc019SAndroid Build Coastguard Worker 
662*d83cc019SAndroid Build Coastguard Worker 		case STAGE_SUBMITTED:
663*d83cc019SAndroid Build Coastguard Worker 			/* We have a fence, trigger it */
664*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(timelines[i], -1);
665*d83cc019SAndroid Build Coastguard Worker 			sw_sync_timeline_inc(timelines[i], 1);
666*d83cc019SAndroid Build Coastguard Worker 			close(timelines[i]);
667*d83cc019SAndroid Build Coastguard Worker 			timelines[i] = -1;
668*d83cc019SAndroid Build Coastguard Worker 			if (num_signaled == 0)
669*d83cc019SAndroid Build Coastguard Worker 				first_signaled = i;
670*d83cc019SAndroid Build Coastguard Worker 			num_signaled++;
671*d83cc019SAndroid Build Coastguard Worker 			break;
672*d83cc019SAndroid Build Coastguard Worker 
673*d83cc019SAndroid Build Coastguard Worker 		case STAGE_SIGNALED:
674*d83cc019SAndroid Build Coastguard Worker 			/* We're already signaled, reset */
675*d83cc019SAndroid Build Coastguard Worker 			syncobj_reset(fd, &syncobjs[i], 1);
676*d83cc019SAndroid Build Coastguard Worker 			break;
677*d83cc019SAndroid Build Coastguard Worker 
678*d83cc019SAndroid Build Coastguard Worker 		case STAGE_RESET:
679*d83cc019SAndroid Build Coastguard Worker 			/* We're reset, submit and don't signal */
680*d83cc019SAndroid Build Coastguard Worker 			timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i]);
681*d83cc019SAndroid Build Coastguard Worker 			break;
682*d83cc019SAndroid Build Coastguard Worker 
683*d83cc019SAndroid Build Coastguard Worker 		case STAGE_RESUBMITTED:
684*d83cc019SAndroid Build Coastguard Worker 			igt_assert(!"Should not reach this stage");
685*d83cc019SAndroid Build Coastguard Worker 			break;
686*d83cc019SAndroid Build Coastguard Worker 		}
687*d83cc019SAndroid Build Coastguard Worker 
688*d83cc019SAndroid Build Coastguard Worker 		if (test_flags & WAIT_ALL) {
689*d83cc019SAndroid Build Coastguard Worker 			if (num_signaled == ARRAY_SIZE(syncobjs))
690*d83cc019SAndroid Build Coastguard Worker 				break;
691*d83cc019SAndroid Build Coastguard Worker 		} else {
692*d83cc019SAndroid Build Coastguard Worker 			if (num_signaled > 0)
693*d83cc019SAndroid Build Coastguard Worker 				break;
694*d83cc019SAndroid Build Coastguard Worker 		}
695*d83cc019SAndroid Build Coastguard Worker 
696*d83cc019SAndroid Build Coastguard Worker 		sleep_nsec(NSECS_PER_SEC / 100);
697*d83cc019SAndroid Build Coastguard Worker 	}
698*d83cc019SAndroid Build Coastguard Worker 
699*d83cc019SAndroid Build Coastguard Worker 	pthread_join(thread, NULL);
700*d83cc019SAndroid Build Coastguard Worker 
701*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & WAIT_ALL) {
702*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(num_signaled, ARRAY_SIZE(syncobjs));
703*d83cc019SAndroid Build Coastguard Worker 	} else {
704*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(num_signaled, 1);
705*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(wait.wait.first_signaled, first_signaled);
706*d83cc019SAndroid Build Coastguard Worker 	}
707*d83cc019SAndroid Build Coastguard Worker 
708*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 8; i++) {
709*d83cc019SAndroid Build Coastguard Worker 		close(timelines[i]);
710*d83cc019SAndroid Build Coastguard Worker 		syncobj_destroy(fd, syncobjs[i]);
711*d83cc019SAndroid Build Coastguard Worker 	}
712*d83cc019SAndroid Build Coastguard Worker }
713*d83cc019SAndroid Build Coastguard Worker 
714*d83cc019SAndroid Build Coastguard Worker static void
test_wait_interrupted(int fd,uint32_t test_flags)715*d83cc019SAndroid Build Coastguard Worker test_wait_interrupted(int fd, uint32_t test_flags)
716*d83cc019SAndroid Build Coastguard Worker {
717*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_wait wait = { 0 };
718*d83cc019SAndroid Build Coastguard Worker 	uint32_t syncobj = syncobj_create(fd, 0);
719*d83cc019SAndroid Build Coastguard Worker 	int timeline;
720*d83cc019SAndroid Build Coastguard Worker 
721*d83cc019SAndroid Build Coastguard Worker 	wait.handles = to_user_pointer(&syncobj);
722*d83cc019SAndroid Build Coastguard Worker 	wait.count_handles = 1;
723*d83cc019SAndroid Build Coastguard Worker 	wait.flags = flags_for_test_flags(test_flags);
724*d83cc019SAndroid Build Coastguard Worker 
725*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & WAIT_FOR_SUBMIT) {
726*d83cc019SAndroid Build Coastguard Worker 		wait.timeout_nsec = short_timeout();
727*d83cc019SAndroid Build Coastguard Worker 		igt_while_interruptible(true)
728*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(__syncobj_wait(fd, &wait), -ETIME);
729*d83cc019SAndroid Build Coastguard Worker 	}
730*d83cc019SAndroid Build Coastguard Worker 
731*d83cc019SAndroid Build Coastguard Worker 	timeline = syncobj_attach_sw_sync(fd, syncobj);
732*d83cc019SAndroid Build Coastguard Worker 
733*d83cc019SAndroid Build Coastguard Worker 	wait.timeout_nsec = short_timeout();
734*d83cc019SAndroid Build Coastguard Worker 	igt_while_interruptible(true)
735*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(__syncobj_wait(fd, &wait), -ETIME);
736*d83cc019SAndroid Build Coastguard Worker 
737*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, syncobj);
738*d83cc019SAndroid Build Coastguard Worker 	close(timeline);
739*d83cc019SAndroid Build Coastguard Worker }
740*d83cc019SAndroid Build Coastguard Worker 
741*d83cc019SAndroid Build Coastguard Worker static bool
has_syncobj_wait(int fd)742*d83cc019SAndroid Build Coastguard Worker has_syncobj_wait(int fd)
743*d83cc019SAndroid Build Coastguard Worker {
744*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_wait wait = { 0 };
745*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = 0;
746*d83cc019SAndroid Build Coastguard Worker 	uint64_t value;
747*d83cc019SAndroid Build Coastguard Worker 	int ret;
748*d83cc019SAndroid Build Coastguard Worker 
749*d83cc019SAndroid Build Coastguard Worker 	if (drmGetCap(fd, DRM_CAP_SYNCOBJ, &value))
750*d83cc019SAndroid Build Coastguard Worker 		return false;
751*d83cc019SAndroid Build Coastguard Worker 	if (!value)
752*d83cc019SAndroid Build Coastguard Worker 		return false;
753*d83cc019SAndroid Build Coastguard Worker 
754*d83cc019SAndroid Build Coastguard Worker 	/* Try waiting for zero sync objects should fail with EINVAL */
755*d83cc019SAndroid Build Coastguard Worker 	wait.count_handles = 1;
756*d83cc019SAndroid Build Coastguard Worker 	wait.handles = to_user_pointer(&handle);
757*d83cc019SAndroid Build Coastguard Worker 	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_WAIT, &wait);
758*d83cc019SAndroid Build Coastguard Worker 	return ret == -1 && errno == ENOENT;
759*d83cc019SAndroid Build Coastguard Worker }
760*d83cc019SAndroid Build Coastguard Worker 
761*d83cc019SAndroid Build Coastguard Worker igt_main
762*d83cc019SAndroid Build Coastguard Worker {
763*d83cc019SAndroid Build Coastguard Worker 	int fd = -1;
764*d83cc019SAndroid Build Coastguard Worker 
765*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
766*d83cc019SAndroid Build Coastguard Worker 		fd = drm_open_driver(DRIVER_ANY);
767*d83cc019SAndroid Build Coastguard Worker 		igt_require(has_syncobj_wait(fd));
768*d83cc019SAndroid Build Coastguard Worker 		igt_require_sw_sync();
769*d83cc019SAndroid Build Coastguard Worker 	}
770*d83cc019SAndroid Build Coastguard Worker 
771*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-wait-bad-flags")
772*d83cc019SAndroid Build Coastguard Worker 		test_wait_bad_flags(fd);
773*d83cc019SAndroid Build Coastguard Worker 
774*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-wait-zero-handles")
775*d83cc019SAndroid Build Coastguard Worker 		test_wait_zero_handles(fd);
776*d83cc019SAndroid Build Coastguard Worker 
777*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-wait-illegal-handle")
778*d83cc019SAndroid Build Coastguard Worker 		test_wait_illegal_handle(fd);
779*d83cc019SAndroid Build Coastguard Worker 
780*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-reset-zero-handles")
781*d83cc019SAndroid Build Coastguard Worker 		test_reset_zero_handles(fd);
782*d83cc019SAndroid Build Coastguard Worker 
783*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-reset-illegal-handle")
784*d83cc019SAndroid Build Coastguard Worker 		test_reset_illegal_handle(fd);
785*d83cc019SAndroid Build Coastguard Worker 
786*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-reset-one-illegal-handle")
787*d83cc019SAndroid Build Coastguard Worker 		test_reset_one_illegal_handle(fd);
788*d83cc019SAndroid Build Coastguard Worker 
789*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-reset-bad-pad")
790*d83cc019SAndroid Build Coastguard Worker 		test_reset_bad_pad(fd);
791*d83cc019SAndroid Build Coastguard Worker 
792*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-signal-zero-handles")
793*d83cc019SAndroid Build Coastguard Worker 		test_signal_zero_handles(fd);
794*d83cc019SAndroid Build Coastguard Worker 
795*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-signal-illegal-handle")
796*d83cc019SAndroid Build Coastguard Worker 		test_signal_illegal_handle(fd);
797*d83cc019SAndroid Build Coastguard Worker 
798*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-signal-one-illegal-handle")
799*d83cc019SAndroid Build Coastguard Worker 		test_signal_one_illegal_handle(fd);
800*d83cc019SAndroid Build Coastguard Worker 
801*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-signal-bad-pad")
802*d83cc019SAndroid Build Coastguard Worker 		test_signal_bad_pad(fd);
803*d83cc019SAndroid Build Coastguard Worker 
804*d83cc019SAndroid Build Coastguard Worker 	for (unsigned flags = 0; flags < WAIT_FLAGS_MAX; flags++) {
805*d83cc019SAndroid Build Coastguard Worker 		int err;
806*d83cc019SAndroid Build Coastguard Worker 
807*d83cc019SAndroid Build Coastguard Worker 		/* Only one wait mode for single-wait tests */
808*d83cc019SAndroid Build Coastguard Worker 		if (__builtin_popcount(flags & (WAIT_UNSUBMITTED |
809*d83cc019SAndroid Build Coastguard Worker 						WAIT_SUBMITTED |
810*d83cc019SAndroid Build Coastguard Worker 						WAIT_SIGNALED)) != 1)
811*d83cc019SAndroid Build Coastguard Worker 			continue;
812*d83cc019SAndroid Build Coastguard Worker 
813*d83cc019SAndroid Build Coastguard Worker 		if ((flags & WAIT_UNSUBMITTED) && !(flags & WAIT_FOR_SUBMIT))
814*d83cc019SAndroid Build Coastguard Worker 			err = -EINVAL;
815*d83cc019SAndroid Build Coastguard Worker 		else if (!(flags & WAIT_SIGNALED))
816*d83cc019SAndroid Build Coastguard Worker 			err = -ETIME;
817*d83cc019SAndroid Build Coastguard Worker 		else
818*d83cc019SAndroid Build Coastguard Worker 			err = 0;
819*d83cc019SAndroid Build Coastguard Worker 
820*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%ssingle-wait%s%s%s%s%s",
821*d83cc019SAndroid Build Coastguard Worker 			      err == -EINVAL ? "invalid-" : "",
822*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_ALL) ? "-all" : "",
823*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_FOR_SUBMIT) ? "-for-submit" : "",
824*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_UNSUBMITTED) ? "-unsubmitted" : "",
825*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_SUBMITTED) ? "-submitted" : "",
826*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_SIGNALED) ? "-signaled" : "")
827*d83cc019SAndroid Build Coastguard Worker 			test_single_wait(fd, flags, err);
828*d83cc019SAndroid Build Coastguard Worker 	}
829*d83cc019SAndroid Build Coastguard Worker 
830*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-delayed-signal")
831*d83cc019SAndroid Build Coastguard Worker 		test_wait_delayed_signal(fd, 0);
832*d83cc019SAndroid Build Coastguard Worker 
833*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-for-submit-delayed-submit")
834*d83cc019SAndroid Build Coastguard Worker 		test_wait_delayed_signal(fd, WAIT_FOR_SUBMIT);
835*d83cc019SAndroid Build Coastguard Worker 
836*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-all-delayed-signal")
837*d83cc019SAndroid Build Coastguard Worker 		test_wait_delayed_signal(fd, WAIT_ALL);
838*d83cc019SAndroid Build Coastguard Worker 
839*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-all-for-submit-delayed-submit")
840*d83cc019SAndroid Build Coastguard Worker 		test_wait_delayed_signal(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
841*d83cc019SAndroid Build Coastguard Worker 
842*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("reset-unsignaled")
843*d83cc019SAndroid Build Coastguard Worker 		test_reset_unsignaled(fd);
844*d83cc019SAndroid Build Coastguard Worker 
845*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("reset-signaled")
846*d83cc019SAndroid Build Coastguard Worker 		test_reset_signaled(fd);
847*d83cc019SAndroid Build Coastguard Worker 
848*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("reset-multiple-signaled")
849*d83cc019SAndroid Build Coastguard Worker 		test_reset_multiple_signaled(fd);
850*d83cc019SAndroid Build Coastguard Worker 
851*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("reset-during-wait-for-submit")
852*d83cc019SAndroid Build Coastguard Worker 		test_reset_during_wait_for_submit(fd);
853*d83cc019SAndroid Build Coastguard Worker 
854*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("signal")
855*d83cc019SAndroid Build Coastguard Worker 		test_signal(fd);
856*d83cc019SAndroid Build Coastguard Worker 
857*d83cc019SAndroid Build Coastguard Worker 	for (unsigned flags = 0; flags < WAIT_FLAGS_MAX; flags++) {
858*d83cc019SAndroid Build Coastguard Worker 		int err;
859*d83cc019SAndroid Build Coastguard Worker 
860*d83cc019SAndroid Build Coastguard Worker 		/* At least one wait mode for multi-wait tests */
861*d83cc019SAndroid Build Coastguard Worker 		if (!(flags & (WAIT_UNSUBMITTED |
862*d83cc019SAndroid Build Coastguard Worker 			       WAIT_SUBMITTED |
863*d83cc019SAndroid Build Coastguard Worker 			       WAIT_SIGNALED)))
864*d83cc019SAndroid Build Coastguard Worker 			continue;
865*d83cc019SAndroid Build Coastguard Worker 
866*d83cc019SAndroid Build Coastguard Worker 		err = 0;
867*d83cc019SAndroid Build Coastguard Worker 		if ((flags & WAIT_UNSUBMITTED) && !(flags & WAIT_FOR_SUBMIT)) {
868*d83cc019SAndroid Build Coastguard Worker 			err = -EINVAL;
869*d83cc019SAndroid Build Coastguard Worker 		} else if (flags & WAIT_ALL) {
870*d83cc019SAndroid Build Coastguard Worker 			if (flags & (WAIT_UNSUBMITTED | WAIT_SUBMITTED))
871*d83cc019SAndroid Build Coastguard Worker 				err = -ETIME;
872*d83cc019SAndroid Build Coastguard Worker 		} else {
873*d83cc019SAndroid Build Coastguard Worker 			if (!(flags & WAIT_SIGNALED))
874*d83cc019SAndroid Build Coastguard Worker 				err = -ETIME;
875*d83cc019SAndroid Build Coastguard Worker 		}
876*d83cc019SAndroid Build Coastguard Worker 
877*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%smulti-wait%s%s%s%s%s",
878*d83cc019SAndroid Build Coastguard Worker 			      err == -EINVAL ? "invalid-" : "",
879*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_ALL) ? "-all" : "",
880*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_FOR_SUBMIT) ? "-for-submit" : "",
881*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_UNSUBMITTED) ? "-unsubmitted" : "",
882*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_SUBMITTED) ? "-submitted" : "",
883*d83cc019SAndroid Build Coastguard Worker 			      (flags & WAIT_SIGNALED) ? "-signaled" : "")
884*d83cc019SAndroid Build Coastguard Worker 			test_multi_wait(fd, flags, err);
885*d83cc019SAndroid Build Coastguard Worker 	}
886*d83cc019SAndroid Build Coastguard Worker 
887*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-any-snapshot")
888*d83cc019SAndroid Build Coastguard Worker 		test_wait_snapshot(fd, 0);
889*d83cc019SAndroid Build Coastguard Worker 
890*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-all-snapshot")
891*d83cc019SAndroid Build Coastguard Worker 		test_wait_snapshot(fd, WAIT_ALL);
892*d83cc019SAndroid Build Coastguard Worker 
893*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-for-submit-snapshot")
894*d83cc019SAndroid Build Coastguard Worker 		test_wait_snapshot(fd, WAIT_FOR_SUBMIT);
895*d83cc019SAndroid Build Coastguard Worker 
896*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-all-for-submit-snapshot")
897*d83cc019SAndroid Build Coastguard Worker 		test_wait_snapshot(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
898*d83cc019SAndroid Build Coastguard Worker 
899*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-any-complex")
900*d83cc019SAndroid Build Coastguard Worker 		test_wait_complex(fd, 0);
901*d83cc019SAndroid Build Coastguard Worker 
902*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-all-complex")
903*d83cc019SAndroid Build Coastguard Worker 		test_wait_complex(fd, WAIT_ALL);
904*d83cc019SAndroid Build Coastguard Worker 
905*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-for-submit-complex")
906*d83cc019SAndroid Build Coastguard Worker 		test_wait_complex(fd, WAIT_FOR_SUBMIT);
907*d83cc019SAndroid Build Coastguard Worker 
908*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-all-for-submit-complex")
909*d83cc019SAndroid Build Coastguard Worker 		test_wait_complex(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
910*d83cc019SAndroid Build Coastguard Worker 
911*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-any-interrupted")
912*d83cc019SAndroid Build Coastguard Worker 		test_wait_interrupted(fd, 0);
913*d83cc019SAndroid Build Coastguard Worker 
914*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("wait-all-interrupted")
915*d83cc019SAndroid Build Coastguard Worker 		test_wait_interrupted(fd, WAIT_ALL);
916*d83cc019SAndroid Build Coastguard Worker }
917