xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_busy.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 <sched.h>
25*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
26*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
27*d83cc019SAndroid Build Coastguard Worker 
28*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
29*d83cc019SAndroid Build Coastguard Worker #include "igt_rand.h"
30*d83cc019SAndroid Build Coastguard Worker #include "igt_vgem.h"
31*d83cc019SAndroid Build Coastguard Worker #include "i915/gem_ring.h"
32*d83cc019SAndroid Build Coastguard Worker 
33*d83cc019SAndroid Build Coastguard Worker #define LOCAL_EXEC_NO_RELOC (1<<11)
34*d83cc019SAndroid Build Coastguard Worker #define PAGE_ALIGN(x) ALIGN(x, 4096)
35*d83cc019SAndroid Build Coastguard Worker 
36*d83cc019SAndroid Build Coastguard Worker /* Exercise the busy-ioctl, ensuring the ABI is never broken */
37*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Basic check of busy-ioctl ABI.");
38*d83cc019SAndroid Build Coastguard Worker 
39*d83cc019SAndroid Build Coastguard Worker enum { TEST = 0, BUSY, BATCH };
40*d83cc019SAndroid Build Coastguard Worker 
gem_busy(int fd,uint32_t handle)41*d83cc019SAndroid Build Coastguard Worker static bool gem_busy(int fd, uint32_t handle)
42*d83cc019SAndroid Build Coastguard Worker {
43*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_busy busy;
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker 	memset(&busy, 0, sizeof(busy));
46*d83cc019SAndroid Build Coastguard Worker 	busy.handle = handle;
47*d83cc019SAndroid Build Coastguard Worker 
48*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker 	return busy.busy != 0;
51*d83cc019SAndroid Build Coastguard Worker }
52*d83cc019SAndroid Build Coastguard Worker 
__gem_busy(int fd,uint32_t handle,uint32_t * read,uint32_t * write)53*d83cc019SAndroid Build Coastguard Worker static void __gem_busy(int fd,
54*d83cc019SAndroid Build Coastguard Worker 		       uint32_t handle,
55*d83cc019SAndroid Build Coastguard Worker 		       uint32_t *read,
56*d83cc019SAndroid Build Coastguard Worker 		       uint32_t *write)
57*d83cc019SAndroid Build Coastguard Worker {
58*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_busy busy;
59*d83cc019SAndroid Build Coastguard Worker 
60*d83cc019SAndroid Build Coastguard Worker 	memset(&busy, 0, sizeof(busy));
61*d83cc019SAndroid Build Coastguard Worker 	busy.handle = handle;
62*d83cc019SAndroid Build Coastguard Worker 
63*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
64*d83cc019SAndroid Build Coastguard Worker 
65*d83cc019SAndroid Build Coastguard Worker 	*write = busy.busy & 0xffff;
66*d83cc019SAndroid Build Coastguard Worker 	*read = busy.busy >> 16;
67*d83cc019SAndroid Build Coastguard Worker }
68*d83cc019SAndroid Build Coastguard Worker 
exec_noop(int fd,uint32_t * handles,unsigned flags,bool write)69*d83cc019SAndroid Build Coastguard Worker static bool exec_noop(int fd,
70*d83cc019SAndroid Build Coastguard Worker 		      uint32_t *handles,
71*d83cc019SAndroid Build Coastguard Worker 		      unsigned flags,
72*d83cc019SAndroid Build Coastguard Worker 		      bool write)
73*d83cc019SAndroid Build Coastguard Worker {
74*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
75*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 exec[3];
76*d83cc019SAndroid Build Coastguard Worker 
77*d83cc019SAndroid Build Coastguard Worker 	memset(exec, 0, sizeof(exec));
78*d83cc019SAndroid Build Coastguard Worker 	exec[0].handle = handles[BUSY];
79*d83cc019SAndroid Build Coastguard Worker 	exec[1].handle = handles[TEST];
80*d83cc019SAndroid Build Coastguard Worker 	if (write)
81*d83cc019SAndroid Build Coastguard Worker 		exec[1].flags |= EXEC_OBJECT_WRITE;
82*d83cc019SAndroid Build Coastguard Worker 	exec[2].handle = handles[BATCH];
83*d83cc019SAndroid Build Coastguard Worker 
84*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
85*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(exec);
86*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 3;
87*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = flags;
88*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Queuing handle for %s on engine %d\n",
89*d83cc019SAndroid Build Coastguard Worker 		  write ? "writing" : "reading", flags);
90*d83cc019SAndroid Build Coastguard Worker 	return __gem_execbuf(fd, &execbuf) == 0;
91*d83cc019SAndroid Build Coastguard Worker }
92*d83cc019SAndroid Build Coastguard Worker 
still_busy(int fd,uint32_t handle)93*d83cc019SAndroid Build Coastguard Worker static bool still_busy(int fd, uint32_t handle)
94*d83cc019SAndroid Build Coastguard Worker {
95*d83cc019SAndroid Build Coastguard Worker 	uint32_t read, write;
96*d83cc019SAndroid Build Coastguard Worker 	__gem_busy(fd, handle, &read, &write);
97*d83cc019SAndroid Build Coastguard Worker 	return write;
98*d83cc019SAndroid Build Coastguard Worker }
99*d83cc019SAndroid Build Coastguard Worker 
semaphore(int fd,const struct intel_execution_engine2 * e)100*d83cc019SAndroid Build Coastguard Worker static void semaphore(int fd, const struct intel_execution_engine2 *e)
101*d83cc019SAndroid Build Coastguard Worker {
102*d83cc019SAndroid Build Coastguard Worker 	struct intel_execution_engine2 *__e;
103*d83cc019SAndroid Build Coastguard Worker 	uint32_t bbe = MI_BATCH_BUFFER_END;
104*d83cc019SAndroid Build Coastguard Worker 	const unsigned uabi = e->class;
105*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
106*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle[3];
107*d83cc019SAndroid Build Coastguard Worker 	uint32_t read, write;
108*d83cc019SAndroid Build Coastguard Worker 	uint32_t active;
109*d83cc019SAndroid Build Coastguard Worker 	unsigned i;
110*d83cc019SAndroid Build Coastguard Worker 
111*d83cc019SAndroid Build Coastguard Worker 	handle[TEST] = gem_create(fd, 4096);
112*d83cc019SAndroid Build Coastguard Worker 	handle[BATCH] = gem_create(fd, 4096);
113*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, handle[BATCH], 0, &bbe, sizeof(bbe));
114*d83cc019SAndroid Build Coastguard Worker 
115*d83cc019SAndroid Build Coastguard Worker 	/* Create a long running batch which we can use to hog the GPU */
116*d83cc019SAndroid Build Coastguard Worker 	handle[BUSY] = gem_create(fd, 4096);
117*d83cc019SAndroid Build Coastguard Worker 	spin = igt_spin_new(fd,
118*d83cc019SAndroid Build Coastguard Worker 			    .engine = e->flags,
119*d83cc019SAndroid Build Coastguard Worker 			    .dependency = handle[BUSY]);
120*d83cc019SAndroid Build Coastguard Worker 
121*d83cc019SAndroid Build Coastguard Worker 	/* Queue a batch after the busy, it should block and remain "busy" */
122*d83cc019SAndroid Build Coastguard Worker 	igt_assert(exec_noop(fd, handle, e->flags, false));
123*d83cc019SAndroid Build Coastguard Worker 	igt_assert(still_busy(fd, handle[BUSY]));
124*d83cc019SAndroid Build Coastguard Worker 	__gem_busy(fd, handle[TEST], &read, &write);
125*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(read, 1 << uabi);
126*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(write, 0);
127*d83cc019SAndroid Build Coastguard Worker 
128*d83cc019SAndroid Build Coastguard Worker 	/* Requeue with a write */
129*d83cc019SAndroid Build Coastguard Worker 	igt_assert(exec_noop(fd, handle, e->flags, true));
130*d83cc019SAndroid Build Coastguard Worker 	igt_assert(still_busy(fd, handle[BUSY]));
131*d83cc019SAndroid Build Coastguard Worker 	__gem_busy(fd, handle[TEST], &read, &write);
132*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(read, 1 << uabi);
133*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(write, 1 + uabi);
134*d83cc019SAndroid Build Coastguard Worker 
135*d83cc019SAndroid Build Coastguard Worker 	/* Now queue it for a read across all available rings */
136*d83cc019SAndroid Build Coastguard Worker 	active = 0;
137*d83cc019SAndroid Build Coastguard Worker 	__for_each_physical_engine(fd, __e) {
138*d83cc019SAndroid Build Coastguard Worker 		if (exec_noop(fd, handle, __e->flags, false))
139*d83cc019SAndroid Build Coastguard Worker 			active |= 1 << __e->class;
140*d83cc019SAndroid Build Coastguard Worker 	}
141*d83cc019SAndroid Build Coastguard Worker 	igt_assert(still_busy(fd, handle[BUSY]));
142*d83cc019SAndroid Build Coastguard Worker 	__gem_busy(fd, handle[TEST], &read, &write);
143*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(read, active);
144*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(write, 1 + uabi); /* from the earlier write */
145*d83cc019SAndroid Build Coastguard Worker 
146*d83cc019SAndroid Build Coastguard Worker 	/* Check that our long batch was long enough */
147*d83cc019SAndroid Build Coastguard Worker 	igt_assert(still_busy(fd, handle[BUSY]));
148*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
149*d83cc019SAndroid Build Coastguard Worker 
150*d83cc019SAndroid Build Coastguard Worker 	/* And make sure it becomes idle again */
151*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, handle[TEST]);
152*d83cc019SAndroid Build Coastguard Worker 	__gem_busy(fd, handle[TEST], &read, &write);
153*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(read, 0);
154*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(write, 0);
155*d83cc019SAndroid Build Coastguard Worker 
156*d83cc019SAndroid Build Coastguard Worker 	for (i = TEST; i <= BATCH; i++)
157*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, handle[i]);
158*d83cc019SAndroid Build Coastguard Worker }
159*d83cc019SAndroid Build Coastguard Worker 
160*d83cc019SAndroid Build Coastguard Worker #define PARALLEL 1
161*d83cc019SAndroid Build Coastguard Worker #define HANG 2
one(int fd,const struct intel_execution_engine2 * e,unsigned test_flags)162*d83cc019SAndroid Build Coastguard Worker static void one(int fd, const struct intel_execution_engine2 *e, unsigned test_flags)
163*d83cc019SAndroid Build Coastguard Worker {
164*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
165*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[2];
166*d83cc019SAndroid Build Coastguard Worker #define SCRATCH 0
167*d83cc019SAndroid Build Coastguard Worker #define BATCH 1
168*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry store[1024+1];
169*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
170*d83cc019SAndroid Build Coastguard Worker 	unsigned size = ALIGN(ARRAY_SIZE(store)*16 + 4, 4096);
171*d83cc019SAndroid Build Coastguard Worker 	const unsigned uabi = e->class;
172*d83cc019SAndroid Build Coastguard Worker 	uint32_t read[2], write[2];
173*d83cc019SAndroid Build Coastguard Worker 	struct timespec tv;
174*d83cc019SAndroid Build Coastguard Worker 	uint32_t *batch, *bbe;
175*d83cc019SAndroid Build Coastguard Worker 	int i, count, timeout;
176*d83cc019SAndroid Build Coastguard Worker 
177*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
178*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj);
179*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 2;
180*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = e->flags;
181*d83cc019SAndroid Build Coastguard Worker 	if (gen < 6)
182*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags |= I915_EXEC_SECURE;
183*d83cc019SAndroid Build Coastguard Worker 
184*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
185*d83cc019SAndroid Build Coastguard Worker 	obj[SCRATCH].handle = gem_create(fd, 4096);
186*d83cc019SAndroid Build Coastguard Worker 
187*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].handle = gem_create(fd, size);
188*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocs_ptr = to_user_pointer(store);
189*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocation_count = ARRAY_SIZE(store);
190*d83cc019SAndroid Build Coastguard Worker 	memset(store, 0, sizeof(store));
191*d83cc019SAndroid Build Coastguard Worker 
192*d83cc019SAndroid Build Coastguard Worker 	batch = gem_mmap__wc(fd, obj[BATCH].handle, 0, size, PROT_WRITE);
193*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, obj[BATCH].handle,
194*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
195*d83cc019SAndroid Build Coastguard Worker 
196*d83cc019SAndroid Build Coastguard Worker 	i = 0;
197*d83cc019SAndroid Build Coastguard Worker 	for (count = 0; count < 1024; count++) {
198*d83cc019SAndroid Build Coastguard Worker 		store[count].target_handle = obj[SCRATCH].handle;
199*d83cc019SAndroid Build Coastguard Worker 		store[count].presumed_offset = -1;
200*d83cc019SAndroid Build Coastguard Worker 		store[count].offset = sizeof(uint32_t) * (i + 1);
201*d83cc019SAndroid Build Coastguard Worker 		store[count].delta = sizeof(uint32_t) * count;
202*d83cc019SAndroid Build Coastguard Worker 		store[count].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
203*d83cc019SAndroid Build Coastguard Worker 		store[count].write_domain = I915_GEM_DOMAIN_INSTRUCTION;
204*d83cc019SAndroid Build Coastguard Worker 		batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
205*d83cc019SAndroid Build Coastguard Worker 		if (gen >= 8) {
206*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = 0;
207*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = 0;
208*d83cc019SAndroid Build Coastguard Worker 		} else if (gen >= 4) {
209*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = 0;
210*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = 0;
211*d83cc019SAndroid Build Coastguard Worker 			store[count].offset += sizeof(uint32_t);
212*d83cc019SAndroid Build Coastguard Worker 		} else {
213*d83cc019SAndroid Build Coastguard Worker 			batch[i]--;
214*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = 0;
215*d83cc019SAndroid Build Coastguard Worker 		}
216*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = count;
217*d83cc019SAndroid Build Coastguard Worker 		i++;
218*d83cc019SAndroid Build Coastguard Worker 	}
219*d83cc019SAndroid Build Coastguard Worker 
220*d83cc019SAndroid Build Coastguard Worker 	bbe = &batch[i];
221*d83cc019SAndroid Build Coastguard Worker 	store[count].target_handle = obj[BATCH].handle; /* recurse */
222*d83cc019SAndroid Build Coastguard Worker 	store[count].presumed_offset = 0;
223*d83cc019SAndroid Build Coastguard Worker 	store[count].offset = sizeof(uint32_t) * (i + 1);
224*d83cc019SAndroid Build Coastguard Worker 	store[count].delta = 0;
225*d83cc019SAndroid Build Coastguard Worker 	store[count].read_domains = I915_GEM_DOMAIN_COMMAND;
226*d83cc019SAndroid Build Coastguard Worker 	store[count].write_domain = 0;
227*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_BATCH_BUFFER_START;
228*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
229*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8 | 1;
230*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
231*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
232*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 6) {
233*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8;
234*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
235*d83cc019SAndroid Build Coastguard Worker 	} else {
236*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 2 << 6;
237*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
238*d83cc019SAndroid Build Coastguard Worker 		if (gen < 4) {
239*d83cc019SAndroid Build Coastguard Worker 			batch[i] |= 1;
240*d83cc019SAndroid Build Coastguard Worker 			store[count].delta = 1;
241*d83cc019SAndroid Build Coastguard Worker 		}
242*d83cc019SAndroid Build Coastguard Worker 	}
243*d83cc019SAndroid Build Coastguard Worker 	i++;
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 	igt_assert(i < size/sizeof(*batch));
246*d83cc019SAndroid Build Coastguard Worker 	igt_require(__gem_execbuf(fd, &execbuf) == 0);
247*d83cc019SAndroid Build Coastguard Worker 
248*d83cc019SAndroid Build Coastguard Worker 	__gem_busy(fd, obj[SCRATCH].handle, &read[SCRATCH], &write[SCRATCH]);
249*d83cc019SAndroid Build Coastguard Worker 	__gem_busy(fd, obj[BATCH].handle, &read[BATCH], &write[BATCH]);
250*d83cc019SAndroid Build Coastguard Worker 
251*d83cc019SAndroid Build Coastguard Worker 	if (test_flags & PARALLEL) {
252*d83cc019SAndroid Build Coastguard Worker 		struct intel_execution_engine2 *e2;
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 		__for_each_physical_engine(fd, e2) {
255*d83cc019SAndroid Build Coastguard Worker 			if (e2->class == e->class &&
256*d83cc019SAndroid Build Coastguard Worker 			    e2->instance == e->instance)
257*d83cc019SAndroid Build Coastguard Worker 				continue;
258*d83cc019SAndroid Build Coastguard Worker 
259*d83cc019SAndroid Build Coastguard Worker 			if (!gem_class_can_store_dword(fd, e2->class))
260*d83cc019SAndroid Build Coastguard Worker 				continue;
261*d83cc019SAndroid Build Coastguard Worker 
262*d83cc019SAndroid Build Coastguard Worker 			igt_debug("Testing %s in parallel\n", e2->name);
263*d83cc019SAndroid Build Coastguard Worker 			one(fd, e2, 0);
264*d83cc019SAndroid Build Coastguard Worker 		}
265*d83cc019SAndroid Build Coastguard Worker 	}
266*d83cc019SAndroid Build Coastguard Worker 
267*d83cc019SAndroid Build Coastguard Worker 	timeout = 120;
268*d83cc019SAndroid Build Coastguard Worker 	if ((test_flags & HANG) == 0) {
269*d83cc019SAndroid Build Coastguard Worker 		*bbe = MI_BATCH_BUFFER_END;
270*d83cc019SAndroid Build Coastguard Worker 		__sync_synchronize();
271*d83cc019SAndroid Build Coastguard Worker 		timeout = 1;
272*d83cc019SAndroid Build Coastguard Worker 	}
273*d83cc019SAndroid Build Coastguard Worker 
274*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(write[SCRATCH], 1 + uabi);
275*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u32(read[SCRATCH], 1 << uabi);
276*d83cc019SAndroid Build Coastguard Worker 
277*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(write[BATCH], 0);
278*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u32(read[BATCH], 1 << uabi);
279*d83cc019SAndroid Build Coastguard Worker 
280*d83cc019SAndroid Build Coastguard Worker 	/* Calling busy in a loop should be enough to flush the rendering */
281*d83cc019SAndroid Build Coastguard Worker 	memset(&tv, 0, sizeof(tv));
282*d83cc019SAndroid Build Coastguard Worker 	while (gem_busy(fd, obj[BATCH].handle))
283*d83cc019SAndroid Build Coastguard Worker 		igt_assert(igt_seconds_elapsed(&tv) < timeout);
284*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!gem_busy(fd, obj[SCRATCH].handle));
285*d83cc019SAndroid Build Coastguard Worker 
286*d83cc019SAndroid Build Coastguard Worker 	munmap(batch, size);
287*d83cc019SAndroid Build Coastguard Worker 	batch = gem_mmap__wc(fd, obj[SCRATCH].handle, 0, 4096, PROT_READ);
288*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < 1024; i++)
289*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(batch[i], i);
290*d83cc019SAndroid Build Coastguard Worker 	munmap(batch, 4096);
291*d83cc019SAndroid Build Coastguard Worker 
292*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[BATCH].handle);
293*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, obj[SCRATCH].handle);
294*d83cc019SAndroid Build Coastguard Worker }
295*d83cc019SAndroid Build Coastguard Worker 
xchg_u32(void * array,unsigned i,unsigned j)296*d83cc019SAndroid Build Coastguard Worker static void xchg_u32(void *array, unsigned i, unsigned j)
297*d83cc019SAndroid Build Coastguard Worker {
298*d83cc019SAndroid Build Coastguard Worker 	uint32_t *u32 = array;
299*d83cc019SAndroid Build Coastguard Worker 	uint32_t tmp = u32[i];
300*d83cc019SAndroid Build Coastguard Worker 	u32[i] = u32[j];
301*d83cc019SAndroid Build Coastguard Worker 	u32[j] = tmp;
302*d83cc019SAndroid Build Coastguard Worker }
303*d83cc019SAndroid Build Coastguard Worker 
close_race(int fd)304*d83cc019SAndroid Build Coastguard Worker static void close_race(int fd)
305*d83cc019SAndroid Build Coastguard Worker {
306*d83cc019SAndroid Build Coastguard Worker 	const unsigned int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
307*d83cc019SAndroid Build Coastguard Worker 	const unsigned int nhandles = gem_measure_ring_inflight(fd, ALL_ENGINES, 0) / 2;
308*d83cc019SAndroid Build Coastguard Worker 	unsigned int engines[16], nengine;
309*d83cc019SAndroid Build Coastguard Worker 	unsigned long *control;
310*d83cc019SAndroid Build Coastguard Worker 	uint32_t *handles;
311*d83cc019SAndroid Build Coastguard Worker 	int i;
312*d83cc019SAndroid Build Coastguard Worker 
313*d83cc019SAndroid Build Coastguard Worker 	igt_require(ncpus > 1);
314*d83cc019SAndroid Build Coastguard Worker 	intel_require_memory(nhandles, 4096, CHECK_RAM);
315*d83cc019SAndroid Build Coastguard Worker 
316*d83cc019SAndroid Build Coastguard Worker 	/*
317*d83cc019SAndroid Build Coastguard Worker 	 * One thread spawning work and randomly closing handles.
318*d83cc019SAndroid Build Coastguard Worker 	 * One background thread per cpu checking busyness.
319*d83cc019SAndroid Build Coastguard Worker 	 */
320*d83cc019SAndroid Build Coastguard Worker 
321*d83cc019SAndroid Build Coastguard Worker 	nengine = 0;
322*d83cc019SAndroid Build Coastguard Worker 	for_each_engine(fd, i)
323*d83cc019SAndroid Build Coastguard Worker 		engines[nengine++] = i;
324*d83cc019SAndroid Build Coastguard Worker 	igt_require(nengine);
325*d83cc019SAndroid Build Coastguard Worker 
326*d83cc019SAndroid Build Coastguard Worker 	control = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
327*d83cc019SAndroid Build Coastguard Worker 	igt_assert(control != MAP_FAILED);
328*d83cc019SAndroid Build Coastguard Worker 
329*d83cc019SAndroid Build Coastguard Worker 	handles = mmap(NULL, PAGE_ALIGN(nhandles*sizeof(*handles)),
330*d83cc019SAndroid Build Coastguard Worker 		   PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
331*d83cc019SAndroid Build Coastguard Worker 	igt_assert(handles != MAP_FAILED);
332*d83cc019SAndroid Build Coastguard Worker 
333*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, ncpus - 1) {
334*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_gem_busy busy;
335*d83cc019SAndroid Build Coastguard Worker 		uint32_t indirection[nhandles];
336*d83cc019SAndroid Build Coastguard Worker 		unsigned long count = 0;
337*d83cc019SAndroid Build Coastguard Worker 
338*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < nhandles; i++)
339*d83cc019SAndroid Build Coastguard Worker 			indirection[i] = i;
340*d83cc019SAndroid Build Coastguard Worker 
341*d83cc019SAndroid Build Coastguard Worker 		hars_petruska_f54_1_random_perturb(child);
342*d83cc019SAndroid Build Coastguard Worker 
343*d83cc019SAndroid Build Coastguard Worker 		memset(&busy, 0, sizeof(busy));
344*d83cc019SAndroid Build Coastguard Worker 		do {
345*d83cc019SAndroid Build Coastguard Worker 			igt_permute_array(indirection, nhandles, xchg_u32);
346*d83cc019SAndroid Build Coastguard Worker 			__sync_synchronize();
347*d83cc019SAndroid Build Coastguard Worker 			for (i = 0; i < nhandles; i++) {
348*d83cc019SAndroid Build Coastguard Worker 				busy.handle = handles[indirection[i]];
349*d83cc019SAndroid Build Coastguard Worker 				/* Check that the busy computation doesn't
350*d83cc019SAndroid Build Coastguard Worker 				 * explode in the face of random gem_close().
351*d83cc019SAndroid Build Coastguard Worker 				 */
352*d83cc019SAndroid Build Coastguard Worker 				drmIoctl(fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
353*d83cc019SAndroid Build Coastguard Worker 			}
354*d83cc019SAndroid Build Coastguard Worker 			count++;
355*d83cc019SAndroid Build Coastguard Worker 		} while(*(volatile long *)control == 0);
356*d83cc019SAndroid Build Coastguard Worker 
357*d83cc019SAndroid Build Coastguard Worker 		igt_debug("child[%d]: count = %lu\n", child, count);
358*d83cc019SAndroid Build Coastguard Worker 		control[child + 1] = count;
359*d83cc019SAndroid Build Coastguard Worker 	}
360*d83cc019SAndroid Build Coastguard Worker 
361*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
362*d83cc019SAndroid Build Coastguard Worker 		struct sched_param rt = {.sched_priority = 99 };
363*d83cc019SAndroid Build Coastguard Worker 		igt_spin_t *spin[nhandles];
364*d83cc019SAndroid Build Coastguard Worker 		unsigned long count = 0;
365*d83cc019SAndroid Build Coastguard Worker 
366*d83cc019SAndroid Build Coastguard Worker 		igt_assert(sched_setscheduler(getpid(), SCHED_RR, &rt) == 0);
367*d83cc019SAndroid Build Coastguard Worker 
368*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < nhandles; i++) {
369*d83cc019SAndroid Build Coastguard Worker 			spin[i] = __igt_spin_new(fd,
370*d83cc019SAndroid Build Coastguard Worker 						 .engine = engines[rand() % nengine]);
371*d83cc019SAndroid Build Coastguard Worker 			handles[i] = spin[i]->handle;
372*d83cc019SAndroid Build Coastguard Worker 		}
373*d83cc019SAndroid Build Coastguard Worker 
374*d83cc019SAndroid Build Coastguard Worker 		igt_until_timeout(20) {
375*d83cc019SAndroid Build Coastguard Worker 			for (i = 0; i < nhandles; i++) {
376*d83cc019SAndroid Build Coastguard Worker 				igt_spin_free(fd, spin[i]);
377*d83cc019SAndroid Build Coastguard Worker 				spin[i] = __igt_spin_new(fd,
378*d83cc019SAndroid Build Coastguard Worker 							 .engine = engines[rand() % nengine]);
379*d83cc019SAndroid Build Coastguard Worker 				handles[i] = spin[i]->handle;
380*d83cc019SAndroid Build Coastguard Worker 				__sync_synchronize();
381*d83cc019SAndroid Build Coastguard Worker 			}
382*d83cc019SAndroid Build Coastguard Worker 			count += nhandles;
383*d83cc019SAndroid Build Coastguard Worker 		}
384*d83cc019SAndroid Build Coastguard Worker 		control[0] = count;
385*d83cc019SAndroid Build Coastguard Worker 		__sync_synchronize();
386*d83cc019SAndroid Build Coastguard Worker 
387*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < nhandles; i++)
388*d83cc019SAndroid Build Coastguard Worker 			igt_spin_free(fd, spin[i]);
389*d83cc019SAndroid Build Coastguard Worker 	}
390*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
391*d83cc019SAndroid Build Coastguard Worker 
392*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ncpus - 1; i++)
393*d83cc019SAndroid Build Coastguard Worker 		control[ncpus] += control[i + 1];
394*d83cc019SAndroid Build Coastguard Worker 	igt_info("Total execs %lu, busy-ioctls %lu\n",
395*d83cc019SAndroid Build Coastguard Worker 		 control[0], control[ncpus] * nhandles);
396*d83cc019SAndroid Build Coastguard Worker 
397*d83cc019SAndroid Build Coastguard Worker 	munmap(handles, PAGE_ALIGN(nhandles * sizeof(*handles)));
398*d83cc019SAndroid Build Coastguard Worker 	munmap(control, 4096);
399*d83cc019SAndroid Build Coastguard Worker 
400*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(fd);
401*d83cc019SAndroid Build Coastguard Worker }
402*d83cc019SAndroid Build Coastguard Worker 
has_semaphores(int fd)403*d83cc019SAndroid Build Coastguard Worker static bool has_semaphores(int fd)
404*d83cc019SAndroid Build Coastguard Worker {
405*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_getparam gp;
406*d83cc019SAndroid Build Coastguard Worker 	int val = -1;
407*d83cc019SAndroid Build Coastguard Worker 
408*d83cc019SAndroid Build Coastguard Worker 	memset(&gp, 0, sizeof(gp));
409*d83cc019SAndroid Build Coastguard Worker 	gp.param = I915_PARAM_HAS_SEMAPHORES;
410*d83cc019SAndroid Build Coastguard Worker 	gp.value = &val;
411*d83cc019SAndroid Build Coastguard Worker 
412*d83cc019SAndroid Build Coastguard Worker 	drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
413*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
414*d83cc019SAndroid Build Coastguard Worker 
415*d83cc019SAndroid Build Coastguard Worker 	return val > 0;
416*d83cc019SAndroid Build Coastguard Worker }
417*d83cc019SAndroid Build Coastguard Worker 
has_extended_busy_ioctl(int fd)418*d83cc019SAndroid Build Coastguard Worker static bool has_extended_busy_ioctl(int fd)
419*d83cc019SAndroid Build Coastguard Worker {
420*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = igt_spin_new(fd, .engine = I915_EXEC_DEFAULT);
421*d83cc019SAndroid Build Coastguard Worker 	uint32_t read, write;
422*d83cc019SAndroid Build Coastguard Worker 
423*d83cc019SAndroid Build Coastguard Worker 	__gem_busy(fd, spin->handle, &read, &write);
424*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
425*d83cc019SAndroid Build Coastguard Worker 
426*d83cc019SAndroid Build Coastguard Worker 	return read != 0;
427*d83cc019SAndroid Build Coastguard Worker }
428*d83cc019SAndroid Build Coastguard Worker 
basic(int fd,const struct intel_execution_engine2 * e,unsigned flags)429*d83cc019SAndroid Build Coastguard Worker static void basic(int fd, const struct intel_execution_engine2 *e, unsigned flags)
430*d83cc019SAndroid Build Coastguard Worker {
431*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin =
432*d83cc019SAndroid Build Coastguard Worker 		igt_spin_new(fd,
433*d83cc019SAndroid Build Coastguard Worker 			     .engine = e->flags,
434*d83cc019SAndroid Build Coastguard Worker 			     .flags = IGT_SPIN_NO_PREEMPTION);
435*d83cc019SAndroid Build Coastguard Worker 	struct timespec tv;
436*d83cc019SAndroid Build Coastguard Worker 	int timeout;
437*d83cc019SAndroid Build Coastguard Worker 	bool busy;
438*d83cc019SAndroid Build Coastguard Worker 
439*d83cc019SAndroid Build Coastguard Worker 	busy = gem_bo_busy(fd, spin->handle);
440*d83cc019SAndroid Build Coastguard Worker 
441*d83cc019SAndroid Build Coastguard Worker 	timeout = 120;
442*d83cc019SAndroid Build Coastguard Worker 	if ((flags & HANG) == 0) {
443*d83cc019SAndroid Build Coastguard Worker 		igt_spin_end(spin);
444*d83cc019SAndroid Build Coastguard Worker 		timeout = 1;
445*d83cc019SAndroid Build Coastguard Worker 	}
446*d83cc019SAndroid Build Coastguard Worker 
447*d83cc019SAndroid Build Coastguard Worker 	igt_assert(busy);
448*d83cc019SAndroid Build Coastguard Worker 	memset(&tv, 0, sizeof(tv));
449*d83cc019SAndroid Build Coastguard Worker 	while (gem_bo_busy(fd, spin->handle)) {
450*d83cc019SAndroid Build Coastguard Worker 		if (igt_seconds_elapsed(&tv) > timeout) {
451*d83cc019SAndroid Build Coastguard Worker 			igt_debugfs_dump(fd, "i915_engine_info");
452*d83cc019SAndroid Build Coastguard Worker 			igt_debugfs_dump(fd, "i915_hangcheck_info");
453*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(igt_seconds_elapsed(&tv) < timeout,
454*d83cc019SAndroid Build Coastguard Worker 				     "%s batch did not complete within %ds\n",
455*d83cc019SAndroid Build Coastguard Worker 				     flags & HANG ? "Hanging" : "Normal",
456*d83cc019SAndroid Build Coastguard Worker 				     timeout);
457*d83cc019SAndroid Build Coastguard Worker 		}
458*d83cc019SAndroid Build Coastguard Worker 	}
459*d83cc019SAndroid Build Coastguard Worker 
460*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, spin);
461*d83cc019SAndroid Build Coastguard Worker }
462*d83cc019SAndroid Build Coastguard Worker 
all(int i915)463*d83cc019SAndroid Build Coastguard Worker static void all(int i915)
464*d83cc019SAndroid Build Coastguard Worker {
465*d83cc019SAndroid Build Coastguard Worker 	const struct intel_execution_engine2 *e;
466*d83cc019SAndroid Build Coastguard Worker 
467*d83cc019SAndroid Build Coastguard Worker 	__for_each_physical_engine(i915, e)
468*d83cc019SAndroid Build Coastguard Worker 		basic(i915, e, 0);
469*d83cc019SAndroid Build Coastguard Worker }
470*d83cc019SAndroid Build Coastguard Worker 
471*d83cc019SAndroid Build Coastguard Worker igt_main
472*d83cc019SAndroid Build Coastguard Worker {
473*d83cc019SAndroid Build Coastguard Worker 	const struct intel_execution_engine2 *e;
474*d83cc019SAndroid Build Coastguard Worker 	int fd = -1;
475*d83cc019SAndroid Build Coastguard Worker 
476*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
477*d83cc019SAndroid Build Coastguard Worker 		fd = drm_open_driver_master(DRIVER_INTEL);
478*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(fd);
479*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_class_can_store_dword(fd,
480*d83cc019SAndroid Build Coastguard Worker 						     I915_ENGINE_CLASS_RENDER));
481*d83cc019SAndroid Build Coastguard Worker 	}
482*d83cc019SAndroid Build Coastguard Worker 
483*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group {
484*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
485*d83cc019SAndroid Build Coastguard Worker 			igt_fork_hang_detector(fd);
486*d83cc019SAndroid Build Coastguard Worker 		}
487*d83cc019SAndroid Build Coastguard Worker 
488*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("busy-all") {
489*d83cc019SAndroid Build Coastguard Worker 			gem_quiescent_gpu(fd);
490*d83cc019SAndroid Build Coastguard Worker 			all(fd);
491*d83cc019SAndroid Build Coastguard Worker 		}
492*d83cc019SAndroid Build Coastguard Worker 
__for_each_physical_engine(fd,e)493*d83cc019SAndroid Build Coastguard Worker 		__for_each_physical_engine(fd, e) {
494*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
495*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("busy-%s", e->name) {
496*d83cc019SAndroid Build Coastguard Worker 					gem_quiescent_gpu(fd);
497*d83cc019SAndroid Build Coastguard Worker 					basic(fd, e, 0);
498*d83cc019SAndroid Build Coastguard Worker 				}
499*d83cc019SAndroid Build Coastguard Worker 			}
500*d83cc019SAndroid Build Coastguard Worker 		}
501*d83cc019SAndroid Build Coastguard Worker 
502*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_group {
503*d83cc019SAndroid Build Coastguard Worker 			igt_fixture {
504*d83cc019SAndroid Build Coastguard Worker 				igt_require(has_extended_busy_ioctl(fd));
505*d83cc019SAndroid Build Coastguard Worker 				gem_require_mmap_wc(fd);
506*d83cc019SAndroid Build Coastguard Worker 			}
507*d83cc019SAndroid Build Coastguard Worker 
__for_each_physical_engine(fd,e)508*d83cc019SAndroid Build Coastguard Worker 			__for_each_physical_engine(fd, e) {
509*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("extended-%s", e->name) {
510*d83cc019SAndroid Build Coastguard Worker 					igt_require(gem_class_can_store_dword(fd,
511*d83cc019SAndroid Build Coastguard Worker 						     e->class));
512*d83cc019SAndroid Build Coastguard Worker 					gem_quiescent_gpu(fd);
513*d83cc019SAndroid Build Coastguard Worker 					one(fd, e, 0);
514*d83cc019SAndroid Build Coastguard Worker 					gem_quiescent_gpu(fd);
515*d83cc019SAndroid Build Coastguard Worker 				}
516*d83cc019SAndroid Build Coastguard Worker 			}
517*d83cc019SAndroid Build Coastguard Worker 
__for_each_physical_engine(fd,e)518*d83cc019SAndroid Build Coastguard Worker 			__for_each_physical_engine(fd, e) {
519*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("extended-parallel-%s", e->name) {
520*d83cc019SAndroid Build Coastguard Worker 					igt_require(gem_class_can_store_dword(fd, e->class));
521*d83cc019SAndroid Build Coastguard Worker 
522*d83cc019SAndroid Build Coastguard Worker 					gem_quiescent_gpu(fd);
523*d83cc019SAndroid Build Coastguard Worker 					one(fd, e, PARALLEL);
524*d83cc019SAndroid Build Coastguard Worker 					gem_quiescent_gpu(fd);
525*d83cc019SAndroid Build Coastguard Worker 				}
526*d83cc019SAndroid Build Coastguard Worker 			}
527*d83cc019SAndroid Build Coastguard Worker 		}
528*d83cc019SAndroid Build Coastguard Worker 
529*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_group {
530*d83cc019SAndroid Build Coastguard Worker 			igt_fixture {
531*d83cc019SAndroid Build Coastguard Worker 				igt_require(has_extended_busy_ioctl(fd));
532*d83cc019SAndroid Build Coastguard Worker 				igt_require(has_semaphores(fd));
533*d83cc019SAndroid Build Coastguard Worker 			}
534*d83cc019SAndroid Build Coastguard Worker 
__for_each_physical_engine(fd,e)535*d83cc019SAndroid Build Coastguard Worker 			__for_each_physical_engine(fd, e) {
536*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("extended-semaphore-%s", e->name)
537*d83cc019SAndroid Build Coastguard Worker 					semaphore(fd, e);
538*d83cc019SAndroid Build Coastguard Worker 			}
539*d83cc019SAndroid Build Coastguard Worker 		}
540*d83cc019SAndroid Build Coastguard Worker 
541*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("close-race")
542*d83cc019SAndroid Build Coastguard Worker 			close_race(fd);
543*d83cc019SAndroid Build Coastguard Worker 
544*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
545*d83cc019SAndroid Build Coastguard Worker 			igt_stop_hang_detector();
546*d83cc019SAndroid Build Coastguard Worker 		}
547*d83cc019SAndroid Build Coastguard Worker 	}
548*d83cc019SAndroid Build Coastguard Worker 
549*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group {
550*d83cc019SAndroid Build Coastguard Worker 		igt_hang_t hang;
551*d83cc019SAndroid Build Coastguard Worker 
552*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
553*d83cc019SAndroid Build Coastguard Worker 			hang = igt_allow_hang(fd, 0, 0);
554*d83cc019SAndroid Build Coastguard Worker 		}
555*d83cc019SAndroid Build Coastguard Worker 
__for_each_physical_engine(fd,e)556*d83cc019SAndroid Build Coastguard Worker 		__for_each_physical_engine(fd, e) {
557*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("%shang-%s",
558*d83cc019SAndroid Build Coastguard Worker 				      e->class == I915_ENGINE_CLASS_RENDER
559*d83cc019SAndroid Build Coastguard Worker 				      ? "basic-" : "", e->name) {
560*d83cc019SAndroid Build Coastguard Worker 				igt_skip_on_simulation();
561*d83cc019SAndroid Build Coastguard Worker 				gem_quiescent_gpu(fd);
562*d83cc019SAndroid Build Coastguard Worker 				basic(fd, e, HANG);
563*d83cc019SAndroid Build Coastguard Worker 			}
564*d83cc019SAndroid Build Coastguard Worker 		}
565*d83cc019SAndroid Build Coastguard Worker 
566*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_group {
567*d83cc019SAndroid Build Coastguard Worker 			igt_fixture {
568*d83cc019SAndroid Build Coastguard Worker 				igt_require(has_extended_busy_ioctl(fd));
569*d83cc019SAndroid Build Coastguard Worker 				gem_require_mmap_wc(fd);
570*d83cc019SAndroid Build Coastguard Worker 			}
571*d83cc019SAndroid Build Coastguard Worker 
__for_each_physical_engine(fd,e)572*d83cc019SAndroid Build Coastguard Worker 			__for_each_physical_engine(fd, e) {
573*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("extended-hang-%s", e->name) {
574*d83cc019SAndroid Build Coastguard Worker 					igt_skip_on_simulation();
575*d83cc019SAndroid Build Coastguard Worker 					igt_require(gem_class_can_store_dword(fd, e->class));
576*d83cc019SAndroid Build Coastguard Worker 
577*d83cc019SAndroid Build Coastguard Worker 					gem_quiescent_gpu(fd);
578*d83cc019SAndroid Build Coastguard Worker 					one(fd, e, HANG);
579*d83cc019SAndroid Build Coastguard Worker 					gem_quiescent_gpu(fd);
580*d83cc019SAndroid Build Coastguard Worker 				}
581*d83cc019SAndroid Build Coastguard Worker 			}
582*d83cc019SAndroid Build Coastguard Worker 		}
583*d83cc019SAndroid Build Coastguard Worker 
584*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
585*d83cc019SAndroid Build Coastguard Worker 			igt_disallow_hang(fd, hang);
586*d83cc019SAndroid Build Coastguard Worker 		}
587*d83cc019SAndroid Build Coastguard Worker 	}
588*d83cc019SAndroid Build Coastguard Worker 
589*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
590*d83cc019SAndroid Build Coastguard Worker 		close(fd);
591*d83cc019SAndroid Build Coastguard Worker 	}
592*d83cc019SAndroid Build Coastguard Worker }
593