xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_exec_whisper.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2009 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 
25*d83cc019SAndroid Build Coastguard Worker /** @file gem_exec_whisper.c
26*d83cc019SAndroid Build Coastguard Worker  *
27*d83cc019SAndroid Build Coastguard Worker  * Pass around a value to write into a scratch buffer between lots of batches
28*d83cc019SAndroid Build Coastguard Worker  */
29*d83cc019SAndroid Build Coastguard Worker 
30*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
31*d83cc019SAndroid Build Coastguard Worker #include "igt_debugfs.h"
32*d83cc019SAndroid Build Coastguard Worker #include "igt_gpu_power.h"
33*d83cc019SAndroid Build Coastguard Worker #include "igt_gt.h"
34*d83cc019SAndroid Build Coastguard Worker #include "igt_rand.h"
35*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
36*d83cc019SAndroid Build Coastguard Worker 
37*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_NO_RELOC (1<<11)
38*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
39*d83cc019SAndroid Build Coastguard Worker 
40*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_SHIFT      (13)
41*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_MASK       (3 << LOCAL_I915_EXEC_BSD_SHIFT)
42*d83cc019SAndroid Build Coastguard Worker 
43*d83cc019SAndroid Build Coastguard Worker #define ENGINE_MASK  (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker #define VERIFY 0
46*d83cc019SAndroid Build Coastguard Worker 
check_bo(int fd,uint32_t handle,int pass)47*d83cc019SAndroid Build Coastguard Worker static void check_bo(int fd, uint32_t handle, int pass)
48*d83cc019SAndroid Build Coastguard Worker {
49*d83cc019SAndroid Build Coastguard Worker 	uint32_t *map;
50*d83cc019SAndroid Build Coastguard Worker 
51*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Verifying result\n");
52*d83cc019SAndroid Build Coastguard Worker 	map = gem_mmap__cpu(fd, handle, 0, 4096, PROT_READ);
53*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
54*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < pass; i++)
55*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(map[i], i);
56*d83cc019SAndroid Build Coastguard Worker 	munmap(map, 4096);
57*d83cc019SAndroid Build Coastguard Worker }
58*d83cc019SAndroid Build Coastguard Worker 
verify_reloc(int fd,uint32_t handle,const struct drm_i915_gem_relocation_entry * reloc)59*d83cc019SAndroid Build Coastguard Worker static void verify_reloc(int fd, uint32_t handle,
60*d83cc019SAndroid Build Coastguard Worker 			 const struct drm_i915_gem_relocation_entry *reloc)
61*d83cc019SAndroid Build Coastguard Worker {
62*d83cc019SAndroid Build Coastguard Worker 	if (VERIFY) {
63*d83cc019SAndroid Build Coastguard Worker 		uint64_t target = 0;
64*d83cc019SAndroid Build Coastguard Worker 		if (intel_gen(intel_get_drm_devid(fd)) >= 8)
65*d83cc019SAndroid Build Coastguard Worker 			gem_read(fd, handle, reloc->offset, &target, 8);
66*d83cc019SAndroid Build Coastguard Worker 		else
67*d83cc019SAndroid Build Coastguard Worker 			gem_read(fd, handle, reloc->offset, &target, 4);
68*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u64(target,
69*d83cc019SAndroid Build Coastguard Worker 				  reloc->presumed_offset + reloc->delta);
70*d83cc019SAndroid Build Coastguard Worker 	}
71*d83cc019SAndroid Build Coastguard Worker }
72*d83cc019SAndroid Build Coastguard Worker 
73*d83cc019SAndroid Build Coastguard Worker #define CONTEXTS 0x1
74*d83cc019SAndroid Build Coastguard Worker #define FDS 0x2
75*d83cc019SAndroid Build Coastguard Worker #define INTERRUPTIBLE 0x4
76*d83cc019SAndroid Build Coastguard Worker #define CHAIN 0x8
77*d83cc019SAndroid Build Coastguard Worker #define FORKED 0x10
78*d83cc019SAndroid Build Coastguard Worker #define HANG 0x20
79*d83cc019SAndroid Build Coastguard Worker #define SYNC 0x40
80*d83cc019SAndroid Build Coastguard Worker #define PRIORITY 0x80
81*d83cc019SAndroid Build Coastguard Worker #define ALL 0x100
82*d83cc019SAndroid Build Coastguard Worker #define QUEUES 0x200
83*d83cc019SAndroid Build Coastguard Worker 
84*d83cc019SAndroid Build Coastguard Worker struct hang {
85*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj;
86*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc;
87*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
88*d83cc019SAndroid Build Coastguard Worker 	int fd;
89*d83cc019SAndroid Build Coastguard Worker };
90*d83cc019SAndroid Build Coastguard Worker 
init_hang(struct hang * h)91*d83cc019SAndroid Build Coastguard Worker static void init_hang(struct hang *h)
92*d83cc019SAndroid Build Coastguard Worker {
93*d83cc019SAndroid Build Coastguard Worker 	uint32_t *batch;
94*d83cc019SAndroid Build Coastguard Worker 	int i, gen;
95*d83cc019SAndroid Build Coastguard Worker 
96*d83cc019SAndroid Build Coastguard Worker 	h->fd = drm_open_driver(DRIVER_INTEL);
97*d83cc019SAndroid Build Coastguard Worker 	igt_allow_hang(h->fd, 0, 0);
98*d83cc019SAndroid Build Coastguard Worker 
99*d83cc019SAndroid Build Coastguard Worker 	gen = intel_gen(intel_get_drm_devid(h->fd));
100*d83cc019SAndroid Build Coastguard Worker 
101*d83cc019SAndroid Build Coastguard Worker 	memset(&h->execbuf, 0, sizeof(h->execbuf));
102*d83cc019SAndroid Build Coastguard Worker 	h->execbuf.buffers_ptr = to_user_pointer(&h->obj);
103*d83cc019SAndroid Build Coastguard Worker 	h->execbuf.buffer_count = 1;
104*d83cc019SAndroid Build Coastguard Worker 
105*d83cc019SAndroid Build Coastguard Worker 	memset(&h->obj, 0, sizeof(h->obj));
106*d83cc019SAndroid Build Coastguard Worker 	h->obj.handle = gem_create(h->fd, 4096);
107*d83cc019SAndroid Build Coastguard Worker 
108*d83cc019SAndroid Build Coastguard Worker 	h->obj.relocs_ptr = to_user_pointer(&h->reloc);
109*d83cc019SAndroid Build Coastguard Worker 	h->obj.relocation_count = 1;
110*d83cc019SAndroid Build Coastguard Worker 	memset(&h->reloc, 0, sizeof(h->reloc));
111*d83cc019SAndroid Build Coastguard Worker 
112*d83cc019SAndroid Build Coastguard Worker 	batch = gem_mmap__cpu(h->fd, h->obj.handle, 0, 4096, PROT_WRITE);
113*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(h->fd, h->obj.handle,
114*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker 	h->reloc.target_handle = h->obj.handle; /* recurse */
117*d83cc019SAndroid Build Coastguard Worker 	h->reloc.presumed_offset = 0;
118*d83cc019SAndroid Build Coastguard Worker 	h->reloc.offset = 5*sizeof(uint32_t);
119*d83cc019SAndroid Build Coastguard Worker 	h->reloc.delta = 0;
120*d83cc019SAndroid Build Coastguard Worker 	h->reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
121*d83cc019SAndroid Build Coastguard Worker 	h->reloc.write_domain = 0;
122*d83cc019SAndroid Build Coastguard Worker 
123*d83cc019SAndroid Build Coastguard Worker 	i = 0;
124*d83cc019SAndroid Build Coastguard Worker 	batch[i++] = 0xffffffff;
125*d83cc019SAndroid Build Coastguard Worker 	batch[i++] = 0xdeadbeef;
126*d83cc019SAndroid Build Coastguard Worker 	batch[i++] = 0xc00fee00;
127*d83cc019SAndroid Build Coastguard Worker 	batch[i++] = 0x00c00fee;
128*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_BATCH_BUFFER_START;
129*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
130*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8 | 1;
131*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
132*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
133*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 6) {
134*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 1 << 8;
135*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
136*d83cc019SAndroid Build Coastguard Worker 	} else {
137*d83cc019SAndroid Build Coastguard Worker 		batch[i] |= 2 << 6;
138*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
139*d83cc019SAndroid Build Coastguard Worker 		if (gen < 4) {
140*d83cc019SAndroid Build Coastguard Worker 			batch[i] |= 1;
141*d83cc019SAndroid Build Coastguard Worker 			h->reloc.delta = 1;
142*d83cc019SAndroid Build Coastguard Worker 		}
143*d83cc019SAndroid Build Coastguard Worker 	}
144*d83cc019SAndroid Build Coastguard Worker 	munmap(batch, 4096);
145*d83cc019SAndroid Build Coastguard Worker }
146*d83cc019SAndroid Build Coastguard Worker 
submit_hang(struct hang * h,unsigned * engines,int nengine,unsigned flags)147*d83cc019SAndroid Build Coastguard Worker static void submit_hang(struct hang *h, unsigned *engines, int nengine, unsigned flags)
148*d83cc019SAndroid Build Coastguard Worker {
149*d83cc019SAndroid Build Coastguard Worker 	while (nengine--) {
150*d83cc019SAndroid Build Coastguard Worker 		h->execbuf.flags &= ~ENGINE_MASK;
151*d83cc019SAndroid Build Coastguard Worker 		h->execbuf.flags |= *engines++;
152*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(h->fd, &h->execbuf);
153*d83cc019SAndroid Build Coastguard Worker 	}
154*d83cc019SAndroid Build Coastguard Worker 	if (flags & SYNC)
155*d83cc019SAndroid Build Coastguard Worker 		gem_sync(h->fd, h->obj.handle);
156*d83cc019SAndroid Build Coastguard Worker }
157*d83cc019SAndroid Build Coastguard Worker 
fini_hang(struct hang * h)158*d83cc019SAndroid Build Coastguard Worker static void fini_hang(struct hang *h)
159*d83cc019SAndroid Build Coastguard Worker {
160*d83cc019SAndroid Build Coastguard Worker 	close(h->fd);
161*d83cc019SAndroid Build Coastguard Worker }
162*d83cc019SAndroid Build Coastguard Worker 
ctx_set_random_priority(int fd,uint32_t ctx)163*d83cc019SAndroid Build Coastguard Worker static void ctx_set_random_priority(int fd, uint32_t ctx)
164*d83cc019SAndroid Build Coastguard Worker {
165*d83cc019SAndroid Build Coastguard Worker 	int prio = hars_petruska_f54_1_random_unsafe_max(1024) - 512;
166*d83cc019SAndroid Build Coastguard Worker 	gem_context_set_priority(fd, ctx, prio);
167*d83cc019SAndroid Build Coastguard Worker }
168*d83cc019SAndroid Build Coastguard Worker 
whisper(int fd,unsigned engine,unsigned flags)169*d83cc019SAndroid Build Coastguard Worker static void whisper(int fd, unsigned engine, unsigned flags)
170*d83cc019SAndroid Build Coastguard Worker {
171*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
172*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
173*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 batches[1024];
174*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry inter[1024];
175*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc;
176*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 store, scratch;
177*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 tmp[2];
178*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
179*d83cc019SAndroid Build Coastguard Worker 	struct hang hang;
180*d83cc019SAndroid Build Coastguard Worker 	int fds[64];
181*d83cc019SAndroid Build Coastguard Worker 	uint32_t contexts[64];
182*d83cc019SAndroid Build Coastguard Worker 	unsigned engines[16];
183*d83cc019SAndroid Build Coastguard Worker 	unsigned nengine;
184*d83cc019SAndroid Build Coastguard Worker 	uint32_t batch[16];
185*d83cc019SAndroid Build Coastguard Worker 	unsigned int relocations = 0;
186*d83cc019SAndroid Build Coastguard Worker 	unsigned int reloc_migrations = 0;
187*d83cc019SAndroid Build Coastguard Worker 	unsigned int reloc_interruptions = 0;
188*d83cc019SAndroid Build Coastguard Worker 	unsigned int eb_migrations = 0;
189*d83cc019SAndroid Build Coastguard Worker 	struct gpu_power_sample sample[2];
190*d83cc019SAndroid Build Coastguard Worker 	struct gpu_power power;
191*d83cc019SAndroid Build Coastguard Worker 	uint64_t old_offset;
192*d83cc019SAndroid Build Coastguard Worker 	int i, n, loc;
193*d83cc019SAndroid Build Coastguard Worker 	int debugfs;
194*d83cc019SAndroid Build Coastguard Worker 	int nchild;
195*d83cc019SAndroid Build Coastguard Worker 
196*d83cc019SAndroid Build Coastguard Worker 	if (flags & PRIORITY) {
197*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_scheduler_enabled(fd));
198*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_scheduler_has_ctx_priority(fd));
199*d83cc019SAndroid Build Coastguard Worker 	}
200*d83cc019SAndroid Build Coastguard Worker 
201*d83cc019SAndroid Build Coastguard Worker 	debugfs = igt_debugfs_dir(fd);
202*d83cc019SAndroid Build Coastguard Worker 	gpu_power_open(&power);
203*d83cc019SAndroid Build Coastguard Worker 
204*d83cc019SAndroid Build Coastguard Worker 	nengine = 0;
205*d83cc019SAndroid Build Coastguard Worker 	if (engine == ALL_ENGINES) {
206*d83cc019SAndroid Build Coastguard Worker 		for_each_physical_engine(fd, engine) {
207*d83cc019SAndroid Build Coastguard Worker 			if (gem_can_store_dword(fd, engine))
208*d83cc019SAndroid Build Coastguard Worker 				engines[nengine++] = engine;
209*d83cc019SAndroid Build Coastguard Worker 		}
210*d83cc019SAndroid Build Coastguard Worker 	} else {
211*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!(flags & ALL));
212*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_has_ring(fd, engine));
213*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(fd, engine));
214*d83cc019SAndroid Build Coastguard Worker 		engines[nengine++] = engine;
215*d83cc019SAndroid Build Coastguard Worker 	}
216*d83cc019SAndroid Build Coastguard Worker 	igt_require(nengine);
217*d83cc019SAndroid Build Coastguard Worker 
218*d83cc019SAndroid Build Coastguard Worker 	if (flags & FDS)
219*d83cc019SAndroid Build Coastguard Worker 		igt_require(gen >= 6);
220*d83cc019SAndroid Build Coastguard Worker 
221*d83cc019SAndroid Build Coastguard Worker 	if (flags & CONTEXTS)
222*d83cc019SAndroid Build Coastguard Worker 		gem_require_contexts(fd);
223*d83cc019SAndroid Build Coastguard Worker 
224*d83cc019SAndroid Build Coastguard Worker 	if (flags & QUEUES)
225*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_has_queues(fd));
226*d83cc019SAndroid Build Coastguard Worker 
227*d83cc019SAndroid Build Coastguard Worker 	if (flags & HANG)
228*d83cc019SAndroid Build Coastguard Worker 		init_hang(&hang);
229*d83cc019SAndroid Build Coastguard Worker 
230*d83cc019SAndroid Build Coastguard Worker 	nchild = 1;
231*d83cc019SAndroid Build Coastguard Worker 	if (flags & FORKED)
232*d83cc019SAndroid Build Coastguard Worker 		nchild *= sysconf(_SC_NPROCESSORS_ONLN);
233*d83cc019SAndroid Build Coastguard Worker 	if (flags & ALL)
234*d83cc019SAndroid Build Coastguard Worker 		nchild *= nengine;
235*d83cc019SAndroid Build Coastguard Worker 
236*d83cc019SAndroid Build Coastguard Worker 	intel_detect_and_clear_missed_interrupts(fd);
237*d83cc019SAndroid Build Coastguard Worker 	gpu_power_read(&power, &sample[0]);
238*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, nchild) {
239*d83cc019SAndroid Build Coastguard Worker 		unsigned int pass;
240*d83cc019SAndroid Build Coastguard Worker 
241*d83cc019SAndroid Build Coastguard Worker 		if (flags & ALL) {
242*d83cc019SAndroid Build Coastguard Worker 			engines[0] = engines[child % nengine];
243*d83cc019SAndroid Build Coastguard Worker 			nengine = 1;
244*d83cc019SAndroid Build Coastguard Worker 		}
245*d83cc019SAndroid Build Coastguard Worker 
246*d83cc019SAndroid Build Coastguard Worker 		memset(&scratch, 0, sizeof(scratch));
247*d83cc019SAndroid Build Coastguard Worker 		scratch.handle = gem_create(fd, 4096);
248*d83cc019SAndroid Build Coastguard Worker 		scratch.flags = EXEC_OBJECT_WRITE;
249*d83cc019SAndroid Build Coastguard Worker 
250*d83cc019SAndroid Build Coastguard Worker 		memset(&store, 0, sizeof(store));
251*d83cc019SAndroid Build Coastguard Worker 		store.handle = gem_create(fd, 4096);
252*d83cc019SAndroid Build Coastguard Worker 		store.relocs_ptr = to_user_pointer(&reloc);
253*d83cc019SAndroid Build Coastguard Worker 		store.relocation_count = 1;
254*d83cc019SAndroid Build Coastguard Worker 
255*d83cc019SAndroid Build Coastguard Worker 		memset(&reloc, 0, sizeof(reloc));
256*d83cc019SAndroid Build Coastguard Worker 		reloc.offset = sizeof(uint32_t);
257*d83cc019SAndroid Build Coastguard Worker 		if (gen < 8 && gen >= 4)
258*d83cc019SAndroid Build Coastguard Worker 			reloc.offset += sizeof(uint32_t);
259*d83cc019SAndroid Build Coastguard Worker 		loc = 8;
260*d83cc019SAndroid Build Coastguard Worker 		if (gen >= 4)
261*d83cc019SAndroid Build Coastguard Worker 			loc += 4;
262*d83cc019SAndroid Build Coastguard Worker 		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
263*d83cc019SAndroid Build Coastguard Worker 		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
264*d83cc019SAndroid Build Coastguard Worker 
265*d83cc019SAndroid Build Coastguard Worker 		{
266*d83cc019SAndroid Build Coastguard Worker 			tmp[0] = scratch;
267*d83cc019SAndroid Build Coastguard Worker 			tmp[1] = store;
268*d83cc019SAndroid Build Coastguard Worker 			gem_write(fd, store.handle, 0, &bbe, sizeof(bbe));
269*d83cc019SAndroid Build Coastguard Worker 
270*d83cc019SAndroid Build Coastguard Worker 			memset(&execbuf, 0, sizeof(execbuf));
271*d83cc019SAndroid Build Coastguard Worker 			execbuf.buffers_ptr = to_user_pointer(tmp);
272*d83cc019SAndroid Build Coastguard Worker 			execbuf.buffer_count = 2;
273*d83cc019SAndroid Build Coastguard Worker 			execbuf.flags = LOCAL_I915_EXEC_HANDLE_LUT;
274*d83cc019SAndroid Build Coastguard Worker 			execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
275*d83cc019SAndroid Build Coastguard Worker 			if (gen < 6)
276*d83cc019SAndroid Build Coastguard Worker 				execbuf.flags |= I915_EXEC_SECURE;
277*d83cc019SAndroid Build Coastguard Worker 			igt_require(__gem_execbuf(fd, &execbuf) == 0);
278*d83cc019SAndroid Build Coastguard Worker 			scratch = tmp[0];
279*d83cc019SAndroid Build Coastguard Worker 			store = tmp[1];
280*d83cc019SAndroid Build Coastguard Worker 		}
281*d83cc019SAndroid Build Coastguard Worker 
282*d83cc019SAndroid Build Coastguard Worker 		i = 0;
283*d83cc019SAndroid Build Coastguard Worker 		batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
284*d83cc019SAndroid Build Coastguard Worker 		if (gen >= 8) {
285*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = store.offset + loc;
286*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = (store.offset + loc) >> 32;
287*d83cc019SAndroid Build Coastguard Worker 		} else if (gen >= 4) {
288*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = 0;
289*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = store.offset + loc;
290*d83cc019SAndroid Build Coastguard Worker 		} else {
291*d83cc019SAndroid Build Coastguard Worker 			batch[i]--;
292*d83cc019SAndroid Build Coastguard Worker 			batch[++i] = store.offset + loc;
293*d83cc019SAndroid Build Coastguard Worker 		}
294*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0xc0ffee;
295*d83cc019SAndroid Build Coastguard Worker 		igt_assert(loc == sizeof(uint32_t) * i);
296*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = MI_BATCH_BUFFER_END;
297*d83cc019SAndroid Build Coastguard Worker 
298*d83cc019SAndroid Build Coastguard Worker 		if (flags & CONTEXTS) {
299*d83cc019SAndroid Build Coastguard Worker 			for (n = 0; n < 64; n++)
300*d83cc019SAndroid Build Coastguard Worker 				contexts[n] = gem_context_create(fd);
301*d83cc019SAndroid Build Coastguard Worker 		}
302*d83cc019SAndroid Build Coastguard Worker 		if (flags & QUEUES) {
303*d83cc019SAndroid Build Coastguard Worker 			for (n = 0; n < 64; n++)
304*d83cc019SAndroid Build Coastguard Worker 				contexts[n] = gem_queue_create(fd);
305*d83cc019SAndroid Build Coastguard Worker 		}
306*d83cc019SAndroid Build Coastguard Worker 		if (flags & FDS) {
307*d83cc019SAndroid Build Coastguard Worker 			for (n = 0; n < 64; n++)
308*d83cc019SAndroid Build Coastguard Worker 				fds[n] = drm_open_driver(DRIVER_INTEL);
309*d83cc019SAndroid Build Coastguard Worker 		}
310*d83cc019SAndroid Build Coastguard Worker 
311*d83cc019SAndroid Build Coastguard Worker 		memset(batches, 0, sizeof(batches));
312*d83cc019SAndroid Build Coastguard Worker 		for (n = 0; n < 1024; n++) {
313*d83cc019SAndroid Build Coastguard Worker 			batches[n].handle = gem_create(fd, 4096);
314*d83cc019SAndroid Build Coastguard Worker 			gem_write(fd, batches[n].handle, 0, &bbe, sizeof(bbe));
315*d83cc019SAndroid Build Coastguard Worker 		}
316*d83cc019SAndroid Build Coastguard Worker 		execbuf.buffers_ptr = to_user_pointer(batches);
317*d83cc019SAndroid Build Coastguard Worker 		execbuf.buffer_count = 1024;
318*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(fd, &execbuf);
319*d83cc019SAndroid Build Coastguard Worker 
320*d83cc019SAndroid Build Coastguard Worker 		execbuf.buffers_ptr = to_user_pointer(tmp);
321*d83cc019SAndroid Build Coastguard Worker 		execbuf.buffer_count = 2;
322*d83cc019SAndroid Build Coastguard Worker 
323*d83cc019SAndroid Build Coastguard Worker 		old_offset = store.offset;
324*d83cc019SAndroid Build Coastguard Worker 		for (n = 0; n < 1024; n++) {
325*d83cc019SAndroid Build Coastguard Worker 			if (gen >= 8) {
326*d83cc019SAndroid Build Coastguard Worker 				batch[1] = old_offset + loc;
327*d83cc019SAndroid Build Coastguard Worker 				batch[2] = (old_offset + loc) >> 32;
328*d83cc019SAndroid Build Coastguard Worker 			} else if (gen >= 4) {
329*d83cc019SAndroid Build Coastguard Worker 				batch[2] = old_offset + loc;
330*d83cc019SAndroid Build Coastguard Worker 			} else {
331*d83cc019SAndroid Build Coastguard Worker 				batch[1] = old_offset + loc;
332*d83cc019SAndroid Build Coastguard Worker 			}
333*d83cc019SAndroid Build Coastguard Worker 
334*d83cc019SAndroid Build Coastguard Worker 			inter[n] = reloc;
335*d83cc019SAndroid Build Coastguard Worker 			inter[n].presumed_offset = old_offset;
336*d83cc019SAndroid Build Coastguard Worker 			inter[n].delta = loc;
337*d83cc019SAndroid Build Coastguard Worker 			batches[n].relocs_ptr = to_user_pointer(&inter[n]);
338*d83cc019SAndroid Build Coastguard Worker 			batches[n].relocation_count = 1;
339*d83cc019SAndroid Build Coastguard Worker 			gem_write(fd, batches[n].handle, 0, batch, sizeof(batch));
340*d83cc019SAndroid Build Coastguard Worker 
341*d83cc019SAndroid Build Coastguard Worker 			old_offset = batches[n].offset;
342*d83cc019SAndroid Build Coastguard Worker 		}
343*d83cc019SAndroid Build Coastguard Worker 
344*d83cc019SAndroid Build Coastguard Worker 		igt_while_interruptible(flags & INTERRUPTIBLE) {
345*d83cc019SAndroid Build Coastguard Worker 			pass = 0;
346*d83cc019SAndroid Build Coastguard Worker 			igt_until_timeout(150) {
347*d83cc019SAndroid Build Coastguard Worker 				uint64_t offset;
348*d83cc019SAndroid Build Coastguard Worker 
349*d83cc019SAndroid Build Coastguard Worker 				if (flags & HANG)
350*d83cc019SAndroid Build Coastguard Worker 					submit_hang(&hang, engines, nengine, flags);
351*d83cc019SAndroid Build Coastguard Worker 
352*d83cc019SAndroid Build Coastguard Worker 				if (flags & CHAIN) {
353*d83cc019SAndroid Build Coastguard Worker 					execbuf.flags &= ~ENGINE_MASK;
354*d83cc019SAndroid Build Coastguard Worker 					execbuf.flags |= engines[rand() % nengine];
355*d83cc019SAndroid Build Coastguard Worker 				}
356*d83cc019SAndroid Build Coastguard Worker 
357*d83cc019SAndroid Build Coastguard Worker 				reloc.presumed_offset = scratch.offset;
358*d83cc019SAndroid Build Coastguard Worker 				reloc.delta = 4*pass;
359*d83cc019SAndroid Build Coastguard Worker 				offset = reloc.presumed_offset + reloc.delta;
360*d83cc019SAndroid Build Coastguard Worker 
361*d83cc019SAndroid Build Coastguard Worker 				i = 0;
362*d83cc019SAndroid Build Coastguard Worker 				if (gen >= 8) {
363*d83cc019SAndroid Build Coastguard Worker 					batch[++i] = offset;
364*d83cc019SAndroid Build Coastguard Worker 					batch[++i] = offset >> 32;
365*d83cc019SAndroid Build Coastguard Worker 				} else if (gen >= 4) {
366*d83cc019SAndroid Build Coastguard Worker 					batch[++i] = 0;
367*d83cc019SAndroid Build Coastguard Worker 					batch[++i] = offset;
368*d83cc019SAndroid Build Coastguard Worker 				} else {
369*d83cc019SAndroid Build Coastguard Worker 					batch[++i] = offset;
370*d83cc019SAndroid Build Coastguard Worker 				}
371*d83cc019SAndroid Build Coastguard Worker 				batch[++i] = ~pass;
372*d83cc019SAndroid Build Coastguard Worker 				gem_write(fd, store.handle, 0, batch, sizeof(batch));
373*d83cc019SAndroid Build Coastguard Worker 
374*d83cc019SAndroid Build Coastguard Worker 				tmp[0] = scratch;
375*d83cc019SAndroid Build Coastguard Worker 				igt_assert(tmp[0].flags & EXEC_OBJECT_WRITE);
376*d83cc019SAndroid Build Coastguard Worker 				tmp[1] = store;
377*d83cc019SAndroid Build Coastguard Worker 				verify_reloc(fd, store.handle, &reloc);
378*d83cc019SAndroid Build Coastguard Worker 				execbuf.buffers_ptr = to_user_pointer(tmp);
379*d83cc019SAndroid Build Coastguard Worker 				gem_execbuf(fd, &execbuf);
380*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq_u64(reloc.presumed_offset, tmp[0].offset);
381*d83cc019SAndroid Build Coastguard Worker 				if (flags & SYNC)
382*d83cc019SAndroid Build Coastguard Worker 					gem_sync(fd, tmp[0].handle);
383*d83cc019SAndroid Build Coastguard Worker 				scratch = tmp[0];
384*d83cc019SAndroid Build Coastguard Worker 
385*d83cc019SAndroid Build Coastguard Worker 				gem_write(fd, batches[1023].handle, loc, &pass, sizeof(pass));
386*d83cc019SAndroid Build Coastguard Worker 				for (n = 1024; --n >= 1; ) {
387*d83cc019SAndroid Build Coastguard Worker 					uint32_t handle[2] = {};
388*d83cc019SAndroid Build Coastguard Worker 					int this_fd = fd;
389*d83cc019SAndroid Build Coastguard Worker 
390*d83cc019SAndroid Build Coastguard Worker 					execbuf.buffers_ptr = to_user_pointer(&batches[n-1]);
391*d83cc019SAndroid Build Coastguard Worker 					reloc_migrations += batches[n-1].offset != inter[n].presumed_offset;
392*d83cc019SAndroid Build Coastguard Worker 					batches[n-1].offset = inter[n].presumed_offset;
393*d83cc019SAndroid Build Coastguard Worker 					old_offset = inter[n].presumed_offset;
394*d83cc019SAndroid Build Coastguard Worker 					batches[n-1].relocation_count = 0;
395*d83cc019SAndroid Build Coastguard Worker 					batches[n-1].flags |= EXEC_OBJECT_WRITE;
396*d83cc019SAndroid Build Coastguard Worker 					verify_reloc(fd, batches[n].handle, &inter[n]);
397*d83cc019SAndroid Build Coastguard Worker 
398*d83cc019SAndroid Build Coastguard Worker 					if (flags & FDS) {
399*d83cc019SAndroid Build Coastguard Worker 						this_fd = fds[rand() % 64];
400*d83cc019SAndroid Build Coastguard Worker 						handle[0] = batches[n-1].handle;
401*d83cc019SAndroid Build Coastguard Worker 						handle[1] = batches[n].handle;
402*d83cc019SAndroid Build Coastguard Worker 						batches[n-1].handle =
403*d83cc019SAndroid Build Coastguard Worker 							gem_open(this_fd,
404*d83cc019SAndroid Build Coastguard Worker 								 gem_flink(fd, handle[0]));
405*d83cc019SAndroid Build Coastguard Worker 						batches[n].handle =
406*d83cc019SAndroid Build Coastguard Worker 							gem_open(this_fd,
407*d83cc019SAndroid Build Coastguard Worker 								 gem_flink(fd, handle[1]));
408*d83cc019SAndroid Build Coastguard Worker 						if (flags & PRIORITY)
409*d83cc019SAndroid Build Coastguard Worker 							ctx_set_random_priority(this_fd, 0);
410*d83cc019SAndroid Build Coastguard Worker 					}
411*d83cc019SAndroid Build Coastguard Worker 
412*d83cc019SAndroid Build Coastguard Worker 					if (!(flags & CHAIN)) {
413*d83cc019SAndroid Build Coastguard Worker 						execbuf.flags &= ~ENGINE_MASK;
414*d83cc019SAndroid Build Coastguard Worker 						execbuf.flags |= engines[rand() % nengine];
415*d83cc019SAndroid Build Coastguard Worker 					}
416*d83cc019SAndroid Build Coastguard Worker 					if (flags & (CONTEXTS | QUEUES)) {
417*d83cc019SAndroid Build Coastguard Worker 						execbuf.rsvd1 = contexts[rand() % 64];
418*d83cc019SAndroid Build Coastguard Worker 						if (flags & PRIORITY)
419*d83cc019SAndroid Build Coastguard Worker 							ctx_set_random_priority(this_fd, execbuf.rsvd1);
420*d83cc019SAndroid Build Coastguard Worker 					}
421*d83cc019SAndroid Build Coastguard Worker 
422*d83cc019SAndroid Build Coastguard Worker 					gem_execbuf(this_fd, &execbuf);
423*d83cc019SAndroid Build Coastguard Worker 					if (inter[n].presumed_offset == -1) {
424*d83cc019SAndroid Build Coastguard Worker 						reloc_interruptions++;
425*d83cc019SAndroid Build Coastguard Worker 						inter[n].presumed_offset = batches[n-1].offset;
426*d83cc019SAndroid Build Coastguard Worker 					}
427*d83cc019SAndroid Build Coastguard Worker 					igt_assert_eq_u64(inter[n].presumed_offset, batches[n-1].offset);
428*d83cc019SAndroid Build Coastguard Worker 
429*d83cc019SAndroid Build Coastguard Worker 					if (flags & SYNC)
430*d83cc019SAndroid Build Coastguard Worker 						gem_sync(this_fd, batches[n-1].handle);
431*d83cc019SAndroid Build Coastguard Worker 					relocations += inter[n].presumed_offset != old_offset;
432*d83cc019SAndroid Build Coastguard Worker 
433*d83cc019SAndroid Build Coastguard Worker 					batches[n-1].relocation_count = 1;
434*d83cc019SAndroid Build Coastguard Worker 					batches[n-1].flags &= ~EXEC_OBJECT_WRITE;
435*d83cc019SAndroid Build Coastguard Worker 
436*d83cc019SAndroid Build Coastguard Worker 					if (this_fd != fd) {
437*d83cc019SAndroid Build Coastguard Worker 						gem_close(this_fd, batches[n-1].handle);
438*d83cc019SAndroid Build Coastguard Worker 						batches[n-1].handle = handle[0];
439*d83cc019SAndroid Build Coastguard Worker 
440*d83cc019SAndroid Build Coastguard Worker 						gem_close(this_fd, batches[n].handle);
441*d83cc019SAndroid Build Coastguard Worker 						batches[n].handle = handle[1];
442*d83cc019SAndroid Build Coastguard Worker 					}
443*d83cc019SAndroid Build Coastguard Worker 				}
444*d83cc019SAndroid Build Coastguard Worker 				execbuf.flags &= ~ENGINE_MASK;
445*d83cc019SAndroid Build Coastguard Worker 				execbuf.rsvd1 = 0;
446*d83cc019SAndroid Build Coastguard Worker 				execbuf.buffers_ptr = to_user_pointer(&tmp);
447*d83cc019SAndroid Build Coastguard Worker 
448*d83cc019SAndroid Build Coastguard Worker 				tmp[0] = tmp[1];
449*d83cc019SAndroid Build Coastguard Worker 				tmp[0].relocation_count = 0;
450*d83cc019SAndroid Build Coastguard Worker 				tmp[0].flags = EXEC_OBJECT_WRITE;
451*d83cc019SAndroid Build Coastguard Worker 				reloc_migrations += tmp[0].offset != inter[0].presumed_offset;
452*d83cc019SAndroid Build Coastguard Worker 				tmp[0].offset = inter[0].presumed_offset;
453*d83cc019SAndroid Build Coastguard Worker 				old_offset = tmp[0].offset;
454*d83cc019SAndroid Build Coastguard Worker 				tmp[1] = batches[0];
455*d83cc019SAndroid Build Coastguard Worker 				verify_reloc(fd, batches[0].handle, &inter[0]);
456*d83cc019SAndroid Build Coastguard Worker 				gem_execbuf(fd, &execbuf);
457*d83cc019SAndroid Build Coastguard Worker 				if (inter[0].presumed_offset == -1) {
458*d83cc019SAndroid Build Coastguard Worker 					reloc_interruptions++;
459*d83cc019SAndroid Build Coastguard Worker 					inter[0].presumed_offset = tmp[0].offset;
460*d83cc019SAndroid Build Coastguard Worker 				}
461*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq_u64(inter[0].presumed_offset, tmp[0].offset);
462*d83cc019SAndroid Build Coastguard Worker 				relocations += inter[0].presumed_offset != old_offset;
463*d83cc019SAndroid Build Coastguard Worker 				batches[0] = tmp[1];
464*d83cc019SAndroid Build Coastguard Worker 
465*d83cc019SAndroid Build Coastguard Worker 				tmp[1] = tmp[0];
466*d83cc019SAndroid Build Coastguard Worker 				tmp[0] = scratch;
467*d83cc019SAndroid Build Coastguard Worker 				igt_assert(tmp[0].flags & EXEC_OBJECT_WRITE);
468*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq_u64(reloc.presumed_offset, tmp[0].offset);
469*d83cc019SAndroid Build Coastguard Worker 				igt_assert(tmp[1].relocs_ptr == to_user_pointer(&reloc));
470*d83cc019SAndroid Build Coastguard Worker 				tmp[1].relocation_count = 1;
471*d83cc019SAndroid Build Coastguard Worker 				tmp[1].flags &= ~EXEC_OBJECT_WRITE;
472*d83cc019SAndroid Build Coastguard Worker 				verify_reloc(fd, store.handle, &reloc);
473*d83cc019SAndroid Build Coastguard Worker 				gem_execbuf(fd, &execbuf);
474*d83cc019SAndroid Build Coastguard Worker 				eb_migrations += tmp[0].offset != scratch.offset;
475*d83cc019SAndroid Build Coastguard Worker 				eb_migrations += tmp[1].offset != store.offset;
476*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq_u64(reloc.presumed_offset, tmp[0].offset);
477*d83cc019SAndroid Build Coastguard Worker 				if (flags & SYNC)
478*d83cc019SAndroid Build Coastguard Worker 					gem_sync(fd, tmp[0].handle);
479*d83cc019SAndroid Build Coastguard Worker 
480*d83cc019SAndroid Build Coastguard Worker 				store = tmp[1];
481*d83cc019SAndroid Build Coastguard Worker 				scratch = tmp[0];
482*d83cc019SAndroid Build Coastguard Worker 
483*d83cc019SAndroid Build Coastguard Worker 				if (++pass == 1024)
484*d83cc019SAndroid Build Coastguard Worker 					break;
485*d83cc019SAndroid Build Coastguard Worker 			}
486*d83cc019SAndroid Build Coastguard Worker 			igt_debug("Completed %d/1024 passes\n", pass);
487*d83cc019SAndroid Build Coastguard Worker 		}
488*d83cc019SAndroid Build Coastguard Worker 		igt_info("Number of migrations for execbuf: %d\n", eb_migrations);
489*d83cc019SAndroid Build Coastguard Worker 		igt_info("Number of migrations for reloc: %d, interrupted %d, patched %d\n", reloc_migrations, reloc_interruptions, relocations);
490*d83cc019SAndroid Build Coastguard Worker 
491*d83cc019SAndroid Build Coastguard Worker 		check_bo(fd, scratch.handle, pass);
492*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, scratch.handle);
493*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, store.handle);
494*d83cc019SAndroid Build Coastguard Worker 
495*d83cc019SAndroid Build Coastguard Worker 		if (flags & FDS) {
496*d83cc019SAndroid Build Coastguard Worker 			for (n = 0; n < 64; n++)
497*d83cc019SAndroid Build Coastguard Worker 				close(fds[n]);
498*d83cc019SAndroid Build Coastguard Worker 		}
499*d83cc019SAndroid Build Coastguard Worker 		if (flags & (CONTEXTS | QUEUES)) {
500*d83cc019SAndroid Build Coastguard Worker 			for (n = 0; n < 64; n++)
501*d83cc019SAndroid Build Coastguard Worker 				gem_context_destroy(fd, contexts[n]);
502*d83cc019SAndroid Build Coastguard Worker 		}
503*d83cc019SAndroid Build Coastguard Worker 		for (n = 0; n < 1024; n++)
504*d83cc019SAndroid Build Coastguard Worker 			gem_close(fd, batches[n].handle);
505*d83cc019SAndroid Build Coastguard Worker 	}
506*d83cc019SAndroid Build Coastguard Worker 
507*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
508*d83cc019SAndroid Build Coastguard Worker 
509*d83cc019SAndroid Build Coastguard Worker 	if (flags & HANG)
510*d83cc019SAndroid Build Coastguard Worker 		fini_hang(&hang);
511*d83cc019SAndroid Build Coastguard Worker 	else
512*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
513*d83cc019SAndroid Build Coastguard Worker 	if (gpu_power_read(&power, &sample[1]))  {
514*d83cc019SAndroid Build Coastguard Worker 		igt_info("Total energy used: %.1fmJ\n",
515*d83cc019SAndroid Build Coastguard Worker 			 gpu_power_J(&power, &sample[0], &sample[1]) * 1e3);
516*d83cc019SAndroid Build Coastguard Worker 	}
517*d83cc019SAndroid Build Coastguard Worker 
518*d83cc019SAndroid Build Coastguard Worker 	close(debugfs);
519*d83cc019SAndroid Build Coastguard Worker }
520*d83cc019SAndroid Build Coastguard Worker 
521*d83cc019SAndroid Build Coastguard Worker igt_main
522*d83cc019SAndroid Build Coastguard Worker {
523*d83cc019SAndroid Build Coastguard Worker 	const struct mode {
524*d83cc019SAndroid Build Coastguard Worker 		const char *name;
525*d83cc019SAndroid Build Coastguard Worker 		unsigned flags;
526*d83cc019SAndroid Build Coastguard Worker 	} modes[] = {
527*d83cc019SAndroid Build Coastguard Worker 		{ "normal", 0 },
528*d83cc019SAndroid Build Coastguard Worker 		{ "interruptible", INTERRUPTIBLE },
529*d83cc019SAndroid Build Coastguard Worker 		{ "forked", FORKED },
530*d83cc019SAndroid Build Coastguard Worker 		{ "sync", SYNC },
531*d83cc019SAndroid Build Coastguard Worker 		{ "chain", CHAIN },
532*d83cc019SAndroid Build Coastguard Worker 		{ "chain-forked", CHAIN | FORKED },
533*d83cc019SAndroid Build Coastguard Worker 		{ "chain-interruptible", CHAIN | INTERRUPTIBLE },
534*d83cc019SAndroid Build Coastguard Worker 		{ "chain-sync", CHAIN | SYNC },
535*d83cc019SAndroid Build Coastguard Worker 		{ "fds", FDS },
536*d83cc019SAndroid Build Coastguard Worker 		{ "fds-interruptible", FDS | INTERRUPTIBLE},
537*d83cc019SAndroid Build Coastguard Worker 		{ "fds-forked", FDS | FORKED},
538*d83cc019SAndroid Build Coastguard Worker 		{ "fds-priority", FDS | FORKED | PRIORITY },
539*d83cc019SAndroid Build Coastguard Worker 		{ "fds-chain", FDS | CHAIN},
540*d83cc019SAndroid Build Coastguard Worker 		{ "fds-sync", FDS | SYNC},
541*d83cc019SAndroid Build Coastguard Worker 		{ "contexts", CONTEXTS },
542*d83cc019SAndroid Build Coastguard Worker 		{ "contexts-interruptible", CONTEXTS | INTERRUPTIBLE},
543*d83cc019SAndroid Build Coastguard Worker 		{ "contexts-forked", CONTEXTS | FORKED},
544*d83cc019SAndroid Build Coastguard Worker 		{ "contexts-priority", CONTEXTS | FORKED | PRIORITY },
545*d83cc019SAndroid Build Coastguard Worker 		{ "contexts-chain", CONTEXTS | CHAIN },
546*d83cc019SAndroid Build Coastguard Worker 		{ "contexts-sync", CONTEXTS | SYNC },
547*d83cc019SAndroid Build Coastguard Worker 		{ "queues", QUEUES },
548*d83cc019SAndroid Build Coastguard Worker 		{ "queues-interruptible", QUEUES | INTERRUPTIBLE},
549*d83cc019SAndroid Build Coastguard Worker 		{ "queues-forked", QUEUES | FORKED},
550*d83cc019SAndroid Build Coastguard Worker 		{ "queues-priority", QUEUES | FORKED | PRIORITY },
551*d83cc019SAndroid Build Coastguard Worker 		{ "queues-chain", QUEUES | CHAIN },
552*d83cc019SAndroid Build Coastguard Worker 		{ "queues-sync", QUEUES | SYNC },
553*d83cc019SAndroid Build Coastguard Worker 		{ NULL }
554*d83cc019SAndroid Build Coastguard Worker 	};
555*d83cc019SAndroid Build Coastguard Worker 	int fd = -1;
556*d83cc019SAndroid Build Coastguard Worker 
557*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
558*d83cc019SAndroid Build Coastguard Worker 		fd = drm_open_driver_master(DRIVER_INTEL);
559*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(fd);
560*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(fd, 0));
561*d83cc019SAndroid Build Coastguard Worker 		gem_submission_print_method(fd);
562*d83cc019SAndroid Build Coastguard Worker 
563*d83cc019SAndroid Build Coastguard Worker 		igt_fork_hang_detector(fd);
564*d83cc019SAndroid Build Coastguard Worker 	}
565*d83cc019SAndroid Build Coastguard Worker 
566*d83cc019SAndroid Build Coastguard Worker 	for (const struct mode *m = modes; m->name; m++) {
567*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%s", m->name)
568*d83cc019SAndroid Build Coastguard Worker 			whisper(fd, ALL_ENGINES, m->flags);
569*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%s-all", m->name)
570*d83cc019SAndroid Build Coastguard Worker 			whisper(fd, ALL_ENGINES, m->flags | ALL);
571*d83cc019SAndroid Build Coastguard Worker 	}
572*d83cc019SAndroid Build Coastguard Worker 
573*d83cc019SAndroid Build Coastguard Worker 	for (const struct intel_execution_engine *e = intel_execution_engines;
574*d83cc019SAndroid Build Coastguard Worker 	     e->name; e++) {
575*d83cc019SAndroid Build Coastguard Worker 		for (const struct mode *m = modes; m->name; m++) {
576*d83cc019SAndroid Build Coastguard Worker 			if (m->flags & CHAIN)
577*d83cc019SAndroid Build Coastguard Worker 				continue;
578*d83cc019SAndroid Build Coastguard Worker 
579*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("%s-%s", e->name, m->name)
580*d83cc019SAndroid Build Coastguard Worker 				whisper(fd, e->exec_id | e->flags, m->flags);
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_stop_hang_detector();
586*d83cc019SAndroid Build Coastguard Worker 	}
587*d83cc019SAndroid Build Coastguard Worker 
588*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group {
589*d83cc019SAndroid Build Coastguard Worker 		for (const struct mode *m = modes; m->name; m++) {
590*d83cc019SAndroid Build Coastguard Worker 			if (m->flags & INTERRUPTIBLE)
591*d83cc019SAndroid Build Coastguard Worker 				continue;
592*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("hang-%s", m->name)
593*d83cc019SAndroid Build Coastguard Worker 				whisper(fd, ALL_ENGINES, m->flags | HANG);
594*d83cc019SAndroid Build Coastguard Worker 		}
595*d83cc019SAndroid Build Coastguard Worker 	}
596*d83cc019SAndroid Build Coastguard Worker 
597*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
598*d83cc019SAndroid Build Coastguard Worker 		close(fd);
599*d83cc019SAndroid Build Coastguard Worker 	}
600*d83cc019SAndroid Build Coastguard Worker }
601