xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_exec_fence.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2016 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 "igt_sysfs.h"
26*d83cc019SAndroid Build Coastguard Worker #include "igt_vgem.h"
27*d83cc019SAndroid Build Coastguard Worker #include "sw_sync.h"
28*d83cc019SAndroid Build Coastguard Worker #include "i915/gem_ring.h"
29*d83cc019SAndroid Build Coastguard Worker 
30*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
31*d83cc019SAndroid Build Coastguard Worker #include <sys/poll.h>
32*d83cc019SAndroid Build Coastguard Worker #include <sys/signal.h>
33*d83cc019SAndroid Build Coastguard Worker 
34*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Check that execbuf waits for explicit fences");
35*d83cc019SAndroid Build Coastguard Worker 
36*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_FENCE_IN (1 << 16)
37*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_FENCE_OUT (1 << 17)
38*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_FENCE_SUBMIT (1 << 20)
39*d83cc019SAndroid Build Coastguard Worker 
40*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_FENCE_ARRAY (1 << 19)
41*d83cc019SAndroid Build Coastguard Worker struct local_gem_exec_fence {
42*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
43*d83cc019SAndroid Build Coastguard Worker 	uint32_t flags;
44*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_FENCE_WAIT (1 << 0)
45*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_FENCE_SIGNAL (1 << 1)
46*d83cc019SAndroid Build Coastguard Worker };
47*d83cc019SAndroid Build Coastguard Worker 
48*d83cc019SAndroid Build Coastguard Worker #ifndef SYNC_IOC_MERGE
49*d83cc019SAndroid Build Coastguard Worker struct sync_merge_data {
50*d83cc019SAndroid Build Coastguard Worker 	char    name[32];
51*d83cc019SAndroid Build Coastguard Worker 	int32_t fd2;
52*d83cc019SAndroid Build Coastguard Worker 	int32_t fence;
53*d83cc019SAndroid Build Coastguard Worker 	uint32_t        flags;
54*d83cc019SAndroid Build Coastguard Worker 	uint32_t        pad;
55*d83cc019SAndroid Build Coastguard Worker };
56*d83cc019SAndroid Build Coastguard Worker #define SYNC_IOC_MAGIC '>'
57*d83cc019SAndroid Build Coastguard Worker #define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
58*d83cc019SAndroid Build Coastguard Worker #endif
59*d83cc019SAndroid Build Coastguard Worker 
store(int fd,unsigned ring,int fence,uint32_t target,unsigned offset_value)60*d83cc019SAndroid Build Coastguard Worker static void store(int fd, unsigned ring, int fence, uint32_t target, unsigned offset_value)
61*d83cc019SAndroid Build Coastguard Worker {
62*d83cc019SAndroid Build Coastguard Worker 	const int SCRATCH = 0;
63*d83cc019SAndroid Build Coastguard Worker 	const int BATCH = 1;
64*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
65*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[2];
66*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc;
67*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
68*d83cc019SAndroid Build Coastguard Worker 	uint32_t batch[16];
69*d83cc019SAndroid Build Coastguard Worker 	int i;
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
72*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj);
73*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 2;
74*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = ring | LOCAL_EXEC_FENCE_IN;
75*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd2 = fence;
76*d83cc019SAndroid Build Coastguard Worker 	if (gen < 6)
77*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags |= I915_EXEC_SECURE;
78*d83cc019SAndroid Build Coastguard Worker 
79*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
80*d83cc019SAndroid Build Coastguard Worker 	obj[SCRATCH].handle = target;
81*d83cc019SAndroid Build Coastguard Worker 
82*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].handle = gem_create(fd, 4096);
83*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
84*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocation_count = 1;
85*d83cc019SAndroid Build Coastguard Worker 	memset(&reloc, 0, sizeof(reloc));
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker 	i = 0;
88*d83cc019SAndroid Build Coastguard Worker 	reloc.target_handle = obj[SCRATCH].handle;
89*d83cc019SAndroid Build Coastguard Worker 	reloc.presumed_offset = -1;
90*d83cc019SAndroid Build Coastguard Worker 	reloc.offset = sizeof(uint32_t) * (i + 1);
91*d83cc019SAndroid Build Coastguard Worker 	reloc.delta = sizeof(uint32_t) * offset_value;
92*d83cc019SAndroid Build Coastguard Worker 	reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
93*d83cc019SAndroid Build Coastguard Worker 	reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
94*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
95*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
96*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = reloc.delta;
97*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
98*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 4) {
99*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
100*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = reloc.delta;
101*d83cc019SAndroid Build Coastguard Worker 		reloc.offset += sizeof(uint32_t);
102*d83cc019SAndroid Build Coastguard Worker 	} else {
103*d83cc019SAndroid Build Coastguard Worker 		batch[i]--;
104*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = reloc.delta;
105*d83cc019SAndroid Build Coastguard Worker 	}
106*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = offset_value;
107*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = MI_BATCH_BUFFER_END;
108*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
109*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
110*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[BATCH].handle);
111*d83cc019SAndroid Build Coastguard Worker }
112*d83cc019SAndroid Build Coastguard Worker 
fence_busy(int fence)113*d83cc019SAndroid Build Coastguard Worker static bool fence_busy(int fence)
114*d83cc019SAndroid Build Coastguard Worker {
115*d83cc019SAndroid Build Coastguard Worker 	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
116*d83cc019SAndroid Build Coastguard Worker }
117*d83cc019SAndroid Build Coastguard Worker 
118*d83cc019SAndroid Build Coastguard Worker #define HANG 0x1
119*d83cc019SAndroid Build Coastguard Worker #define NONBLOCK 0x2
120*d83cc019SAndroid Build Coastguard Worker #define WAIT 0x4
121*d83cc019SAndroid Build Coastguard Worker 
test_fence_busy(int fd,unsigned ring,unsigned flags)122*d83cc019SAndroid Build Coastguard Worker static void test_fence_busy(int fd, unsigned ring, unsigned flags)
123*d83cc019SAndroid Build Coastguard Worker {
124*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
125*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
126*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc;
127*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
128*d83cc019SAndroid Build Coastguard Worker 	struct timespec tv;
129*d83cc019SAndroid Build Coastguard Worker 	uint32_t *batch;
130*d83cc019SAndroid Build Coastguard Worker 	int fence, i, timeout;
131*d83cc019SAndroid Build Coastguard Worker 
132*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
133*d83cc019SAndroid Build Coastguard Worker 
134*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
135*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
136*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
137*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = ring | LOCAL_EXEC_FENCE_OUT;
138*d83cc019SAndroid Build Coastguard Worker 
139*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
140*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	obj.relocs_ptr = to_user_pointer(&reloc);
143*d83cc019SAndroid Build Coastguard Worker 	obj.relocation_count = 1;
144*d83cc019SAndroid Build Coastguard Worker 	memset(&reloc, 0, sizeof(reloc));
145*d83cc019SAndroid Build Coastguard Worker 
146*d83cc019SAndroid Build Coastguard Worker 	batch = gem_mmap__wc(fd, obj.handle, 0, 4096, PROT_WRITE);
147*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, obj.handle,
148*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
149*d83cc019SAndroid Build Coastguard Worker 
150*d83cc019SAndroid Build Coastguard Worker 	reloc.target_handle = obj.handle; /* recurse */
151*d83cc019SAndroid Build Coastguard Worker 	reloc.presumed_offset = 0;
152*d83cc019SAndroid Build Coastguard Worker 	reloc.offset = sizeof(uint32_t);
153*d83cc019SAndroid Build Coastguard Worker 	reloc.delta = 0;
154*d83cc019SAndroid Build Coastguard Worker 	reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
155*d83cc019SAndroid Build Coastguard Worker 	reloc.write_domain = 0;
156*d83cc019SAndroid Build Coastguard Worker 
157*d83cc019SAndroid Build Coastguard Worker 	i = 0;
158*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_BATCH_BUFFER_START;
159*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
160*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8 | 1;
161*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
162*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
163*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 6) {
164*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8;
165*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
166*d83cc019SAndroid Build Coastguard Worker 	} else {
167*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 2 << 6;
168*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
169*d83cc019SAndroid Build Coastguard Worker 		if (gen < 4) {
170*d83cc019SAndroid Build Coastguard Worker 			batch[i] |= 1;
171*d83cc019SAndroid Build Coastguard Worker 			reloc.delta = 1;
172*d83cc019SAndroid Build Coastguard Worker 		}
173*d83cc019SAndroid Build Coastguard Worker 	}
174*d83cc019SAndroid Build Coastguard Worker 	i++;
175*d83cc019SAndroid Build Coastguard Worker 
176*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd2 = -1;
177*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf_wr(fd, &execbuf);
178*d83cc019SAndroid Build Coastguard Worker 	fence = execbuf.rsvd2 >> 32;
179*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fence != -1);
180*d83cc019SAndroid Build Coastguard Worker 
181*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, obj.handle));
182*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fence_busy(fence));
183*d83cc019SAndroid Build Coastguard Worker 
184*d83cc019SAndroid Build Coastguard Worker 	timeout = 120;
185*d83cc019SAndroid Build Coastguard Worker 	if ((flags & HANG) == 0) {
186*d83cc019SAndroid Build Coastguard Worker 		*batch = MI_BATCH_BUFFER_END;
187*d83cc019SAndroid Build Coastguard Worker 		__sync_synchronize();
188*d83cc019SAndroid Build Coastguard Worker 		timeout = 1;
189*d83cc019SAndroid Build Coastguard Worker 	}
190*d83cc019SAndroid Build Coastguard Worker 	munmap(batch, 4096);
191*d83cc019SAndroid Build Coastguard Worker 
192*d83cc019SAndroid Build Coastguard Worker 	if (flags & WAIT) {
193*d83cc019SAndroid Build Coastguard Worker 		struct pollfd pfd = { .fd = fence, .events = POLLIN };
194*d83cc019SAndroid Build Coastguard Worker 		igt_assert(poll(&pfd, 1, timeout*1000) == 1);
195*d83cc019SAndroid Build Coastguard Worker 	} else {
196*d83cc019SAndroid Build Coastguard Worker 		memset(&tv, 0, sizeof(tv));
197*d83cc019SAndroid Build Coastguard Worker 		while (fence_busy(fence))
198*d83cc019SAndroid Build Coastguard Worker 			igt_assert(igt_seconds_elapsed(&tv) < timeout);
199*d83cc019SAndroid Build Coastguard Worker 	}
200*d83cc019SAndroid Build Coastguard Worker 
201*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!gem_bo_busy(fd, obj.handle));
202*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(sync_fence_status(fence),
203*d83cc019SAndroid Build Coastguard Worker 		      flags & HANG ? -EIO : SYNC_FENCE_OK);
204*d83cc019SAndroid Build Coastguard Worker 
205*d83cc019SAndroid Build Coastguard Worker 	close(fence);
206*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
207*d83cc019SAndroid Build Coastguard Worker 
208*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
209*d83cc019SAndroid Build Coastguard Worker }
210*d83cc019SAndroid Build Coastguard Worker 
test_fence_busy_all(int fd,unsigned flags)211*d83cc019SAndroid Build Coastguard Worker static void test_fence_busy_all(int fd, unsigned flags)
212*d83cc019SAndroid Build Coastguard Worker {
213*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
214*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
215*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc;
216*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
217*d83cc019SAndroid Build Coastguard Worker 	struct timespec tv;
218*d83cc019SAndroid Build Coastguard Worker 	uint32_t *batch;
219*d83cc019SAndroid Build Coastguard Worker 	unsigned int engine;
220*d83cc019SAndroid Build Coastguard Worker 	int all, i, timeout;
221*d83cc019SAndroid Build Coastguard Worker 
222*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
223*d83cc019SAndroid Build Coastguard Worker 
224*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
225*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
226*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
227*d83cc019SAndroid Build Coastguard Worker 
228*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
229*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
230*d83cc019SAndroid Build Coastguard Worker 
231*d83cc019SAndroid Build Coastguard Worker 	obj.relocs_ptr = to_user_pointer(&reloc);
232*d83cc019SAndroid Build Coastguard Worker 	obj.relocation_count = 1;
233*d83cc019SAndroid Build Coastguard Worker 	memset(&reloc, 0, sizeof(reloc));
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 	batch = gem_mmap__wc(fd, obj.handle, 0, 4096, PROT_WRITE);
236*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, obj.handle,
237*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker 	reloc.target_handle = obj.handle; /* recurse */
240*d83cc019SAndroid Build Coastguard Worker 	reloc.presumed_offset = 0;
241*d83cc019SAndroid Build Coastguard Worker 	reloc.offset = sizeof(uint32_t);
242*d83cc019SAndroid Build Coastguard Worker 	reloc.delta = 0;
243*d83cc019SAndroid Build Coastguard Worker 	reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
244*d83cc019SAndroid Build Coastguard Worker 	reloc.write_domain = 0;
245*d83cc019SAndroid Build Coastguard Worker 
246*d83cc019SAndroid Build Coastguard Worker 	i = 0;
247*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_BATCH_BUFFER_START;
248*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
249*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8 | 1;
250*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
251*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
252*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 6) {
253*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8;
254*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
255*d83cc019SAndroid Build Coastguard Worker 	} else {
256*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 2 << 6;
257*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
258*d83cc019SAndroid Build Coastguard Worker 		if (gen < 4) {
259*d83cc019SAndroid Build Coastguard Worker 			batch[i] |= 1;
260*d83cc019SAndroid Build Coastguard Worker 			reloc.delta = 1;
261*d83cc019SAndroid Build Coastguard Worker 		}
262*d83cc019SAndroid Build Coastguard Worker 	}
263*d83cc019SAndroid Build Coastguard Worker 	i++;
264*d83cc019SAndroid Build Coastguard Worker 
265*d83cc019SAndroid Build Coastguard Worker 	all = -1;
266*d83cc019SAndroid Build Coastguard Worker 	for_each_engine(fd, engine) {
267*d83cc019SAndroid Build Coastguard Worker 		int fence, new;
268*d83cc019SAndroid Build Coastguard Worker 
269*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags = engine | LOCAL_EXEC_FENCE_OUT;
270*d83cc019SAndroid Build Coastguard Worker 		execbuf.rsvd2 = -1;
271*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf_wr(fd, &execbuf);
272*d83cc019SAndroid Build Coastguard Worker 		fence = execbuf.rsvd2 >> 32;
273*d83cc019SAndroid Build Coastguard Worker 		igt_assert(fence != -1);
274*d83cc019SAndroid Build Coastguard Worker 
275*d83cc019SAndroid Build Coastguard Worker 		if (all < 0) {
276*d83cc019SAndroid Build Coastguard Worker 			all = fence;
277*d83cc019SAndroid Build Coastguard Worker 			continue;
278*d83cc019SAndroid Build Coastguard Worker 		}
279*d83cc019SAndroid Build Coastguard Worker 
280*d83cc019SAndroid Build Coastguard Worker 		new = sync_fence_merge(all, fence);
281*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lte(0, new);
282*d83cc019SAndroid Build Coastguard Worker 		close(all);
283*d83cc019SAndroid Build Coastguard Worker 		close(fence);
284*d83cc019SAndroid Build Coastguard Worker 
285*d83cc019SAndroid Build Coastguard Worker 		all = new;
286*d83cc019SAndroid Build Coastguard Worker 	}
287*d83cc019SAndroid Build Coastguard Worker 
288*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, obj.handle));
289*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fence_busy(all));
290*d83cc019SAndroid Build Coastguard Worker 
291*d83cc019SAndroid Build Coastguard Worker 	timeout = 120;
292*d83cc019SAndroid Build Coastguard Worker 	if ((flags & HANG) == 0) {
293*d83cc019SAndroid Build Coastguard Worker 		*batch = MI_BATCH_BUFFER_END;
294*d83cc019SAndroid Build Coastguard Worker 		__sync_synchronize();
295*d83cc019SAndroid Build Coastguard Worker 		timeout = 1;
296*d83cc019SAndroid Build Coastguard Worker 	}
297*d83cc019SAndroid Build Coastguard Worker 	munmap(batch, 4096);
298*d83cc019SAndroid Build Coastguard Worker 
299*d83cc019SAndroid Build Coastguard Worker 	if (flags & WAIT) {
300*d83cc019SAndroid Build Coastguard Worker 		struct pollfd pfd = { .fd = all, .events = POLLIN };
301*d83cc019SAndroid Build Coastguard Worker 		igt_assert(poll(&pfd, 1, timeout*1000) == 1);
302*d83cc019SAndroid Build Coastguard Worker 	} else {
303*d83cc019SAndroid Build Coastguard Worker 		memset(&tv, 0, sizeof(tv));
304*d83cc019SAndroid Build Coastguard Worker 		while (fence_busy(all))
305*d83cc019SAndroid Build Coastguard Worker 			igt_assert(igt_seconds_elapsed(&tv) < timeout);
306*d83cc019SAndroid Build Coastguard Worker 	}
307*d83cc019SAndroid Build Coastguard Worker 
308*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!gem_bo_busy(fd, obj.handle));
309*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(sync_fence_status(all),
310*d83cc019SAndroid Build Coastguard Worker 		      flags & HANG ? -EIO : SYNC_FENCE_OK);
311*d83cc019SAndroid Build Coastguard Worker 
312*d83cc019SAndroid Build Coastguard Worker 	close(all);
313*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
316*d83cc019SAndroid Build Coastguard Worker }
317*d83cc019SAndroid Build Coastguard Worker 
test_fence_await(int fd,unsigned ring,unsigned flags)318*d83cc019SAndroid Build Coastguard Worker static void test_fence_await(int fd, unsigned ring, unsigned flags)
319*d83cc019SAndroid Build Coastguard Worker {
320*d83cc019SAndroid Build Coastguard Worker 	uint32_t scratch = gem_create(fd, 4096);
321*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
322*d83cc019SAndroid Build Coastguard Worker 	unsigned engine;
323*d83cc019SAndroid Build Coastguard Worker 	uint32_t *out;
324*d83cc019SAndroid Build Coastguard Worker 	int i;
325*d83cc019SAndroid Build Coastguard Worker 
326*d83cc019SAndroid Build Coastguard Worker 	igt_require(gem_can_store_dword(fd, 0));
327*d83cc019SAndroid Build Coastguard Worker 
328*d83cc019SAndroid Build Coastguard Worker 	out = gem_mmap__wc(fd, scratch, 0, 4096, PROT_WRITE);
329*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, scratch,
330*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
331*d83cc019SAndroid Build Coastguard Worker 
332*d83cc019SAndroid Build Coastguard Worker 	spin = igt_spin_new(fd,
333*d83cc019SAndroid Build Coastguard Worker 			    .engine = ring,
334*d83cc019SAndroid Build Coastguard Worker 			    .flags = IGT_SPIN_FENCE_OUT);
335*d83cc019SAndroid Build Coastguard Worker 	igt_assert(spin->out_fence != -1);
336*d83cc019SAndroid Build Coastguard Worker 
337*d83cc019SAndroid Build Coastguard Worker 	i = 0;
338*d83cc019SAndroid Build Coastguard Worker 	for_each_physical_engine(fd, engine) {
339*d83cc019SAndroid Build Coastguard Worker 		if (!gem_can_store_dword(fd, engine))
340*d83cc019SAndroid Build Coastguard Worker 			continue;
341*d83cc019SAndroid Build Coastguard Worker 
342*d83cc019SAndroid Build Coastguard Worker 		if (flags & NONBLOCK) {
343*d83cc019SAndroid Build Coastguard Worker 			store(fd, engine, spin->out_fence, scratch, i);
344*d83cc019SAndroid Build Coastguard Worker 		} else {
345*d83cc019SAndroid Build Coastguard Worker 			igt_fork(child, 1)
346*d83cc019SAndroid Build Coastguard Worker 				store(fd, engine, spin->out_fence, scratch, i);
347*d83cc019SAndroid Build Coastguard Worker 		}
348*d83cc019SAndroid Build Coastguard Worker 
349*d83cc019SAndroid Build Coastguard Worker 		i++;
350*d83cc019SAndroid Build Coastguard Worker 	}
351*d83cc019SAndroid Build Coastguard Worker 
352*d83cc019SAndroid Build Coastguard Worker 	sleep(1);
353*d83cc019SAndroid Build Coastguard Worker 
354*d83cc019SAndroid Build Coastguard Worker 	/* Check for invalidly completing the task early */
355*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fence_busy(spin->out_fence));
356*d83cc019SAndroid Build Coastguard Worker 	for (int n = 0; n < i; n++)
357*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(out[n], 0);
358*d83cc019SAndroid Build Coastguard Worker 
359*d83cc019SAndroid Build Coastguard Worker 	if ((flags & HANG) == 0)
360*d83cc019SAndroid Build Coastguard Worker 		igt_spin_end(spin);
361*d83cc019SAndroid Build Coastguard Worker 
362*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
363*d83cc019SAndroid Build Coastguard Worker 
364*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, scratch, I915_GEM_DOMAIN_GTT, 0);
365*d83cc019SAndroid Build Coastguard Worker 	while (i--)
366*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(out[i], i);
367*d83cc019SAndroid Build Coastguard Worker 	munmap(out, 4096);
368*d83cc019SAndroid Build Coastguard Worker 
369*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
370*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, scratch);
371*d83cc019SAndroid Build Coastguard Worker }
372*d83cc019SAndroid Build Coastguard Worker 
resubmit(int fd,uint32_t handle,unsigned int ring,int count)373*d83cc019SAndroid Build Coastguard Worker static void resubmit(int fd, uint32_t handle, unsigned int ring, int count)
374*d83cc019SAndroid Build Coastguard Worker {
375*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = { .handle = handle };
376*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf = {
377*d83cc019SAndroid Build Coastguard Worker 		.buffers_ptr = to_user_pointer(&obj),
378*d83cc019SAndroid Build Coastguard Worker 		.buffer_count = 1,
379*d83cc019SAndroid Build Coastguard Worker 		.flags = ring,
380*d83cc019SAndroid Build Coastguard Worker 	};
381*d83cc019SAndroid Build Coastguard Worker 	while (count--)
382*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(fd, &execbuf);
383*d83cc019SAndroid Build Coastguard Worker }
384*d83cc019SAndroid Build Coastguard Worker 
alarm_handler(int sig)385*d83cc019SAndroid Build Coastguard Worker static void alarm_handler(int sig)
386*d83cc019SAndroid Build Coastguard Worker {
387*d83cc019SAndroid Build Coastguard Worker }
388*d83cc019SAndroid Build Coastguard Worker 
__execbuf(int fd,struct drm_i915_gem_execbuffer2 * execbuf)389*d83cc019SAndroid Build Coastguard Worker static int __execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf)
390*d83cc019SAndroid Build Coastguard Worker {
391*d83cc019SAndroid Build Coastguard Worker 	int err;
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker 	err = 0;
394*d83cc019SAndroid Build Coastguard Worker 	if (ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2_WR, execbuf))
395*d83cc019SAndroid Build Coastguard Worker 		err = -errno;
396*d83cc019SAndroid Build Coastguard Worker 
397*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
398*d83cc019SAndroid Build Coastguard Worker 	return err;
399*d83cc019SAndroid Build Coastguard Worker }
400*d83cc019SAndroid Build Coastguard Worker 
test_parallel(int fd,unsigned int master)401*d83cc019SAndroid Build Coastguard Worker static void test_parallel(int fd, unsigned int master)
402*d83cc019SAndroid Build Coastguard Worker {
403*d83cc019SAndroid Build Coastguard Worker 	const int SCRATCH = 0;
404*d83cc019SAndroid Build Coastguard Worker 	const int BATCH = 1;
405*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
406*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[2];
407*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc[2];
408*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
409*d83cc019SAndroid Build Coastguard Worker 	uint32_t scratch = gem_create(fd, 4096);
410*d83cc019SAndroid Build Coastguard Worker 	uint32_t *out = gem_mmap__wc(fd, scratch, 0, 4096, PROT_READ);
411*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle[16];
412*d83cc019SAndroid Build Coastguard Worker 	uint32_t batch[16];
413*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
414*d83cc019SAndroid Build Coastguard Worker 	unsigned engine;
415*d83cc019SAndroid Build Coastguard Worker 	IGT_CORK_HANDLE(c);
416*d83cc019SAndroid Build Coastguard Worker 	uint32_t plug;
417*d83cc019SAndroid Build Coastguard Worker 	int i, x = 0;
418*d83cc019SAndroid Build Coastguard Worker 
419*d83cc019SAndroid Build Coastguard Worker 	plug = igt_cork_plug(&c, fd);
420*d83cc019SAndroid Build Coastguard Worker 
421*d83cc019SAndroid Build Coastguard Worker 	/* Fill the queue with many requests so that the next one has to
422*d83cc019SAndroid Build Coastguard Worker 	 * wait before it can be executed by the hardware.
423*d83cc019SAndroid Build Coastguard Worker 	 */
424*d83cc019SAndroid Build Coastguard Worker 	spin = igt_spin_new(fd, .engine = master, .dependency = plug);
425*d83cc019SAndroid Build Coastguard Worker 	resubmit(fd, spin->handle, master, 16);
426*d83cc019SAndroid Build Coastguard Worker 
427*d83cc019SAndroid Build Coastguard Worker 	/* Now queue the master request and its secondaries */
428*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
429*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj);
430*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 2;
431*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = master | LOCAL_EXEC_FENCE_OUT;
432*d83cc019SAndroid Build Coastguard Worker 	if (gen < 6)
433*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags |= I915_EXEC_SECURE;
434*d83cc019SAndroid Build Coastguard Worker 
435*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
436*d83cc019SAndroid Build Coastguard Worker 	obj[SCRATCH].handle = scratch;
437*d83cc019SAndroid Build Coastguard Worker 
438*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].handle = gem_create(fd, 4096);
439*d83cc019SAndroid Build Coastguard Worker 	handle[x] = obj[BATCH].handle;
440*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
441*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocation_count = 2;
442*d83cc019SAndroid Build Coastguard Worker 	memset(reloc, 0, sizeof(reloc));
443*d83cc019SAndroid Build Coastguard Worker 
444*d83cc019SAndroid Build Coastguard Worker 	i = 0;
445*d83cc019SAndroid Build Coastguard Worker 
446*d83cc019SAndroid Build Coastguard Worker 	reloc[0].target_handle = obj[SCRATCH].handle;
447*d83cc019SAndroid Build Coastguard Worker 	reloc[0].presumed_offset = -1;
448*d83cc019SAndroid Build Coastguard Worker 	reloc[0].offset = sizeof(uint32_t) * (i + 1);
449*d83cc019SAndroid Build Coastguard Worker 	reloc[0].delta = sizeof(uint32_t) * x++;
450*d83cc019SAndroid Build Coastguard Worker 	reloc[0].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
451*d83cc019SAndroid Build Coastguard Worker 	reloc[0].write_domain = 0; /* lies */
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
454*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
455*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = reloc[0].presumed_offset + reloc[0].delta;
456*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = (reloc[0].presumed_offset + reloc[0].delta) >> 32;
457*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 4) {
458*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
459*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = reloc[0].presumed_offset + reloc[0].delta;
460*d83cc019SAndroid Build Coastguard Worker 		reloc[0].offset += sizeof(uint32_t);
461*d83cc019SAndroid Build Coastguard Worker 	} else {
462*d83cc019SAndroid Build Coastguard Worker 		batch[i]--;
463*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = reloc[0].presumed_offset + reloc[0].delta;
464*d83cc019SAndroid Build Coastguard Worker 	}
465*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = ~0u ^ x;
466*d83cc019SAndroid Build Coastguard Worker 
467*d83cc019SAndroid Build Coastguard Worker 	reloc[1].target_handle = obj[BATCH].handle; /* recurse */
468*d83cc019SAndroid Build Coastguard Worker 	reloc[1].presumed_offset = 0;
469*d83cc019SAndroid Build Coastguard Worker 	reloc[1].offset = sizeof(uint32_t) * (i + 2);
470*d83cc019SAndroid Build Coastguard Worker 	reloc[1].delta = 0;
471*d83cc019SAndroid Build Coastguard Worker 	reloc[1].read_domains = I915_GEM_DOMAIN_COMMAND;
472*d83cc019SAndroid Build Coastguard Worker 	reloc[1].write_domain = 0;
473*d83cc019SAndroid Build Coastguard Worker 
474*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = MI_BATCH_BUFFER_START;
475*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
476*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8 | 1;
477*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
478*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
479*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 6) {
480*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8;
481*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
482*d83cc019SAndroid Build Coastguard Worker 	} else {
483*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 2 << 6;
484*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
485*d83cc019SAndroid Build Coastguard Worker 		if (gen < 4) {
486*d83cc019SAndroid Build Coastguard Worker 			batch[i] |= 1;
487*d83cc019SAndroid Build Coastguard Worker 			reloc[1].delta = 1;
488*d83cc019SAndroid Build Coastguard Worker 		}
489*d83cc019SAndroid Build Coastguard Worker 	}
490*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = MI_BATCH_BUFFER_END;
491*d83cc019SAndroid Build Coastguard Worker 	igt_assert(i < sizeof(batch)/sizeof(batch[0]));
492*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
493*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf_wr(fd, &execbuf);
494*d83cc019SAndroid Build Coastguard Worker 
495*d83cc019SAndroid Build Coastguard Worker 	igt_assert(execbuf.rsvd2);
496*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd2 >>= 32; /* out fence -> in fence */
497*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocation_count = 1;
498*d83cc019SAndroid Build Coastguard Worker 
499*d83cc019SAndroid Build Coastguard Worker 	/* Queue all secondaries */
500*d83cc019SAndroid Build Coastguard Worker 	for_each_physical_engine(fd, engine) {
501*d83cc019SAndroid Build Coastguard Worker 		if (engine == master)
502*d83cc019SAndroid Build Coastguard Worker 			continue;
503*d83cc019SAndroid Build Coastguard Worker 
504*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags = engine | LOCAL_EXEC_FENCE_SUBMIT;
505*d83cc019SAndroid Build Coastguard Worker 		if (gen < 6)
506*d83cc019SAndroid Build Coastguard Worker 			execbuf.flags |= I915_EXEC_SECURE;
507*d83cc019SAndroid Build Coastguard Worker 
508*d83cc019SAndroid Build Coastguard Worker 		obj[BATCH].handle = gem_create(fd, 4096);
509*d83cc019SAndroid Build Coastguard Worker 		handle[x] = obj[BATCH].handle;
510*d83cc019SAndroid Build Coastguard Worker 
511*d83cc019SAndroid Build Coastguard Worker 		i = 0;
512*d83cc019SAndroid Build Coastguard Worker 		reloc[0].delta = sizeof(uint32_t) * x++;
513*d83cc019SAndroid Build Coastguard Worker 		batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
514*d83cc019SAndroid Build Coastguard Worker 		if (gen >= 8) {
515*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = reloc[0].presumed_offset + reloc[0].delta;
516*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = (reloc[0].presumed_offset + reloc[0].delta) >> 32;
517*d83cc019SAndroid Build Coastguard Worker 		} else if (gen >= 4) {
518*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = 0;
519*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = reloc[0].presumed_offset + reloc[0].delta;
520*d83cc019SAndroid Build Coastguard Worker 		} else {
521*d83cc019SAndroid Build Coastguard Worker 			batch[i]--;
522*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = reloc[0].presumed_offset + reloc[0].delta;
523*d83cc019SAndroid Build Coastguard Worker 		}
524*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = ~0u ^ x;
525*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = MI_BATCH_BUFFER_END;
526*d83cc019SAndroid Build Coastguard Worker 		gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
527*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(fd, &execbuf);
528*d83cc019SAndroid Build Coastguard Worker 	}
529*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, spin->handle));
530*d83cc019SAndroid Build Coastguard Worker 	close(execbuf.rsvd2);
531*d83cc019SAndroid Build Coastguard Worker 
532*d83cc019SAndroid Build Coastguard Worker 	/* No secondary should be executed since master is stalled. If there
533*d83cc019SAndroid Build Coastguard Worker 	 * was no dependency chain at all, the secondaries would start
534*d83cc019SAndroid Build Coastguard Worker 	 * immediately.
535*d83cc019SAndroid Build Coastguard Worker 	 */
536*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < x; i++) {
537*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(out[i], 0);
538*d83cc019SAndroid Build Coastguard Worker 		igt_assert(gem_bo_busy(fd, handle[i]));
539*d83cc019SAndroid Build Coastguard Worker 	}
540*d83cc019SAndroid Build Coastguard Worker 
541*d83cc019SAndroid Build Coastguard Worker 	/* Unblock the master */
542*d83cc019SAndroid Build Coastguard Worker 	igt_cork_unplug(&c);
543*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, plug);
544*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(spin);
545*d83cc019SAndroid Build Coastguard Worker 
546*d83cc019SAndroid Build Coastguard Worker 	/* Wait for all secondaries to complete. If we used a regular fence
547*d83cc019SAndroid Build Coastguard Worker 	 * then the secondaries would not start until the master was complete.
548*d83cc019SAndroid Build Coastguard Worker 	 * In this case that can only happen with a GPU reset, and so we run
549*d83cc019SAndroid Build Coastguard Worker 	 * under the hang detector and double check that the master is still
550*d83cc019SAndroid Build Coastguard Worker 	 * running afterwards.
551*d83cc019SAndroid Build Coastguard Worker 	 */
552*d83cc019SAndroid Build Coastguard Worker 	for (i = 1; i < x; i++) {
553*d83cc019SAndroid Build Coastguard Worker 		while (gem_bo_busy(fd, handle[i]))
554*d83cc019SAndroid Build Coastguard Worker 			sleep(0);
555*d83cc019SAndroid Build Coastguard Worker 
556*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(out[i], "Missing output from engine %d\n", i);
557*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, handle[i]);
558*d83cc019SAndroid Build Coastguard Worker 	}
559*d83cc019SAndroid Build Coastguard Worker 	munmap(out, 4096);
560*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[SCRATCH].handle);
561*d83cc019SAndroid Build Coastguard Worker 
562*d83cc019SAndroid Build Coastguard Worker 	/* Master should still be spinning, but all output should be written */
563*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, handle[0]));
564*d83cc019SAndroid Build Coastguard Worker 	out = gem_mmap__wc(fd, handle[0], 0, 4096, PROT_WRITE);
565*d83cc019SAndroid Build Coastguard Worker 	out[0] = MI_BATCH_BUFFER_END;
566*d83cc019SAndroid Build Coastguard Worker 	munmap(out, 4096);
567*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, handle[0]);
568*d83cc019SAndroid Build Coastguard Worker }
569*d83cc019SAndroid Build Coastguard Worker 
batch_create(int fd)570*d83cc019SAndroid Build Coastguard Worker static uint32_t batch_create(int fd)
571*d83cc019SAndroid Build Coastguard Worker {
572*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
573*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
574*d83cc019SAndroid Build Coastguard Worker 
575*d83cc019SAndroid Build Coastguard Worker 	handle = gem_create(fd, 4096);
576*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, handle, 0, &bbe, sizeof(bbe));
577*d83cc019SAndroid Build Coastguard Worker 
578*d83cc019SAndroid Build Coastguard Worker 	return handle;
579*d83cc019SAndroid Build Coastguard Worker }
580*d83cc019SAndroid Build Coastguard Worker 
lower_32_bits(uint64_t x)581*d83cc019SAndroid Build Coastguard Worker static inline uint32_t lower_32_bits(uint64_t x)
582*d83cc019SAndroid Build Coastguard Worker {
583*d83cc019SAndroid Build Coastguard Worker 	return x & 0xffffffff;
584*d83cc019SAndroid Build Coastguard Worker }
585*d83cc019SAndroid Build Coastguard Worker 
upper_32_bits(uint64_t x)586*d83cc019SAndroid Build Coastguard Worker static inline uint32_t upper_32_bits(uint64_t x)
587*d83cc019SAndroid Build Coastguard Worker {
588*d83cc019SAndroid Build Coastguard Worker 	return x >> 32;
589*d83cc019SAndroid Build Coastguard Worker }
590*d83cc019SAndroid Build Coastguard Worker 
test_keep_in_fence(int fd,unsigned int engine,unsigned int flags)591*d83cc019SAndroid Build Coastguard Worker static void test_keep_in_fence(int fd, unsigned int engine, unsigned int flags)
592*d83cc019SAndroid Build Coastguard Worker {
593*d83cc019SAndroid Build Coastguard Worker 	struct sigaction sa = { .sa_handler = alarm_handler };
594*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = {
595*d83cc019SAndroid Build Coastguard Worker 		.handle = batch_create(fd),
596*d83cc019SAndroid Build Coastguard Worker 	};
597*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf = {
598*d83cc019SAndroid Build Coastguard Worker 		.buffers_ptr = to_user_pointer(&obj),
599*d83cc019SAndroid Build Coastguard Worker 		.buffer_count = 1,
600*d83cc019SAndroid Build Coastguard Worker 		.flags = engine | LOCAL_EXEC_FENCE_OUT,
601*d83cc019SAndroid Build Coastguard Worker 	};
602*d83cc019SAndroid Build Coastguard Worker 	unsigned long count, last;
603*d83cc019SAndroid Build Coastguard Worker 	struct itimerval itv;
604*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
605*d83cc019SAndroid Build Coastguard Worker 	int fence;
606*d83cc019SAndroid Build Coastguard Worker 
607*d83cc019SAndroid Build Coastguard Worker 	spin = igt_spin_new(fd, .engine = engine);
608*d83cc019SAndroid Build Coastguard Worker 
609*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf_wr(fd, &execbuf);
610*d83cc019SAndroid Build Coastguard Worker 	fence = upper_32_bits(execbuf.rsvd2);
611*d83cc019SAndroid Build Coastguard Worker 
612*d83cc019SAndroid Build Coastguard Worker 	sigaction(SIGALRM, &sa, NULL);
613*d83cc019SAndroid Build Coastguard Worker 	itv.it_interval.tv_sec = 0;
614*d83cc019SAndroid Build Coastguard Worker 	itv.it_interval.tv_usec = 1000;
615*d83cc019SAndroid Build Coastguard Worker 	itv.it_value.tv_sec = 0;
616*d83cc019SAndroid Build Coastguard Worker 	itv.it_value.tv_usec = 10000;
617*d83cc019SAndroid Build Coastguard Worker 	setitimer(ITIMER_REAL, &itv, NULL);
618*d83cc019SAndroid Build Coastguard Worker 
619*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags |= LOCAL_EXEC_FENCE_IN;
620*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd2 = fence;
621*d83cc019SAndroid Build Coastguard Worker 
622*d83cc019SAndroid Build Coastguard Worker 	last = -1;
623*d83cc019SAndroid Build Coastguard Worker 	count = 0;
624*d83cc019SAndroid Build Coastguard Worker 	do {
625*d83cc019SAndroid Build Coastguard Worker 		int err = __execbuf(fd, &execbuf);
626*d83cc019SAndroid Build Coastguard Worker 
627*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(lower_32_bits(execbuf.rsvd2), fence);
628*d83cc019SAndroid Build Coastguard Worker 
629*d83cc019SAndroid Build Coastguard Worker 		if (err == 0) {
630*d83cc019SAndroid Build Coastguard Worker 			close(fence);
631*d83cc019SAndroid Build Coastguard Worker 
632*d83cc019SAndroid Build Coastguard Worker 			fence = upper_32_bits(execbuf.rsvd2);
633*d83cc019SAndroid Build Coastguard Worker 			execbuf.rsvd2 = fence;
634*d83cc019SAndroid Build Coastguard Worker 
635*d83cc019SAndroid Build Coastguard Worker 			count++;
636*d83cc019SAndroid Build Coastguard Worker 			continue;
637*d83cc019SAndroid Build Coastguard Worker 		}
638*d83cc019SAndroid Build Coastguard Worker 
639*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(err, -EINTR);
640*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(upper_32_bits(execbuf.rsvd2), 0);
641*d83cc019SAndroid Build Coastguard Worker 
642*d83cc019SAndroid Build Coastguard Worker 		if (last == count)
643*d83cc019SAndroid Build Coastguard Worker 			break;
644*d83cc019SAndroid Build Coastguard Worker 
645*d83cc019SAndroid Build Coastguard Worker 		last = count;
646*d83cc019SAndroid Build Coastguard Worker 	} while (1);
647*d83cc019SAndroid Build Coastguard Worker 
648*d83cc019SAndroid Build Coastguard Worker 	memset(&itv, 0, sizeof(itv));
649*d83cc019SAndroid Build Coastguard Worker 	setitimer(ITIMER_REAL, &itv, NULL);
650*d83cc019SAndroid Build Coastguard Worker 
651*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
652*d83cc019SAndroid Build Coastguard Worker 	close(fence);
653*d83cc019SAndroid Build Coastguard Worker 
654*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
655*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
656*d83cc019SAndroid Build Coastguard Worker }
657*d83cc019SAndroid Build Coastguard Worker 
658*d83cc019SAndroid Build Coastguard Worker #define EXPIRED 0x10000
test_long_history(int fd,long ring_size,unsigned flags)659*d83cc019SAndroid Build Coastguard Worker static void test_long_history(int fd, long ring_size, unsigned flags)
660*d83cc019SAndroid Build Coastguard Worker {
661*d83cc019SAndroid Build Coastguard Worker 	const uint32_t sz = 1 << 20;
662*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
663*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[2];
664*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
665*d83cc019SAndroid Build Coastguard Worker 	unsigned int engines[16], engine;
666*d83cc019SAndroid Build Coastguard Worker 	unsigned int nengine, n, s;
667*d83cc019SAndroid Build Coastguard Worker 	unsigned long limit;
668*d83cc019SAndroid Build Coastguard Worker 	int all_fences;
669*d83cc019SAndroid Build Coastguard Worker 	IGT_CORK_HANDLE(c);
670*d83cc019SAndroid Build Coastguard Worker 
671*d83cc019SAndroid Build Coastguard Worker 	limit = -1;
672*d83cc019SAndroid Build Coastguard Worker 	if (!gem_uses_full_ppgtt(fd))
673*d83cc019SAndroid Build Coastguard Worker 		limit = ring_size / 3;
674*d83cc019SAndroid Build Coastguard Worker 
675*d83cc019SAndroid Build Coastguard Worker 	nengine = 0;
676*d83cc019SAndroid Build Coastguard Worker 	for_each_physical_engine(fd, engine)
677*d83cc019SAndroid Build Coastguard Worker 		engines[nengine++] = engine;
678*d83cc019SAndroid Build Coastguard Worker 	igt_require(nengine);
679*d83cc019SAndroid Build Coastguard Worker 
680*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
681*d83cc019SAndroid Build Coastguard Worker 
682*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
683*d83cc019SAndroid Build Coastguard Worker 	obj[1].handle = gem_create(fd, sz);
684*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj[1].handle, sz - sizeof(bbe), &bbe, sizeof(bbe));
685*d83cc019SAndroid Build Coastguard Worker 
686*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
687*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj[1]);
688*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
689*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_OUT;
690*d83cc019SAndroid Build Coastguard Worker 
691*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf_wr(fd, &execbuf);
692*d83cc019SAndroid Build Coastguard Worker 	all_fences = execbuf.rsvd2 >> 32;
693*d83cc019SAndroid Build Coastguard Worker 
694*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj);
695*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 2;
696*d83cc019SAndroid Build Coastguard Worker 
697*d83cc019SAndroid Build Coastguard Worker 	obj[0].handle = igt_cork_plug(&c, fd);
698*d83cc019SAndroid Build Coastguard Worker 
699*d83cc019SAndroid Build Coastguard Worker 	igt_until_timeout(5) {
700*d83cc019SAndroid Build Coastguard Worker 		execbuf.rsvd1 = gem_context_create(fd);
701*d83cc019SAndroid Build Coastguard Worker 
702*d83cc019SAndroid Build Coastguard Worker 		for (n = 0; n < nengine; n++) {
703*d83cc019SAndroid Build Coastguard Worker 			struct sync_merge_data merge;
704*d83cc019SAndroid Build Coastguard Worker 
705*d83cc019SAndroid Build Coastguard Worker 			execbuf.flags = engines[n] | LOCAL_EXEC_FENCE_OUT;
706*d83cc019SAndroid Build Coastguard Worker 			if (__gem_execbuf_wr(fd, &execbuf))
707*d83cc019SAndroid Build Coastguard Worker 				continue;
708*d83cc019SAndroid Build Coastguard Worker 
709*d83cc019SAndroid Build Coastguard Worker 			memset(&merge, 0, sizeof(merge));
710*d83cc019SAndroid Build Coastguard Worker 			merge.fd2 = execbuf.rsvd2 >> 32;
711*d83cc019SAndroid Build Coastguard Worker 			strcpy(merge.name, "igt");
712*d83cc019SAndroid Build Coastguard Worker 
713*d83cc019SAndroid Build Coastguard Worker 			do_ioctl(all_fences, SYNC_IOC_MERGE, &merge);
714*d83cc019SAndroid Build Coastguard Worker 
715*d83cc019SAndroid Build Coastguard Worker 			close(all_fences);
716*d83cc019SAndroid Build Coastguard Worker 			close(merge.fd2);
717*d83cc019SAndroid Build Coastguard Worker 
718*d83cc019SAndroid Build Coastguard Worker 			all_fences = merge.fence;
719*d83cc019SAndroid Build Coastguard Worker 		}
720*d83cc019SAndroid Build Coastguard Worker 
721*d83cc019SAndroid Build Coastguard Worker 		gem_context_destroy(fd, execbuf.rsvd1);
722*d83cc019SAndroid Build Coastguard Worker 		if (!--limit)
723*d83cc019SAndroid Build Coastguard Worker 			break;
724*d83cc019SAndroid Build Coastguard Worker 	}
725*d83cc019SAndroid Build Coastguard Worker 	igt_cork_unplug(&c);
726*d83cc019SAndroid Build Coastguard Worker 
727*d83cc019SAndroid Build Coastguard Worker 	igt_info("History depth = %d\n", sync_fence_count(all_fences));
728*d83cc019SAndroid Build Coastguard Worker 
729*d83cc019SAndroid Build Coastguard Worker 	if (flags & EXPIRED)
730*d83cc019SAndroid Build Coastguard Worker 		gem_sync(fd, obj[1].handle);
731*d83cc019SAndroid Build Coastguard Worker 
732*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj[1]);
733*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
734*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd2 = all_fences;
735*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd1 = 0;
736*d83cc019SAndroid Build Coastguard Worker 
737*d83cc019SAndroid Build Coastguard Worker 	for (s = 0; s < ring_size; s++) {
738*d83cc019SAndroid Build Coastguard Worker 		for (n = 0; n < nengine; n++) {
739*d83cc019SAndroid Build Coastguard Worker 			execbuf.flags = engines[n] | LOCAL_EXEC_FENCE_IN;
740*d83cc019SAndroid Build Coastguard Worker 			if (__gem_execbuf_wr(fd, &execbuf))
741*d83cc019SAndroid Build Coastguard Worker 				continue;
742*d83cc019SAndroid Build Coastguard Worker 		}
743*d83cc019SAndroid Build Coastguard Worker 	}
744*d83cc019SAndroid Build Coastguard Worker 
745*d83cc019SAndroid Build Coastguard Worker 	close(all_fences);
746*d83cc019SAndroid Build Coastguard Worker 
747*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, obj[1].handle);
748*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[1].handle);
749*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[0].handle);
750*d83cc019SAndroid Build Coastguard Worker }
751*d83cc019SAndroid Build Coastguard Worker 
test_fence_flip(int i915)752*d83cc019SAndroid Build Coastguard Worker static void test_fence_flip(int i915)
753*d83cc019SAndroid Build Coastguard Worker {
754*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_f(1, "no fence-in for atomic flips\n");
755*d83cc019SAndroid Build Coastguard Worker }
756*d83cc019SAndroid Build Coastguard Worker 
has_submit_fence(int fd)757*d83cc019SAndroid Build Coastguard Worker static bool has_submit_fence(int fd)
758*d83cc019SAndroid Build Coastguard Worker {
759*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_getparam gp;
760*d83cc019SAndroid Build Coastguard Worker 	int value = 0;
761*d83cc019SAndroid Build Coastguard Worker 
762*d83cc019SAndroid Build Coastguard Worker 	memset(&gp, 0, sizeof(gp));
763*d83cc019SAndroid Build Coastguard Worker 	gp.param = 0xdeadbeef ^ 51; /* I915_PARAM_HAS_EXEC_SUBMIT_FENCE */
764*d83cc019SAndroid Build Coastguard Worker 	gp.value = &value;
765*d83cc019SAndroid Build Coastguard Worker 
766*d83cc019SAndroid Build Coastguard Worker 	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
767*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
768*d83cc019SAndroid Build Coastguard Worker 
769*d83cc019SAndroid Build Coastguard Worker 	return value;
770*d83cc019SAndroid Build Coastguard Worker }
771*d83cc019SAndroid Build Coastguard Worker 
has_syncobj(int fd)772*d83cc019SAndroid Build Coastguard Worker static bool has_syncobj(int fd)
773*d83cc019SAndroid Build Coastguard Worker {
774*d83cc019SAndroid Build Coastguard Worker 	struct drm_get_cap cap = { .capability = 0x13 };
775*d83cc019SAndroid Build Coastguard Worker 	ioctl(fd, DRM_IOCTL_GET_CAP, &cap);
776*d83cc019SAndroid Build Coastguard Worker 	return cap.value;
777*d83cc019SAndroid Build Coastguard Worker }
778*d83cc019SAndroid Build Coastguard Worker 
exec_has_fence_array(int fd)779*d83cc019SAndroid Build Coastguard Worker static bool exec_has_fence_array(int fd)
780*d83cc019SAndroid Build Coastguard Worker {
781*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_getparam gp;
782*d83cc019SAndroid Build Coastguard Worker 	int value = 0;
783*d83cc019SAndroid Build Coastguard Worker 
784*d83cc019SAndroid Build Coastguard Worker 	memset(&gp, 0, sizeof(gp));
785*d83cc019SAndroid Build Coastguard Worker 	gp.param = 49; /* I915_PARAM_HAS_EXEC_FENCE_ARRAY */
786*d83cc019SAndroid Build Coastguard Worker 	gp.value = &value;
787*d83cc019SAndroid Build Coastguard Worker 
788*d83cc019SAndroid Build Coastguard Worker 	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
789*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
790*d83cc019SAndroid Build Coastguard Worker 
791*d83cc019SAndroid Build Coastguard Worker 	return value;
792*d83cc019SAndroid Build Coastguard Worker }
793*d83cc019SAndroid Build Coastguard Worker 
test_invalid_fence_array(int fd)794*d83cc019SAndroid Build Coastguard Worker static void test_invalid_fence_array(int fd)
795*d83cc019SAndroid Build Coastguard Worker {
796*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
797*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
798*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
799*d83cc019SAndroid Build Coastguard Worker 	struct local_gem_exec_fence fence;
800*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
801*d83cc019SAndroid Build Coastguard Worker 
802*d83cc019SAndroid Build Coastguard Worker 	/* create an otherwise valid execbuf */
803*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
804*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
805*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
806*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
807*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
808*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
809*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
810*d83cc019SAndroid Build Coastguard Worker 
811*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags |= LOCAL_EXEC_FENCE_ARRAY;
812*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
813*d83cc019SAndroid Build Coastguard Worker 
814*d83cc019SAndroid Build Coastguard Worker 	/* Now add a few invalid fence-array pointers */
815*d83cc019SAndroid Build Coastguard Worker 	if (sizeof(execbuf.num_cliprects) == sizeof(size_t)) {
816*d83cc019SAndroid Build Coastguard Worker 		execbuf.num_cliprects = -1;
817*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
818*d83cc019SAndroid Build Coastguard Worker 	}
819*d83cc019SAndroid Build Coastguard Worker 
820*d83cc019SAndroid Build Coastguard Worker 	execbuf.num_cliprects = 1;
821*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = -1;
822*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
823*d83cc019SAndroid Build Coastguard Worker 
824*d83cc019SAndroid Build Coastguard Worker 	memset(&fence, 0, sizeof(fence));
825*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(&fence);
826*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
827*d83cc019SAndroid Build Coastguard Worker 
828*d83cc019SAndroid Build Coastguard Worker 	ptr = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
829*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ptr != MAP_FAILED);
830*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(ptr);
831*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
832*d83cc019SAndroid Build Coastguard Worker 
833*d83cc019SAndroid Build Coastguard Worker 	do_or_die(mprotect(ptr, 4096, PROT_READ));
834*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
835*d83cc019SAndroid Build Coastguard Worker 
836*d83cc019SAndroid Build Coastguard Worker 	do_or_die(mprotect(ptr, 4096, PROT_NONE));
837*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
838*d83cc019SAndroid Build Coastguard Worker 
839*d83cc019SAndroid Build Coastguard Worker 	munmap(ptr, 4096);
840*d83cc019SAndroid Build Coastguard Worker }
841*d83cc019SAndroid Build Coastguard Worker 
__syncobj_create(int fd)842*d83cc019SAndroid Build Coastguard Worker static uint32_t __syncobj_create(int fd)
843*d83cc019SAndroid Build Coastguard Worker {
844*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_create {
845*d83cc019SAndroid Build Coastguard Worker 		uint32_t handle, flags;
846*d83cc019SAndroid Build Coastguard Worker 	} arg;
847*d83cc019SAndroid Build Coastguard Worker #define LOCAL_IOCTL_SYNCOBJ_CREATE        DRM_IOWR(0xBF, struct local_syncobj_create)
848*d83cc019SAndroid Build Coastguard Worker 
849*d83cc019SAndroid Build Coastguard Worker 	memset(&arg, 0, sizeof(arg));
850*d83cc019SAndroid Build Coastguard Worker 	igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_CREATE, &arg);
851*d83cc019SAndroid Build Coastguard Worker 
852*d83cc019SAndroid Build Coastguard Worker 	return arg.handle;
853*d83cc019SAndroid Build Coastguard Worker }
854*d83cc019SAndroid Build Coastguard Worker 
syncobj_create(int fd)855*d83cc019SAndroid Build Coastguard Worker static uint32_t syncobj_create(int fd)
856*d83cc019SAndroid Build Coastguard Worker {
857*d83cc019SAndroid Build Coastguard Worker 	uint32_t ret;
858*d83cc019SAndroid Build Coastguard Worker 
859*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq((ret = __syncobj_create(fd)), 0);
860*d83cc019SAndroid Build Coastguard Worker 
861*d83cc019SAndroid Build Coastguard Worker 	return ret;
862*d83cc019SAndroid Build Coastguard Worker }
863*d83cc019SAndroid Build Coastguard Worker 
__syncobj_destroy(int fd,uint32_t handle)864*d83cc019SAndroid Build Coastguard Worker static int __syncobj_destroy(int fd, uint32_t handle)
865*d83cc019SAndroid Build Coastguard Worker {
866*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_destroy {
867*d83cc019SAndroid Build Coastguard Worker 		uint32_t handle, flags;
868*d83cc019SAndroid Build Coastguard Worker 	} arg;
869*d83cc019SAndroid Build Coastguard Worker #define LOCAL_IOCTL_SYNCOBJ_DESTROY        DRM_IOWR(0xC0, struct local_syncobj_destroy)
870*d83cc019SAndroid Build Coastguard Worker 	int err = 0;
871*d83cc019SAndroid Build Coastguard Worker 
872*d83cc019SAndroid Build Coastguard Worker 	memset(&arg, 0, sizeof(arg));
873*d83cc019SAndroid Build Coastguard Worker 	arg.handle = handle;
874*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_DESTROY, &arg))
875*d83cc019SAndroid Build Coastguard Worker 		err = -errno;
876*d83cc019SAndroid Build Coastguard Worker 
877*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
878*d83cc019SAndroid Build Coastguard Worker 	return err;
879*d83cc019SAndroid Build Coastguard Worker }
880*d83cc019SAndroid Build Coastguard Worker 
syncobj_destroy(int fd,uint32_t handle)881*d83cc019SAndroid Build Coastguard Worker static void syncobj_destroy(int fd, uint32_t handle)
882*d83cc019SAndroid Build Coastguard Worker {
883*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_destroy(fd, handle), 0);
884*d83cc019SAndroid Build Coastguard Worker }
885*d83cc019SAndroid Build Coastguard Worker 
__syncobj_to_sync_file(int fd,uint32_t handle)886*d83cc019SAndroid Build Coastguard Worker static int __syncobj_to_sync_file(int fd, uint32_t handle)
887*d83cc019SAndroid Build Coastguard Worker {
888*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_handle {
889*d83cc019SAndroid Build Coastguard Worker 		uint32_t handle;
890*d83cc019SAndroid Build Coastguard Worker 		uint32_t flags;
891*d83cc019SAndroid Build Coastguard Worker 		int32_t fd;
892*d83cc019SAndroid Build Coastguard Worker 		uint32_t pad;
893*d83cc019SAndroid Build Coastguard Worker 	} arg;
894*d83cc019SAndroid Build Coastguard Worker #define LOCAL_IOCTL_SYNCOBJ_HANDLE_TO_FD  DRM_IOWR(0xC1, struct local_syncobj_handle)
895*d83cc019SAndroid Build Coastguard Worker 
896*d83cc019SAndroid Build Coastguard Worker 	memset(&arg, 0, sizeof(arg));
897*d83cc019SAndroid Build Coastguard Worker 	arg.handle = handle;
898*d83cc019SAndroid Build Coastguard Worker 	arg.flags = 1 << 0; /* EXPORT_SYNC_FILE */
899*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_HANDLE_TO_FD, &arg))
900*d83cc019SAndroid Build Coastguard Worker 		arg.fd = -errno;
901*d83cc019SAndroid Build Coastguard Worker 
902*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
903*d83cc019SAndroid Build Coastguard Worker 	return arg.fd;
904*d83cc019SAndroid Build Coastguard Worker }
905*d83cc019SAndroid Build Coastguard Worker 
syncobj_to_sync_file(int fd,uint32_t handle)906*d83cc019SAndroid Build Coastguard Worker static int syncobj_to_sync_file(int fd, uint32_t handle)
907*d83cc019SAndroid Build Coastguard Worker {
908*d83cc019SAndroid Build Coastguard Worker 	int ret;
909*d83cc019SAndroid Build Coastguard Worker 
910*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(0, (ret = __syncobj_to_sync_file(fd, handle)));
911*d83cc019SAndroid Build Coastguard Worker 
912*d83cc019SAndroid Build Coastguard Worker 	return ret;
913*d83cc019SAndroid Build Coastguard Worker }
914*d83cc019SAndroid Build Coastguard Worker 
__syncobj_from_sync_file(int fd,uint32_t handle,int sf)915*d83cc019SAndroid Build Coastguard Worker static int __syncobj_from_sync_file(int fd, uint32_t handle, int sf)
916*d83cc019SAndroid Build Coastguard Worker {
917*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_handle {
918*d83cc019SAndroid Build Coastguard Worker 		uint32_t handle;
919*d83cc019SAndroid Build Coastguard Worker 		uint32_t flags;
920*d83cc019SAndroid Build Coastguard Worker 		int32_t fd;
921*d83cc019SAndroid Build Coastguard Worker 		uint32_t pad;
922*d83cc019SAndroid Build Coastguard Worker 	} arg;
923*d83cc019SAndroid Build Coastguard Worker #define LOCAL_IOCTL_SYNCOBJ_FD_TO_HANDLE  DRM_IOWR(0xC2, struct local_syncobj_handle)
924*d83cc019SAndroid Build Coastguard Worker 	int err = 0;
925*d83cc019SAndroid Build Coastguard Worker 
926*d83cc019SAndroid Build Coastguard Worker 	memset(&arg, 0, sizeof(arg));
927*d83cc019SAndroid Build Coastguard Worker 	arg.handle = handle;
928*d83cc019SAndroid Build Coastguard Worker 	arg.fd = sf;
929*d83cc019SAndroid Build Coastguard Worker 	arg.flags = 1 << 0; /* IMPORT_SYNC_FILE */
930*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_FD_TO_HANDLE, &arg))
931*d83cc019SAndroid Build Coastguard Worker 		err = -errno;
932*d83cc019SAndroid Build Coastguard Worker 
933*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
934*d83cc019SAndroid Build Coastguard Worker 	return err;
935*d83cc019SAndroid Build Coastguard Worker }
936*d83cc019SAndroid Build Coastguard Worker 
syncobj_from_sync_file(int fd,uint32_t handle,int sf)937*d83cc019SAndroid Build Coastguard Worker static void syncobj_from_sync_file(int fd, uint32_t handle, int sf)
938*d83cc019SAndroid Build Coastguard Worker {
939*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_from_sync_file(fd, handle, sf), 0);
940*d83cc019SAndroid Build Coastguard Worker }
941*d83cc019SAndroid Build Coastguard Worker 
__syncobj_export(int fd,uint32_t handle,int * syncobj)942*d83cc019SAndroid Build Coastguard Worker static int __syncobj_export(int fd, uint32_t handle, int *syncobj)
943*d83cc019SAndroid Build Coastguard Worker {
944*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_handle {
945*d83cc019SAndroid Build Coastguard Worker 		uint32_t handle;
946*d83cc019SAndroid Build Coastguard Worker 		uint32_t flags;
947*d83cc019SAndroid Build Coastguard Worker 		int32_t fd;
948*d83cc019SAndroid Build Coastguard Worker 		uint32_t pad;
949*d83cc019SAndroid Build Coastguard Worker 	} arg;
950*d83cc019SAndroid Build Coastguard Worker 	int err;
951*d83cc019SAndroid Build Coastguard Worker 
952*d83cc019SAndroid Build Coastguard Worker 	memset(&arg, 0, sizeof(arg));
953*d83cc019SAndroid Build Coastguard Worker 	arg.handle = handle;
954*d83cc019SAndroid Build Coastguard Worker 
955*d83cc019SAndroid Build Coastguard Worker 	err = 0;
956*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_HANDLE_TO_FD, &arg))
957*d83cc019SAndroid Build Coastguard Worker 		err = -errno;
958*d83cc019SAndroid Build Coastguard Worker 
959*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
960*d83cc019SAndroid Build Coastguard Worker 	*syncobj = arg.fd;
961*d83cc019SAndroid Build Coastguard Worker 	return err;
962*d83cc019SAndroid Build Coastguard Worker }
963*d83cc019SAndroid Build Coastguard Worker 
syncobj_export(int fd,uint32_t handle)964*d83cc019SAndroid Build Coastguard Worker static int syncobj_export(int fd, uint32_t handle)
965*d83cc019SAndroid Build Coastguard Worker {
966*d83cc019SAndroid Build Coastguard Worker 	int syncobj;
967*d83cc019SAndroid Build Coastguard Worker 
968*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_export(fd, handle, &syncobj), 0);
969*d83cc019SAndroid Build Coastguard Worker 
970*d83cc019SAndroid Build Coastguard Worker 	return syncobj;
971*d83cc019SAndroid Build Coastguard Worker }
972*d83cc019SAndroid Build Coastguard Worker 
__syncobj_import(int fd,int syncobj,uint32_t * handle)973*d83cc019SAndroid Build Coastguard Worker static int __syncobj_import(int fd, int syncobj, uint32_t *handle)
974*d83cc019SAndroid Build Coastguard Worker {
975*d83cc019SAndroid Build Coastguard Worker 	struct local_syncobj_handle {
976*d83cc019SAndroid Build Coastguard Worker 		uint32_t handle;
977*d83cc019SAndroid Build Coastguard Worker 		uint32_t flags;
978*d83cc019SAndroid Build Coastguard Worker 		int32_t fd;
979*d83cc019SAndroid Build Coastguard Worker 		uint32_t pad;
980*d83cc019SAndroid Build Coastguard Worker 	} arg;
981*d83cc019SAndroid Build Coastguard Worker #define LOCAL_IOCTL_SYNCOBJ_FD_TO_HANDLE  DRM_IOWR(0xC2, struct local_syncobj_handle)
982*d83cc019SAndroid Build Coastguard Worker 	int err;
983*d83cc019SAndroid Build Coastguard Worker 
984*d83cc019SAndroid Build Coastguard Worker 	memset(&arg, 0, sizeof(arg));
985*d83cc019SAndroid Build Coastguard Worker 	arg.fd = syncobj;
986*d83cc019SAndroid Build Coastguard Worker 
987*d83cc019SAndroid Build Coastguard Worker 	err = 0;
988*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_FD_TO_HANDLE, &arg))
989*d83cc019SAndroid Build Coastguard Worker 		err = -errno;
990*d83cc019SAndroid Build Coastguard Worker 
991*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
992*d83cc019SAndroid Build Coastguard Worker 	*handle = arg.handle;
993*d83cc019SAndroid Build Coastguard Worker 	return err;
994*d83cc019SAndroid Build Coastguard Worker }
995*d83cc019SAndroid Build Coastguard Worker 
syncobj_import(int fd,int syncobj)996*d83cc019SAndroid Build Coastguard Worker static uint32_t syncobj_import(int fd, int syncobj)
997*d83cc019SAndroid Build Coastguard Worker {
998*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
999*d83cc019SAndroid Build Coastguard Worker 
1000*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_import(fd, syncobj, &handle), 0);
1001*d83cc019SAndroid Build Coastguard Worker 
1002*d83cc019SAndroid Build Coastguard Worker 
1003*d83cc019SAndroid Build Coastguard Worker 	return handle;
1004*d83cc019SAndroid Build Coastguard Worker }
1005*d83cc019SAndroid Build Coastguard Worker 
syncobj_busy(int fd,uint32_t handle)1006*d83cc019SAndroid Build Coastguard Worker static bool syncobj_busy(int fd, uint32_t handle)
1007*d83cc019SAndroid Build Coastguard Worker {
1008*d83cc019SAndroid Build Coastguard Worker 	bool result;
1009*d83cc019SAndroid Build Coastguard Worker 	int sf;
1010*d83cc019SAndroid Build Coastguard Worker 
1011*d83cc019SAndroid Build Coastguard Worker 	sf = syncobj_to_sync_file(fd, handle);
1012*d83cc019SAndroid Build Coastguard Worker 	result = poll(&(struct pollfd){sf, POLLIN}, 1, 0) == 0;
1013*d83cc019SAndroid Build Coastguard Worker 	close(sf);
1014*d83cc019SAndroid Build Coastguard Worker 
1015*d83cc019SAndroid Build Coastguard Worker 	return result;
1016*d83cc019SAndroid Build Coastguard Worker }
1017*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_unused_fence(int fd)1018*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_unused_fence(int fd)
1019*d83cc019SAndroid Build Coastguard Worker {
1020*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1021*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1022*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1023*d83cc019SAndroid Build Coastguard Worker 	struct local_gem_exec_fence fence = {
1024*d83cc019SAndroid Build Coastguard Worker 		.handle = syncobj_create(fd),
1025*d83cc019SAndroid Build Coastguard Worker 	};
1026*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = igt_spin_new(fd);
1027*d83cc019SAndroid Build Coastguard Worker 
1028*d83cc019SAndroid Build Coastguard Worker 	/* sanity check our syncobj_to_sync_file interface */
1029*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_to_sync_file(fd, 0), -ENOENT);
1030*d83cc019SAndroid Build Coastguard Worker 
1031*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1032*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1033*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1034*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1035*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(&fence);
1036*d83cc019SAndroid Build Coastguard Worker 	execbuf.num_cliprects = 1;
1037*d83cc019SAndroid Build Coastguard Worker 
1038*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1039*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1040*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1041*d83cc019SAndroid Build Coastguard Worker 
1042*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
1043*d83cc019SAndroid Build Coastguard Worker 
1044*d83cc019SAndroid Build Coastguard Worker 	/* no flags, the fence isn't created */
1045*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__syncobj_to_sync_file(fd, fence.handle), -EINVAL);
1046*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, obj.handle));
1047*d83cc019SAndroid Build Coastguard Worker 
1048*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1049*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, fence.handle);
1050*d83cc019SAndroid Build Coastguard Worker 
1051*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
1052*d83cc019SAndroid Build Coastguard Worker }
1053*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_invalid_wait(int fd)1054*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_invalid_wait(int fd)
1055*d83cc019SAndroid Build Coastguard Worker {
1056*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1057*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1058*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1059*d83cc019SAndroid Build Coastguard Worker 	struct local_gem_exec_fence fence = {
1060*d83cc019SAndroid Build Coastguard Worker 		.handle = syncobj_create(fd),
1061*d83cc019SAndroid Build Coastguard Worker 	};
1062*d83cc019SAndroid Build Coastguard Worker 
1063*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1064*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1065*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1066*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1067*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(&fence);
1068*d83cc019SAndroid Build Coastguard Worker 	execbuf.num_cliprects = 1;
1069*d83cc019SAndroid Build Coastguard Worker 
1070*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1071*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1072*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1073*d83cc019SAndroid Build Coastguard Worker 
1074*d83cc019SAndroid Build Coastguard Worker 	/* waiting before the fence is set is invalid */
1075*d83cc019SAndroid Build Coastguard Worker 	fence.flags = LOCAL_EXEC_FENCE_WAIT;
1076*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
1077*d83cc019SAndroid Build Coastguard Worker 
1078*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1079*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, fence.handle);
1080*d83cc019SAndroid Build Coastguard Worker }
1081*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_invalid_flags(int fd)1082*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_invalid_flags(int fd)
1083*d83cc019SAndroid Build Coastguard Worker {
1084*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1085*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1086*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1087*d83cc019SAndroid Build Coastguard Worker 	struct local_gem_exec_fence fence = {
1088*d83cc019SAndroid Build Coastguard Worker 		.handle = syncobj_create(fd),
1089*d83cc019SAndroid Build Coastguard Worker 	};
1090*d83cc019SAndroid Build Coastguard Worker 
1091*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1092*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1093*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1094*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1095*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(&fence);
1096*d83cc019SAndroid Build Coastguard Worker 	execbuf.num_cliprects = 1;
1097*d83cc019SAndroid Build Coastguard Worker 
1098*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1099*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1100*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1101*d83cc019SAndroid Build Coastguard Worker 
1102*d83cc019SAndroid Build Coastguard Worker 	/* set all flags to hit an invalid one */
1103*d83cc019SAndroid Build Coastguard Worker 	fence.flags = ~0;
1104*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
1105*d83cc019SAndroid Build Coastguard Worker 
1106*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1107*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, fence.handle);
1108*d83cc019SAndroid Build Coastguard Worker }
1109*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_signal(int fd)1110*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_signal(int fd)
1111*d83cc019SAndroid Build Coastguard Worker {
1112*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1113*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1114*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1115*d83cc019SAndroid Build Coastguard Worker 	struct local_gem_exec_fence fence = {
1116*d83cc019SAndroid Build Coastguard Worker 		.handle = syncobj_create(fd),
1117*d83cc019SAndroid Build Coastguard Worker 	};
1118*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = igt_spin_new(fd);
1119*d83cc019SAndroid Build Coastguard Worker 
1120*d83cc019SAndroid Build Coastguard Worker 	/* Check that the syncobj is signaled only when our request/fence is */
1121*d83cc019SAndroid Build Coastguard Worker 
1122*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1123*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1124*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1125*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1126*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(&fence);
1127*d83cc019SAndroid Build Coastguard Worker 	execbuf.num_cliprects = 1;
1128*d83cc019SAndroid Build Coastguard Worker 
1129*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1130*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1131*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1132*d83cc019SAndroid Build Coastguard Worker 
1133*d83cc019SAndroid Build Coastguard Worker 	fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
1134*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
1135*d83cc019SAndroid Build Coastguard Worker 
1136*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, obj.handle));
1137*d83cc019SAndroid Build Coastguard Worker 	igt_assert(syncobj_busy(fd, fence.handle));
1138*d83cc019SAndroid Build Coastguard Worker 
1139*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
1140*d83cc019SAndroid Build Coastguard Worker 
1141*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, obj.handle);
1142*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!gem_bo_busy(fd, obj.handle));
1143*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!syncobj_busy(fd, fence.handle));
1144*d83cc019SAndroid Build Coastguard Worker 
1145*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1146*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, fence.handle);
1147*d83cc019SAndroid Build Coastguard Worker }
1148*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_wait(int fd)1149*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_wait(int fd)
1150*d83cc019SAndroid Build Coastguard Worker {
1151*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1152*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1153*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1154*d83cc019SAndroid Build Coastguard Worker 	struct local_gem_exec_fence fence = {
1155*d83cc019SAndroid Build Coastguard Worker 		.handle = syncobj_create(fd),
1156*d83cc019SAndroid Build Coastguard Worker 	};
1157*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
1158*d83cc019SAndroid Build Coastguard Worker 	unsigned engine;
1159*d83cc019SAndroid Build Coastguard Worker 	unsigned handle[16];
1160*d83cc019SAndroid Build Coastguard Worker 	int n;
1161*d83cc019SAndroid Build Coastguard Worker 
1162*d83cc019SAndroid Build Coastguard Worker 	/* Check that we can use the syncobj to asynchronous wait prior to
1163*d83cc019SAndroid Build Coastguard Worker 	 * execution.
1164*d83cc019SAndroid Build Coastguard Worker 	 */
1165*d83cc019SAndroid Build Coastguard Worker 
1166*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
1167*d83cc019SAndroid Build Coastguard Worker 
1168*d83cc019SAndroid Build Coastguard Worker 	spin = igt_spin_new(fd);
1169*d83cc019SAndroid Build Coastguard Worker 
1170*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1171*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1172*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1173*d83cc019SAndroid Build Coastguard Worker 
1174*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1175*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1176*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1177*d83cc019SAndroid Build Coastguard Worker 
1178*d83cc019SAndroid Build Coastguard Worker 	/* Queue a signaler from the blocked engine */
1179*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1180*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(&fence);
1181*d83cc019SAndroid Build Coastguard Worker 	execbuf.num_cliprects = 1;
1182*d83cc019SAndroid Build Coastguard Worker 	fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
1183*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
1184*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, spin->handle));
1185*d83cc019SAndroid Build Coastguard Worker 
1186*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1187*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1188*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1189*d83cc019SAndroid Build Coastguard Worker 
1190*d83cc019SAndroid Build Coastguard Worker 	n = 0;
1191*d83cc019SAndroid Build Coastguard Worker 	for_each_engine(fd, engine) {
1192*d83cc019SAndroid Build Coastguard Worker 		obj.handle = gem_create(fd, 4096);
1193*d83cc019SAndroid Build Coastguard Worker 		gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1194*d83cc019SAndroid Build Coastguard Worker 
1195*d83cc019SAndroid Build Coastguard Worker 		/* No inter-engine synchronisation, will complete */
1196*d83cc019SAndroid Build Coastguard Worker 		if (engine == I915_EXEC_BLT) {
1197*d83cc019SAndroid Build Coastguard Worker 			execbuf.flags = engine;
1198*d83cc019SAndroid Build Coastguard Worker 			execbuf.cliprects_ptr = 0;
1199*d83cc019SAndroid Build Coastguard Worker 			execbuf.num_cliprects = 0;
1200*d83cc019SAndroid Build Coastguard Worker 			gem_execbuf(fd, &execbuf);
1201*d83cc019SAndroid Build Coastguard Worker 			gem_sync(fd, obj.handle);
1202*d83cc019SAndroid Build Coastguard Worker 			igt_assert(gem_bo_busy(fd, spin->handle));
1203*d83cc019SAndroid Build Coastguard Worker 		}
1204*d83cc019SAndroid Build Coastguard Worker 		igt_assert(gem_bo_busy(fd, spin->handle));
1205*d83cc019SAndroid Build Coastguard Worker 
1206*d83cc019SAndroid Build Coastguard Worker 		/* Now wait upon the blocked engine */
1207*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY | engine;
1208*d83cc019SAndroid Build Coastguard Worker 		execbuf.cliprects_ptr = to_user_pointer(&fence);
1209*d83cc019SAndroid Build Coastguard Worker 		execbuf.num_cliprects = 1;
1210*d83cc019SAndroid Build Coastguard Worker 		fence.flags = LOCAL_EXEC_FENCE_WAIT;
1211*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(fd, &execbuf);
1212*d83cc019SAndroid Build Coastguard Worker 
1213*d83cc019SAndroid Build Coastguard Worker 		igt_assert(gem_bo_busy(fd, obj.handle));
1214*d83cc019SAndroid Build Coastguard Worker 		handle[n++] = obj.handle;
1215*d83cc019SAndroid Build Coastguard Worker 	}
1216*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, fence.handle);
1217*d83cc019SAndroid Build Coastguard Worker 
1218*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < n; i++)
1219*d83cc019SAndroid Build Coastguard Worker 		igt_assert(gem_bo_busy(fd, handle[i]));
1220*d83cc019SAndroid Build Coastguard Worker 
1221*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
1222*d83cc019SAndroid Build Coastguard Worker 
1223*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < n; i++) {
1224*d83cc019SAndroid Build Coastguard Worker 		gem_sync(fd, handle[i]);
1225*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, handle[i]);
1226*d83cc019SAndroid Build Coastguard Worker 	}
1227*d83cc019SAndroid Build Coastguard Worker }
1228*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_export(int fd)1229*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_export(int fd)
1230*d83cc019SAndroid Build Coastguard Worker {
1231*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1232*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1233*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1234*d83cc019SAndroid Build Coastguard Worker 	struct local_gem_exec_fence fence = {
1235*d83cc019SAndroid Build Coastguard Worker 		.handle = syncobj_create(fd),
1236*d83cc019SAndroid Build Coastguard Worker 	};
1237*d83cc019SAndroid Build Coastguard Worker 	int export[2];
1238*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = igt_spin_new(fd);
1239*d83cc019SAndroid Build Coastguard Worker 
1240*d83cc019SAndroid Build Coastguard Worker 	/* Check that if we export the syncobj prior to use it picks up
1241*d83cc019SAndroid Build Coastguard Worker 	 * the later fence. This allows a syncobj to establish a channel
1242*d83cc019SAndroid Build Coastguard Worker 	 * between clients that may be updated to a later fence by either
1243*d83cc019SAndroid Build Coastguard Worker 	 * end.
1244*d83cc019SAndroid Build Coastguard Worker 	 */
1245*d83cc019SAndroid Build Coastguard Worker 	for (int n = 0; n < ARRAY_SIZE(export); n++)
1246*d83cc019SAndroid Build Coastguard Worker 		export[n] = syncobj_export(fd, fence.handle);
1247*d83cc019SAndroid Build Coastguard Worker 
1248*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1249*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1250*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1251*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1252*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(&fence);
1253*d83cc019SAndroid Build Coastguard Worker 	execbuf.num_cliprects = 1;
1254*d83cc019SAndroid Build Coastguard Worker 
1255*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1256*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1257*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1258*d83cc019SAndroid Build Coastguard Worker 
1259*d83cc019SAndroid Build Coastguard Worker 	fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
1260*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
1261*d83cc019SAndroid Build Coastguard Worker 
1262*d83cc019SAndroid Build Coastguard Worker 	igt_assert(syncobj_busy(fd, fence.handle));
1263*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, obj.handle));
1264*d83cc019SAndroid Build Coastguard Worker 
1265*d83cc019SAndroid Build Coastguard Worker 	for (int n = 0; n < ARRAY_SIZE(export); n++) {
1266*d83cc019SAndroid Build Coastguard Worker 		uint32_t import = syncobj_import(fd, export[n]);
1267*d83cc019SAndroid Build Coastguard Worker 		igt_assert(syncobj_busy(fd, import));
1268*d83cc019SAndroid Build Coastguard Worker 		syncobj_destroy(fd, import);
1269*d83cc019SAndroid Build Coastguard Worker 	}
1270*d83cc019SAndroid Build Coastguard Worker 
1271*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
1272*d83cc019SAndroid Build Coastguard Worker 
1273*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, obj.handle);
1274*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!gem_bo_busy(fd, obj.handle));
1275*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!syncobj_busy(fd, fence.handle));
1276*d83cc019SAndroid Build Coastguard Worker 
1277*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1278*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, fence.handle);
1279*d83cc019SAndroid Build Coastguard Worker 
1280*d83cc019SAndroid Build Coastguard Worker 	for (int n = 0; n < ARRAY_SIZE(export); n++) {
1281*d83cc019SAndroid Build Coastguard Worker 		uint32_t import = syncobj_import(fd, export[n]);
1282*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!syncobj_busy(fd, import));
1283*d83cc019SAndroid Build Coastguard Worker 		syncobj_destroy(fd, import);
1284*d83cc019SAndroid Build Coastguard Worker 		close(export[n]);
1285*d83cc019SAndroid Build Coastguard Worker 	}
1286*d83cc019SAndroid Build Coastguard Worker }
1287*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_repeat(int fd)1288*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_repeat(int fd)
1289*d83cc019SAndroid Build Coastguard Worker {
1290*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1291*d83cc019SAndroid Build Coastguard Worker 	const unsigned nfences = 4096;
1292*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1293*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1294*d83cc019SAndroid Build Coastguard Worker 	struct local_gem_exec_fence *fence;
1295*d83cc019SAndroid Build Coastguard Worker 	int export;
1296*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = igt_spin_new(fd);
1297*d83cc019SAndroid Build Coastguard Worker 
1298*d83cc019SAndroid Build Coastguard Worker 	/* Check that we can wait on the same fence multiple times */
1299*d83cc019SAndroid Build Coastguard Worker 	fence = calloc(nfences, sizeof(*fence));
1300*d83cc019SAndroid Build Coastguard Worker 	fence->handle = syncobj_create(fd);
1301*d83cc019SAndroid Build Coastguard Worker 	export = syncobj_export(fd, fence->handle);
1302*d83cc019SAndroid Build Coastguard Worker 	for (int i = 1; i < nfences; i++)
1303*d83cc019SAndroid Build Coastguard Worker 		fence[i].handle = syncobj_import(fd, export);
1304*d83cc019SAndroid Build Coastguard Worker 	close(export);
1305*d83cc019SAndroid Build Coastguard Worker 
1306*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1307*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1308*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1309*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1310*d83cc019SAndroid Build Coastguard Worker 	execbuf.cliprects_ptr = to_user_pointer(fence);
1311*d83cc019SAndroid Build Coastguard Worker 	execbuf.num_cliprects = nfences;
1312*d83cc019SAndroid Build Coastguard Worker 
1313*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1314*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1315*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1316*d83cc019SAndroid Build Coastguard Worker 
1317*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < nfences; i++)
1318*d83cc019SAndroid Build Coastguard Worker 		fence[i].flags = LOCAL_EXEC_FENCE_SIGNAL;
1319*d83cc019SAndroid Build Coastguard Worker 
1320*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
1321*d83cc019SAndroid Build Coastguard Worker 
1322*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < nfences; i++) {
1323*d83cc019SAndroid Build Coastguard Worker 		igt_assert(syncobj_busy(fd, fence[i].handle));
1324*d83cc019SAndroid Build Coastguard Worker 		fence[i].flags |= LOCAL_EXEC_FENCE_WAIT;
1325*d83cc019SAndroid Build Coastguard Worker 	}
1326*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, obj.handle));
1327*d83cc019SAndroid Build Coastguard Worker 
1328*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
1329*d83cc019SAndroid Build Coastguard Worker 
1330*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < nfences; i++)
1331*d83cc019SAndroid Build Coastguard Worker 		igt_assert(syncobj_busy(fd, fence[i].handle));
1332*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, obj.handle));
1333*d83cc019SAndroid Build Coastguard Worker 
1334*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
1335*d83cc019SAndroid Build Coastguard Worker 
1336*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, obj.handle);
1337*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1338*d83cc019SAndroid Build Coastguard Worker 
1339*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < nfences; i++) {
1340*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!syncobj_busy(fd, fence[i].handle));
1341*d83cc019SAndroid Build Coastguard Worker 		syncobj_destroy(fd, fence[i].handle);
1342*d83cc019SAndroid Build Coastguard Worker 	}
1343*d83cc019SAndroid Build Coastguard Worker 	free(fence);
1344*d83cc019SAndroid Build Coastguard Worker }
1345*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_import(int fd)1346*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_import(int fd)
1347*d83cc019SAndroid Build Coastguard Worker {
1348*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1349*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1350*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1351*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = igt_spin_new(fd);
1352*d83cc019SAndroid Build Coastguard Worker 	uint32_t sync = syncobj_create(fd);
1353*d83cc019SAndroid Build Coastguard Worker 	int fence;
1354*d83cc019SAndroid Build Coastguard Worker 
1355*d83cc019SAndroid Build Coastguard Worker 	/* Check that we can create a syncobj from an explicit fence (which
1356*d83cc019SAndroid Build Coastguard Worker 	 * uses sync_file) and that it acts just like a regular fence.
1357*d83cc019SAndroid Build Coastguard Worker 	 */
1358*d83cc019SAndroid Build Coastguard Worker 
1359*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1360*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1361*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1362*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_OUT;
1363*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd2 = -1;
1364*d83cc019SAndroid Build Coastguard Worker 
1365*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1366*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1367*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1368*d83cc019SAndroid Build Coastguard Worker 
1369*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf_wr(fd, &execbuf);
1370*d83cc019SAndroid Build Coastguard Worker 
1371*d83cc019SAndroid Build Coastguard Worker 	fence = execbuf.rsvd2 >> 32;
1372*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fence_busy(fence));
1373*d83cc019SAndroid Build Coastguard Worker 	syncobj_from_sync_file(fd, sync, fence);
1374*d83cc019SAndroid Build Coastguard Worker 	close(fence);
1375*d83cc019SAndroid Build Coastguard Worker 
1376*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, obj.handle));
1377*d83cc019SAndroid Build Coastguard Worker 	igt_assert(syncobj_busy(fd, sync));
1378*d83cc019SAndroid Build Coastguard Worker 
1379*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
1380*d83cc019SAndroid Build Coastguard Worker 
1381*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, obj.handle);
1382*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!gem_bo_busy(fd, obj.handle));
1383*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!syncobj_busy(fd, sync));
1384*d83cc019SAndroid Build Coastguard Worker 
1385*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1386*d83cc019SAndroid Build Coastguard Worker 	syncobj_destroy(fd, sync);
1387*d83cc019SAndroid Build Coastguard Worker }
1388*d83cc019SAndroid Build Coastguard Worker 
test_syncobj_channel(int fd)1389*d83cc019SAndroid Build Coastguard Worker static void test_syncobj_channel(int fd)
1390*d83cc019SAndroid Build Coastguard Worker {
1391*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
1392*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
1393*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
1394*d83cc019SAndroid Build Coastguard Worker 	unsigned int *control;
1395*d83cc019SAndroid Build Coastguard Worker 	int syncobj[3];
1396*d83cc019SAndroid Build Coastguard Worker 
1397*d83cc019SAndroid Build Coastguard Worker 	/* Create a pair of channels (like a pipe) between two clients
1398*d83cc019SAndroid Build Coastguard Worker 	 * and try to create races on the syncobj.
1399*d83cc019SAndroid Build Coastguard Worker 	 */
1400*d83cc019SAndroid Build Coastguard Worker 
1401*d83cc019SAndroid Build Coastguard Worker 	control = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
1402*d83cc019SAndroid Build Coastguard Worker 	igt_assert(control != MAP_FAILED);
1403*d83cc019SAndroid Build Coastguard Worker 
1404*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
1405*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(&obj);
1406*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
1407*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = LOCAL_EXEC_FENCE_OUT;
1408*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd2 = -1;
1409*d83cc019SAndroid Build Coastguard Worker 
1410*d83cc019SAndroid Build Coastguard Worker 	memset(&obj, 0, sizeof(obj));
1411*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(fd, 4096);
1412*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
1413*d83cc019SAndroid Build Coastguard Worker 
1414*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < ARRAY_SIZE(syncobj); i++) {
1415*d83cc019SAndroid Build Coastguard Worker 		struct local_gem_exec_fence fence;
1416*d83cc019SAndroid Build Coastguard Worker 
1417*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1418*d83cc019SAndroid Build Coastguard Worker 		execbuf.cliprects_ptr = to_user_pointer(&fence);
1419*d83cc019SAndroid Build Coastguard Worker 		execbuf.num_cliprects = 1;
1420*d83cc019SAndroid Build Coastguard Worker 
1421*d83cc019SAndroid Build Coastguard Worker 		/* Create a primed fence */
1422*d83cc019SAndroid Build Coastguard Worker 		fence.handle = syncobj_create(fd);
1423*d83cc019SAndroid Build Coastguard Worker 		fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
1424*d83cc019SAndroid Build Coastguard Worker 
1425*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(fd, &execbuf);
1426*d83cc019SAndroid Build Coastguard Worker 
1427*d83cc019SAndroid Build Coastguard Worker 		syncobj[i] = fence.handle;
1428*d83cc019SAndroid Build Coastguard Worker 	}
1429*d83cc019SAndroid Build Coastguard Worker 
1430*d83cc019SAndroid Build Coastguard Worker 	/* Two processes in ping-pong unison (pipe), one out of sync */
1431*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1432*d83cc019SAndroid Build Coastguard Worker 		struct local_gem_exec_fence fence[3];
1433*d83cc019SAndroid Build Coastguard Worker 		unsigned long count;
1434*d83cc019SAndroid Build Coastguard Worker 
1435*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1436*d83cc019SAndroid Build Coastguard Worker 		execbuf.cliprects_ptr = to_user_pointer(fence);
1437*d83cc019SAndroid Build Coastguard Worker 		execbuf.num_cliprects = 3;
1438*d83cc019SAndroid Build Coastguard Worker 
1439*d83cc019SAndroid Build Coastguard Worker 		fence[0].handle = syncobj[0];
1440*d83cc019SAndroid Build Coastguard Worker 		fence[0].flags = LOCAL_EXEC_FENCE_SIGNAL;
1441*d83cc019SAndroid Build Coastguard Worker 
1442*d83cc019SAndroid Build Coastguard Worker 		fence[1].handle = syncobj[1];
1443*d83cc019SAndroid Build Coastguard Worker 		fence[1].flags = LOCAL_EXEC_FENCE_WAIT;
1444*d83cc019SAndroid Build Coastguard Worker 
1445*d83cc019SAndroid Build Coastguard Worker 		fence[2].handle = syncobj[2];
1446*d83cc019SAndroid Build Coastguard Worker 		fence[2].flags = LOCAL_EXEC_FENCE_WAIT;
1447*d83cc019SAndroid Build Coastguard Worker 
1448*d83cc019SAndroid Build Coastguard Worker 		count = 0;
1449*d83cc019SAndroid Build Coastguard Worker 		while (!*(volatile unsigned *)control) {
1450*d83cc019SAndroid Build Coastguard Worker 			gem_execbuf(fd, &execbuf);
1451*d83cc019SAndroid Build Coastguard Worker 			count++;
1452*d83cc019SAndroid Build Coastguard Worker 		}
1453*d83cc019SAndroid Build Coastguard Worker 
1454*d83cc019SAndroid Build Coastguard Worker 		control[1] = count;
1455*d83cc019SAndroid Build Coastguard Worker 	}
1456*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1457*d83cc019SAndroid Build Coastguard Worker 		struct local_gem_exec_fence fence[3];
1458*d83cc019SAndroid Build Coastguard Worker 		unsigned long count;
1459*d83cc019SAndroid Build Coastguard Worker 
1460*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1461*d83cc019SAndroid Build Coastguard Worker 		execbuf.cliprects_ptr = to_user_pointer(fence);
1462*d83cc019SAndroid Build Coastguard Worker 		execbuf.num_cliprects = 3;
1463*d83cc019SAndroid Build Coastguard Worker 
1464*d83cc019SAndroid Build Coastguard Worker 		fence[0].handle = syncobj[0];
1465*d83cc019SAndroid Build Coastguard Worker 		fence[0].flags = LOCAL_EXEC_FENCE_WAIT;
1466*d83cc019SAndroid Build Coastguard Worker 
1467*d83cc019SAndroid Build Coastguard Worker 		fence[1].handle = syncobj[1];
1468*d83cc019SAndroid Build Coastguard Worker 		fence[1].flags = LOCAL_EXEC_FENCE_SIGNAL;
1469*d83cc019SAndroid Build Coastguard Worker 
1470*d83cc019SAndroid Build Coastguard Worker 		fence[2].handle = syncobj[2];
1471*d83cc019SAndroid Build Coastguard Worker 		fence[2].flags = LOCAL_EXEC_FENCE_WAIT;
1472*d83cc019SAndroid Build Coastguard Worker 
1473*d83cc019SAndroid Build Coastguard Worker 		count = 0;
1474*d83cc019SAndroid Build Coastguard Worker 		while (!*(volatile unsigned *)control) {
1475*d83cc019SAndroid Build Coastguard Worker 			gem_execbuf(fd, &execbuf);
1476*d83cc019SAndroid Build Coastguard Worker 			count++;
1477*d83cc019SAndroid Build Coastguard Worker 		}
1478*d83cc019SAndroid Build Coastguard Worker 		control[2] = count;
1479*d83cc019SAndroid Build Coastguard Worker 	}
1480*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1481*d83cc019SAndroid Build Coastguard Worker 		struct local_gem_exec_fence fence;
1482*d83cc019SAndroid Build Coastguard Worker 		unsigned long count;
1483*d83cc019SAndroid Build Coastguard Worker 
1484*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
1485*d83cc019SAndroid Build Coastguard Worker 		execbuf.cliprects_ptr = to_user_pointer(&fence);
1486*d83cc019SAndroid Build Coastguard Worker 		execbuf.num_cliprects = 1;
1487*d83cc019SAndroid Build Coastguard Worker 
1488*d83cc019SAndroid Build Coastguard Worker 		fence.handle = syncobj[2];
1489*d83cc019SAndroid Build Coastguard Worker 		fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
1490*d83cc019SAndroid Build Coastguard Worker 
1491*d83cc019SAndroid Build Coastguard Worker 		count = 0;
1492*d83cc019SAndroid Build Coastguard Worker 		while (!*(volatile unsigned *)control) {
1493*d83cc019SAndroid Build Coastguard Worker 			gem_execbuf(fd, &execbuf);
1494*d83cc019SAndroid Build Coastguard Worker 			count++;
1495*d83cc019SAndroid Build Coastguard Worker 		}
1496*d83cc019SAndroid Build Coastguard Worker 		control[3] = count;
1497*d83cc019SAndroid Build Coastguard Worker 	}
1498*d83cc019SAndroid Build Coastguard Worker 
1499*d83cc019SAndroid Build Coastguard Worker 	sleep(1);
1500*d83cc019SAndroid Build Coastguard Worker 	*control = 1;
1501*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1502*d83cc019SAndroid Build Coastguard Worker 
1503*d83cc019SAndroid Build Coastguard Worker 	igt_info("Pipe=[%u, %u], gooseberry=%u\n",
1504*d83cc019SAndroid Build Coastguard Worker 		 control[1], control[2], control[3]);
1505*d83cc019SAndroid Build Coastguard Worker 	munmap(control, 4096);
1506*d83cc019SAndroid Build Coastguard Worker 
1507*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, obj.handle);
1508*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj.handle);
1509*d83cc019SAndroid Build Coastguard Worker 
1510*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < ARRAY_SIZE(syncobj); i++)
1511*d83cc019SAndroid Build Coastguard Worker 		syncobj_destroy(fd, syncobj[i]);
1512*d83cc019SAndroid Build Coastguard Worker }
1513*d83cc019SAndroid Build Coastguard Worker 
1514*d83cc019SAndroid Build Coastguard Worker igt_main
1515*d83cc019SAndroid Build Coastguard Worker {
1516*d83cc019SAndroid Build Coastguard Worker 	const struct intel_execution_engine *e;
1517*d83cc019SAndroid Build Coastguard Worker 	int i915 = -1;
1518*d83cc019SAndroid Build Coastguard Worker 
1519*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
1520*d83cc019SAndroid Build Coastguard Worker 		i915 = drm_open_driver_master(DRIVER_INTEL);
1521*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(i915);
1522*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_has_exec_fence(i915));
1523*d83cc019SAndroid Build Coastguard Worker 		gem_require_mmap_wc(i915);
1524*d83cc019SAndroid Build Coastguard Worker 
1525*d83cc019SAndroid Build Coastguard Worker 		gem_submission_print_method(i915);
1526*d83cc019SAndroid Build Coastguard Worker 	}
1527*d83cc019SAndroid Build Coastguard Worker 
1528*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group {
1529*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
1530*d83cc019SAndroid Build Coastguard Worker 			igt_fork_hang_detector(i915);
1531*d83cc019SAndroid Build Coastguard Worker 		}
1532*d83cc019SAndroid Build Coastguard Worker 
1533*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("basic-busy-all")
1534*d83cc019SAndroid Build Coastguard Worker 			test_fence_busy_all(i915, 0);
1535*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("basic-wait-all")
1536*d83cc019SAndroid Build Coastguard Worker 			test_fence_busy_all(i915, WAIT);
1537*d83cc019SAndroid Build Coastguard Worker 
1538*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
1539*d83cc019SAndroid Build Coastguard Worker 			igt_stop_hang_detector();
1540*d83cc019SAndroid Build Coastguard Worker 		}
1541*d83cc019SAndroid Build Coastguard Worker 
1542*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("busy-hang-all")
1543*d83cc019SAndroid Build Coastguard Worker 			test_fence_busy_all(i915, HANG);
1544*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("wait-hang-all")
1545*d83cc019SAndroid Build Coastguard Worker 			test_fence_busy_all(i915, WAIT | HANG);
1546*d83cc019SAndroid Build Coastguard Worker 	}
1547*d83cc019SAndroid Build Coastguard Worker 
1548*d83cc019SAndroid Build Coastguard Worker 	for (e = intel_execution_engines; e->name; e++) {
1549*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_group {
1550*d83cc019SAndroid Build Coastguard Worker 			igt_fixture {
1551*d83cc019SAndroid Build Coastguard Worker 				igt_require(gem_has_ring(i915, e->exec_id | e->flags));
1552*d83cc019SAndroid Build Coastguard Worker 				igt_require(gem_can_store_dword(i915, e->exec_id | e->flags));
1553*d83cc019SAndroid Build Coastguard Worker 			}
1554*d83cc019SAndroid Build Coastguard Worker 
1555*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1556*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1557*d83cc019SAndroid Build Coastguard Worker 					igt_fork_hang_detector(i915);
1558*d83cc019SAndroid Build Coastguard Worker 				}
1559*d83cc019SAndroid Build Coastguard Worker 
1560*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%sbusy-%s",
1561*d83cc019SAndroid Build Coastguard Worker 						e->exec_id == 0 ? "basic-" : "",
1562*d83cc019SAndroid Build Coastguard Worker 						e->name)
1563*d83cc019SAndroid Build Coastguard Worker 					test_fence_busy(i915, e->exec_id | e->flags, 0);
1564*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%swait-%s",
1565*d83cc019SAndroid Build Coastguard Worker 						e->exec_id == 0 ? "basic-" : "",
1566*d83cc019SAndroid Build Coastguard Worker 						e->name)
1567*d83cc019SAndroid Build Coastguard Worker 					test_fence_busy(i915, e->exec_id | e->flags, WAIT);
1568*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("%sawait-%s",
1569*d83cc019SAndroid Build Coastguard Worker 						e->exec_id == 0 ? "basic-" : "",
1570*d83cc019SAndroid Build Coastguard Worker 						e->name)
1571*d83cc019SAndroid Build Coastguard Worker 					test_fence_await(i915, e->exec_id | e->flags, 0);
1572*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("nb-await-%s", e->name)
1573*d83cc019SAndroid Build Coastguard Worker 					test_fence_await(i915, e->exec_id | e->flags, NONBLOCK);
1574*d83cc019SAndroid Build Coastguard Worker 
1575*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("keep-in-fence-%s", e->name)
1576*d83cc019SAndroid Build Coastguard Worker 					test_keep_in_fence(i915, e->exec_id | e->flags, 0);
1577*d83cc019SAndroid Build Coastguard Worker 
1578*d83cc019SAndroid Build Coastguard Worker 				if (e->exec_id &&
1579*d83cc019SAndroid Build Coastguard Worker 				    !(e->exec_id == I915_EXEC_BSD && !e->flags)) {
1580*d83cc019SAndroid Build Coastguard Worker 					igt_subtest_f("parallel-%s", e->name) {
1581*d83cc019SAndroid Build Coastguard Worker 						igt_require(has_submit_fence(i915));
1582*d83cc019SAndroid Build Coastguard Worker 						igt_until_timeout(2)
1583*d83cc019SAndroid Build Coastguard Worker 							test_parallel(i915, e->exec_id | e->flags);
1584*d83cc019SAndroid Build Coastguard Worker 					}
1585*d83cc019SAndroid Build Coastguard Worker 				}
1586*d83cc019SAndroid Build Coastguard Worker 
1587*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1588*d83cc019SAndroid Build Coastguard Worker 					igt_stop_hang_detector();
1589*d83cc019SAndroid Build Coastguard Worker 				}
1590*d83cc019SAndroid Build Coastguard Worker 			}
1591*d83cc019SAndroid Build Coastguard Worker 
1592*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
1593*d83cc019SAndroid Build Coastguard Worker 				igt_hang_t hang;
1594*d83cc019SAndroid Build Coastguard Worker 
1595*d83cc019SAndroid Build Coastguard Worker 				igt_skip_on_simulation();
1596*d83cc019SAndroid Build Coastguard Worker 
1597*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1598*d83cc019SAndroid Build Coastguard Worker 					hang = igt_allow_hang(i915, 0, 0);
1599*d83cc019SAndroid Build Coastguard Worker 				}
1600*d83cc019SAndroid Build Coastguard Worker 
1601*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("busy-hang-%s", e->name)
1602*d83cc019SAndroid Build Coastguard Worker 					test_fence_busy(i915, e->exec_id | e->flags, HANG);
1603*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("wait-hang-%s", e->name)
1604*d83cc019SAndroid Build Coastguard Worker 					test_fence_busy(i915, e->exec_id | e->flags, HANG | WAIT);
1605*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("await-hang-%s", e->name)
1606*d83cc019SAndroid Build Coastguard Worker 					test_fence_await(i915, e->exec_id | e->flags, HANG);
1607*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("nb-await-hang-%s", e->name)
1608*d83cc019SAndroid Build Coastguard Worker 					test_fence_await(i915, e->exec_id | e->flags, NONBLOCK | HANG);
1609*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
1610*d83cc019SAndroid Build Coastguard Worker 					igt_disallow_hang(i915, hang);
1611*d83cc019SAndroid Build Coastguard Worker 				}
1612*d83cc019SAndroid Build Coastguard Worker 			}
1613*d83cc019SAndroid Build Coastguard Worker 		}
1614*d83cc019SAndroid Build Coastguard Worker 	}
1615*d83cc019SAndroid Build Coastguard Worker 
1616*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group {
1617*d83cc019SAndroid Build Coastguard Worker 		long ring_size = 0;
1618*d83cc019SAndroid Build Coastguard Worker 
1619*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
1620*d83cc019SAndroid Build Coastguard Worker 			ring_size = gem_measure_ring_inflight(i915, ALL_ENGINES, 0) - 1;
1621*d83cc019SAndroid Build Coastguard Worker 			igt_info("Ring size: %ld batches\n", ring_size);
1622*d83cc019SAndroid Build Coastguard Worker 			igt_require(ring_size);
1623*d83cc019SAndroid Build Coastguard Worker 
1624*d83cc019SAndroid Build Coastguard Worker 			gem_require_contexts(i915);
1625*d83cc019SAndroid Build Coastguard Worker 		}
1626*d83cc019SAndroid Build Coastguard Worker 
1627*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("long-history")
1628*d83cc019SAndroid Build Coastguard Worker 			test_long_history(i915, ring_size, 0);
1629*d83cc019SAndroid Build Coastguard Worker 
1630*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("expired-history")
1631*d83cc019SAndroid Build Coastguard Worker 			test_long_history(i915, ring_size, EXPIRED);
1632*d83cc019SAndroid Build Coastguard Worker 	}
1633*d83cc019SAndroid Build Coastguard Worker 
1634*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("flip") {
1635*d83cc019SAndroid Build Coastguard Worker 		gem_quiescent_gpu(i915);
1636*d83cc019SAndroid Build Coastguard Worker 		test_fence_flip(i915);
1637*d83cc019SAndroid Build Coastguard Worker 	}
1638*d83cc019SAndroid Build Coastguard Worker 
1639*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group { /* syncobj */
1640*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
1641*d83cc019SAndroid Build Coastguard Worker 			igt_require(exec_has_fence_array(i915));
1642*d83cc019SAndroid Build Coastguard Worker 			igt_assert(has_syncobj(i915));
1643*d83cc019SAndroid Build Coastguard Worker 			igt_fork_hang_detector(i915);
1644*d83cc019SAndroid Build Coastguard Worker 		}
1645*d83cc019SAndroid Build Coastguard Worker 
1646*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("invalid-fence-array")
1647*d83cc019SAndroid Build Coastguard Worker 			test_invalid_fence_array(i915);
1648*d83cc019SAndroid Build Coastguard Worker 
1649*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-unused-fence")
1650*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_unused_fence(i915);
1651*d83cc019SAndroid Build Coastguard Worker 
1652*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-invalid-wait")
1653*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_invalid_wait(i915);
1654*d83cc019SAndroid Build Coastguard Worker 
1655*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-invalid-flags")
1656*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_invalid_flags(i915);
1657*d83cc019SAndroid Build Coastguard Worker 
1658*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-signal")
1659*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_signal(i915);
1660*d83cc019SAndroid Build Coastguard Worker 
1661*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-wait")
1662*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_wait(i915);
1663*d83cc019SAndroid Build Coastguard Worker 
1664*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-export")
1665*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_export(i915);
1666*d83cc019SAndroid Build Coastguard Worker 
1667*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-repeat")
1668*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_repeat(i915);
1669*d83cc019SAndroid Build Coastguard Worker 
1670*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-import")
1671*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_import(i915);
1672*d83cc019SAndroid Build Coastguard Worker 
1673*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("syncobj-channel")
1674*d83cc019SAndroid Build Coastguard Worker 			test_syncobj_channel(i915);
1675*d83cc019SAndroid Build Coastguard Worker 
1676*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
1677*d83cc019SAndroid Build Coastguard Worker 			igt_stop_hang_detector();
1678*d83cc019SAndroid Build Coastguard Worker 		}
1679*d83cc019SAndroid Build Coastguard Worker 	}
1680*d83cc019SAndroid Build Coastguard Worker 
1681*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
1682*d83cc019SAndroid Build Coastguard Worker 		close(i915);
1683*d83cc019SAndroid Build Coastguard Worker 	}
1684*d83cc019SAndroid Build Coastguard Worker }
1685