xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_ctx_shared.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2017-2019 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 #include "igt.h"
26*d83cc019SAndroid Build Coastguard Worker 
27*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
33*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
34*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
35*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
36*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
37*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
38*d83cc019SAndroid Build Coastguard Worker 
39*d83cc019SAndroid Build Coastguard Worker #include <drm.h>
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker #include "igt_rand.h"
42*d83cc019SAndroid Build Coastguard Worker #include "igt_vgem.h"
43*d83cc019SAndroid Build Coastguard Worker #include "sync_file.h"
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker #define LO 0
46*d83cc019SAndroid Build Coastguard Worker #define HI 1
47*d83cc019SAndroid Build Coastguard Worker #define NOISE 2
48*d83cc019SAndroid Build Coastguard Worker 
49*d83cc019SAndroid Build Coastguard Worker #define MAX_PRIO LOCAL_I915_CONTEXT_MAX_USER_PRIORITY
50*d83cc019SAndroid Build Coastguard Worker #define MIN_PRIO LOCAL_I915_CONTEXT_MIN_USER_PRIORITY
51*d83cc019SAndroid Build Coastguard Worker 
52*d83cc019SAndroid Build Coastguard Worker static int priorities[] = {
53*d83cc019SAndroid Build Coastguard Worker 	[LO] = MIN_PRIO / 2,
54*d83cc019SAndroid Build Coastguard Worker 	[HI] = MAX_PRIO / 2,
55*d83cc019SAndroid Build Coastguard Worker };
56*d83cc019SAndroid Build Coastguard Worker 
57*d83cc019SAndroid Build Coastguard Worker #define MAX_ELSP_QLEN 16
58*d83cc019SAndroid Build Coastguard Worker 
59*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Test shared contexts.");
60*d83cc019SAndroid Build Coastguard Worker 
create_shared_gtt(int i915,unsigned int flags)61*d83cc019SAndroid Build Coastguard Worker static void create_shared_gtt(int i915, unsigned int flags)
62*d83cc019SAndroid Build Coastguard Worker #define DETACHED 0x1
63*d83cc019SAndroid Build Coastguard Worker {
64*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
65*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = {
66*d83cc019SAndroid Build Coastguard Worker 		.handle = gem_create(i915, 4096),
67*d83cc019SAndroid Build Coastguard Worker 	};
68*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf = {
69*d83cc019SAndroid Build Coastguard Worker 		.buffers_ptr = to_user_pointer(&obj),
70*d83cc019SAndroid Build Coastguard Worker 		.buffer_count = 1,
71*d83cc019SAndroid Build Coastguard Worker 	};
72*d83cc019SAndroid Build Coastguard Worker 	uint32_t parent, child;
73*d83cc019SAndroid Build Coastguard Worker 
74*d83cc019SAndroid Build Coastguard Worker 	gem_write(i915, obj.handle, 0, &bbe, sizeof(bbe));
75*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
76*d83cc019SAndroid Build Coastguard Worker 	gem_sync(i915, obj.handle);
77*d83cc019SAndroid Build Coastguard Worker 
78*d83cc019SAndroid Build Coastguard Worker 	child = flags & DETACHED ? gem_context_create(i915) : 0;
79*d83cc019SAndroid Build Coastguard Worker 	igt_until_timeout(2) {
80*d83cc019SAndroid Build Coastguard Worker 		parent = flags & DETACHED ? child : 0;
81*d83cc019SAndroid Build Coastguard Worker 		child = gem_context_clone(i915,
82*d83cc019SAndroid Build Coastguard Worker 					  parent, I915_CONTEXT_CLONE_VM,
83*d83cc019SAndroid Build Coastguard Worker 					  0);
84*d83cc019SAndroid Build Coastguard Worker 		execbuf.rsvd1 = child;
85*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(i915, &execbuf);
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker 		if (flags & DETACHED) {
88*d83cc019SAndroid Build Coastguard Worker 			gem_context_destroy(i915, parent);
89*d83cc019SAndroid Build Coastguard Worker 			gem_execbuf(i915, &execbuf);
90*d83cc019SAndroid Build Coastguard Worker 		} else {
91*d83cc019SAndroid Build Coastguard Worker 			parent = child;
92*d83cc019SAndroid Build Coastguard Worker 			gem_context_destroy(i915, parent);
93*d83cc019SAndroid Build Coastguard Worker 		}
94*d83cc019SAndroid Build Coastguard Worker 
95*d83cc019SAndroid Build Coastguard Worker 		execbuf.rsvd1 = parent;
96*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(__gem_execbuf(i915, &execbuf), -ENOENT);
97*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(__gem_context_clone(i915,
98*d83cc019SAndroid Build Coastguard Worker 						  parent, I915_CONTEXT_CLONE_VM,
99*d83cc019SAndroid Build Coastguard Worker 						  0, &parent), -ENOENT);
100*d83cc019SAndroid Build Coastguard Worker 	}
101*d83cc019SAndroid Build Coastguard Worker 	if (flags & DETACHED)
102*d83cc019SAndroid Build Coastguard Worker 		gem_context_destroy(i915, child);
103*d83cc019SAndroid Build Coastguard Worker 
104*d83cc019SAndroid Build Coastguard Worker 	gem_sync(i915, obj.handle);
105*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, obj.handle);
106*d83cc019SAndroid Build Coastguard Worker }
107*d83cc019SAndroid Build Coastguard Worker 
disjoint_timelines(int i915)108*d83cc019SAndroid Build Coastguard Worker static void disjoint_timelines(int i915)
109*d83cc019SAndroid Build Coastguard Worker {
110*d83cc019SAndroid Build Coastguard Worker 	IGT_CORK_HANDLE(cork);
111*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin[2];
112*d83cc019SAndroid Build Coastguard Worker 	uint32_t plug, child;
113*d83cc019SAndroid Build Coastguard Worker 
114*d83cc019SAndroid Build Coastguard Worker 	igt_require(gem_has_execlists(i915));
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker 	/*
117*d83cc019SAndroid Build Coastguard Worker 	 * Each context, although they share a vm, are expected to be
118*d83cc019SAndroid Build Coastguard Worker 	 * distinct timelines. A request queued to one context should be
119*d83cc019SAndroid Build Coastguard Worker 	 * independent of any shared contexts.
120*d83cc019SAndroid Build Coastguard Worker 	 */
121*d83cc019SAndroid Build Coastguard Worker 	child = gem_context_clone(i915, 0, I915_CONTEXT_CLONE_VM, 0);
122*d83cc019SAndroid Build Coastguard Worker 	plug = igt_cork_plug(&cork, i915);
123*d83cc019SAndroid Build Coastguard Worker 
124*d83cc019SAndroid Build Coastguard Worker 	spin[0] = __igt_spin_new(i915, .ctx = 0, .dependency = plug);
125*d83cc019SAndroid Build Coastguard Worker 	spin[1] = __igt_spin_new(i915, .ctx = child);
126*d83cc019SAndroid Build Coastguard Worker 
127*d83cc019SAndroid Build Coastguard Worker 	/* Wait for the second spinner, will hang if stuck behind the first */
128*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(spin[1]);
129*d83cc019SAndroid Build Coastguard Worker 	gem_sync(i915, spin[1]->handle);
130*d83cc019SAndroid Build Coastguard Worker 
131*d83cc019SAndroid Build Coastguard Worker 	igt_cork_unplug(&cork);
132*d83cc019SAndroid Build Coastguard Worker 
133*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(i915, spin[1]);
134*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(i915, spin[0]);
135*d83cc019SAndroid Build Coastguard Worker }
136*d83cc019SAndroid Build Coastguard Worker 
exhaust_shared_gtt(int i915,unsigned int flags)137*d83cc019SAndroid Build Coastguard Worker static void exhaust_shared_gtt(int i915, unsigned int flags)
138*d83cc019SAndroid Build Coastguard Worker #define EXHAUST_LRC 0x1
139*d83cc019SAndroid Build Coastguard Worker {
140*d83cc019SAndroid Build Coastguard Worker 	i915 = gem_reopen_driver(i915);
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	igt_fork(pid, 1) {
143*d83cc019SAndroid Build Coastguard Worker 		const uint32_t bbe = MI_BATCH_BUFFER_END;
144*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_gem_exec_object2 obj = {
145*d83cc019SAndroid Build Coastguard Worker 			.handle = gem_create(i915, 4096)
146*d83cc019SAndroid Build Coastguard Worker 		};
147*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_gem_execbuffer2 execbuf = {
148*d83cc019SAndroid Build Coastguard Worker 			.buffers_ptr = to_user_pointer(&obj),
149*d83cc019SAndroid Build Coastguard Worker 			.buffer_count = 1,
150*d83cc019SAndroid Build Coastguard Worker 		};
151*d83cc019SAndroid Build Coastguard Worker 		uint32_t parent, child;
152*d83cc019SAndroid Build Coastguard Worker 		unsigned long count = 0;
153*d83cc019SAndroid Build Coastguard Worker 		int err;
154*d83cc019SAndroid Build Coastguard Worker 
155*d83cc019SAndroid Build Coastguard Worker 		gem_write(i915, obj.handle, 0, &bbe, sizeof(bbe));
156*d83cc019SAndroid Build Coastguard Worker 
157*d83cc019SAndroid Build Coastguard Worker 		child = 0;
158*d83cc019SAndroid Build Coastguard Worker 		for (;;) {
159*d83cc019SAndroid Build Coastguard Worker 			parent = child;
160*d83cc019SAndroid Build Coastguard Worker 			err = __gem_context_clone(i915,
161*d83cc019SAndroid Build Coastguard Worker 						  parent, I915_CONTEXT_CLONE_VM,
162*d83cc019SAndroid Build Coastguard Worker 						  0, &child);
163*d83cc019SAndroid Build Coastguard Worker 			if (err)
164*d83cc019SAndroid Build Coastguard Worker 				break;
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 			if (flags & EXHAUST_LRC) {
167*d83cc019SAndroid Build Coastguard Worker 				execbuf.rsvd1 = child;
168*d83cc019SAndroid Build Coastguard Worker 				err = __gem_execbuf(i915, &execbuf);
169*d83cc019SAndroid Build Coastguard Worker 				if (err)
170*d83cc019SAndroid Build Coastguard Worker 					break;
171*d83cc019SAndroid Build Coastguard Worker 			}
172*d83cc019SAndroid Build Coastguard Worker 
173*d83cc019SAndroid Build Coastguard Worker 			count++;
174*d83cc019SAndroid Build Coastguard Worker 		}
175*d83cc019SAndroid Build Coastguard Worker 		gem_sync(i915, obj.handle);
176*d83cc019SAndroid Build Coastguard Worker 
177*d83cc019SAndroid Build Coastguard Worker 		igt_info("Created %lu shared contexts, before %d (%s)\n",
178*d83cc019SAndroid Build Coastguard Worker 			 count, err, strerror(-err));
179*d83cc019SAndroid Build Coastguard Worker 	}
180*d83cc019SAndroid Build Coastguard Worker 	close(i915);
181*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
182*d83cc019SAndroid Build Coastguard Worker }
183*d83cc019SAndroid Build Coastguard Worker 
exec_shared_gtt(int i915,unsigned int ring)184*d83cc019SAndroid Build Coastguard Worker static void exec_shared_gtt(int i915, unsigned int ring)
185*d83cc019SAndroid Build Coastguard Worker {
186*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(i915));
187*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
188*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = {};
189*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf = {
190*d83cc019SAndroid Build Coastguard Worker 		.buffers_ptr = to_user_pointer(&obj),
191*d83cc019SAndroid Build Coastguard Worker 		.buffer_count = 1,
192*d83cc019SAndroid Build Coastguard Worker 		.flags = ring,
193*d83cc019SAndroid Build Coastguard Worker 	};
194*d83cc019SAndroid Build Coastguard Worker 	uint32_t scratch, *s;
195*d83cc019SAndroid Build Coastguard Worker 	uint32_t batch, cs[16];
196*d83cc019SAndroid Build Coastguard Worker 	uint64_t offset;
197*d83cc019SAndroid Build Coastguard Worker 	int i;
198*d83cc019SAndroid Build Coastguard Worker 
199*d83cc019SAndroid Build Coastguard Worker 	gem_require_ring(i915, ring);
200*d83cc019SAndroid Build Coastguard Worker 	igt_require(gem_can_store_dword(i915, ring));
201*d83cc019SAndroid Build Coastguard Worker 
202*d83cc019SAndroid Build Coastguard Worker 	/* Find a hole big enough for both objects later */
203*d83cc019SAndroid Build Coastguard Worker 	scratch = gem_create(i915, 16384);
204*d83cc019SAndroid Build Coastguard Worker 	gem_write(i915, scratch, 0, &bbe, sizeof(bbe));
205*d83cc019SAndroid Build Coastguard Worker 	obj.handle = scratch;
206*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
207*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, scratch);
208*d83cc019SAndroid Build Coastguard Worker 	obj.flags |= EXEC_OBJECT_PINNED; /* reuse this address */
209*d83cc019SAndroid Build Coastguard Worker 
210*d83cc019SAndroid Build Coastguard Worker 	scratch = gem_create(i915, 4096);
211*d83cc019SAndroid Build Coastguard Worker 	s = gem_mmap__wc(i915, scratch, 0, 4096, PROT_WRITE);
212*d83cc019SAndroid Build Coastguard Worker 
213*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(i915, scratch, I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
214*d83cc019SAndroid Build Coastguard Worker 	s[0] = bbe;
215*d83cc019SAndroid Build Coastguard Worker 	s[64] = bbe;
216*d83cc019SAndroid Build Coastguard Worker 
217*d83cc019SAndroid Build Coastguard Worker 	/* Load object into place in the GTT */
218*d83cc019SAndroid Build Coastguard Worker 	obj.handle = scratch;
219*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
220*d83cc019SAndroid Build Coastguard Worker 	offset = obj.offset;
221*d83cc019SAndroid Build Coastguard Worker 
222*d83cc019SAndroid Build Coastguard Worker 	/* Presume nothing causes an eviction in the meantime! */
223*d83cc019SAndroid Build Coastguard Worker 
224*d83cc019SAndroid Build Coastguard Worker 	batch = gem_create(i915, 4096);
225*d83cc019SAndroid Build Coastguard Worker 
226*d83cc019SAndroid Build Coastguard Worker 	i = 0;
227*d83cc019SAndroid Build Coastguard Worker 	cs[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
228*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
229*d83cc019SAndroid Build Coastguard Worker 		cs[++i] = obj.offset;
230*d83cc019SAndroid Build Coastguard Worker 		cs[++i] = obj.offset >> 32;
231*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 4) {
232*d83cc019SAndroid Build Coastguard Worker 		cs[++i] = 0;
233*d83cc019SAndroid Build Coastguard Worker 		cs[++i] = obj.offset;
234*d83cc019SAndroid Build Coastguard Worker 	} else {
235*d83cc019SAndroid Build Coastguard Worker 		cs[i]--;
236*d83cc019SAndroid Build Coastguard Worker 		cs[++i] = obj.offset;
237*d83cc019SAndroid Build Coastguard Worker 	}
238*d83cc019SAndroid Build Coastguard Worker 	cs[++i] = 0xc0ffee;
239*d83cc019SAndroid Build Coastguard Worker 	cs[++i] = bbe;
240*d83cc019SAndroid Build Coastguard Worker 	gem_write(i915, batch, 0, cs, sizeof(cs));
241*d83cc019SAndroid Build Coastguard Worker 
242*d83cc019SAndroid Build Coastguard Worker 	obj.handle = batch;
243*d83cc019SAndroid Build Coastguard Worker 	obj.offset += 8192; /* make sure we don't cause an eviction! */
244*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd1 = gem_context_clone(i915, 0, I915_CONTEXT_CLONE_VM, 0);
245*d83cc019SAndroid Build Coastguard Worker 	if (gen > 3 && gen < 6)
246*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags |= I915_EXEC_SECURE;
247*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
248*d83cc019SAndroid Build Coastguard Worker 
249*d83cc019SAndroid Build Coastguard Worker 	/* Check the scratch didn't move */
250*d83cc019SAndroid Build Coastguard Worker 	obj.handle = scratch;
251*d83cc019SAndroid Build Coastguard Worker 	obj.offset = -1;
252*d83cc019SAndroid Build Coastguard Worker 	obj.flags &= ~EXEC_OBJECT_PINNED;
253*d83cc019SAndroid Build Coastguard Worker 	execbuf.batch_start_offset = 64 * sizeof(s[0]);
254*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
255*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u64(obj.offset, offset);
256*d83cc019SAndroid Build Coastguard Worker 	gem_context_destroy(i915, execbuf.rsvd1);
257*d83cc019SAndroid Build Coastguard Worker 
258*d83cc019SAndroid Build Coastguard Worker 	gem_sync(i915, batch); /* write hazard lies */
259*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, batch);
260*d83cc019SAndroid Build Coastguard Worker 
261*d83cc019SAndroid Build Coastguard Worker 	/*
262*d83cc019SAndroid Build Coastguard Worker 	 * If we created the new context with the old GTT, the write
263*d83cc019SAndroid Build Coastguard Worker 	 * into the stale location of scratch will have landed in the right
264*d83cc019SAndroid Build Coastguard Worker 	 * object. Otherwise, it should read the previous value of
265*d83cc019SAndroid Build Coastguard Worker 	 * MI_BATCH_BUFFER_END.
266*d83cc019SAndroid Build Coastguard Worker 	 */
267*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u32(*s, 0xc0ffee);
268*d83cc019SAndroid Build Coastguard Worker 
269*d83cc019SAndroid Build Coastguard Worker 	munmap(s, 4096);
270*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, scratch);
271*d83cc019SAndroid Build Coastguard Worker }
272*d83cc019SAndroid Build Coastguard Worker 
nop_sync(int i915,uint32_t ctx,unsigned int ring,int64_t timeout)273*d83cc019SAndroid Build Coastguard Worker static int nop_sync(int i915, uint32_t ctx, unsigned int ring, int64_t timeout)
274*d83cc019SAndroid Build Coastguard Worker {
275*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
276*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = {
277*d83cc019SAndroid Build Coastguard Worker 		.handle = gem_create(i915, 4096),
278*d83cc019SAndroid Build Coastguard Worker 	};
279*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf = {
280*d83cc019SAndroid Build Coastguard Worker 		.buffers_ptr = to_user_pointer(&obj),
281*d83cc019SAndroid Build Coastguard Worker 		.buffer_count = 1,
282*d83cc019SAndroid Build Coastguard Worker 		.flags = ring,
283*d83cc019SAndroid Build Coastguard Worker 		.rsvd1 = ctx,
284*d83cc019SAndroid Build Coastguard Worker 	};
285*d83cc019SAndroid Build Coastguard Worker 	int err;
286*d83cc019SAndroid Build Coastguard Worker 
287*d83cc019SAndroid Build Coastguard Worker 	gem_write(i915, obj.handle, 0, &bbe, sizeof(bbe));
288*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
289*d83cc019SAndroid Build Coastguard Worker 	err = gem_wait(i915, obj.handle, &timeout);
290*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, obj.handle);
291*d83cc019SAndroid Build Coastguard Worker 
292*d83cc019SAndroid Build Coastguard Worker 	return err;
293*d83cc019SAndroid Build Coastguard Worker }
294*d83cc019SAndroid Build Coastguard Worker 
has_single_timeline(int i915)295*d83cc019SAndroid Build Coastguard Worker static bool has_single_timeline(int i915)
296*d83cc019SAndroid Build Coastguard Worker {
297*d83cc019SAndroid Build Coastguard Worker 	uint32_t ctx;
298*d83cc019SAndroid Build Coastguard Worker 
299*d83cc019SAndroid Build Coastguard Worker 	__gem_context_clone(i915, 0, 0,
300*d83cc019SAndroid Build Coastguard Worker 			    I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE,
301*d83cc019SAndroid Build Coastguard Worker 			    &ctx);
302*d83cc019SAndroid Build Coastguard Worker 	if (ctx)
303*d83cc019SAndroid Build Coastguard Worker 		gem_context_destroy(i915, ctx);
304*d83cc019SAndroid Build Coastguard Worker 
305*d83cc019SAndroid Build Coastguard Worker 	return ctx != 0;
306*d83cc019SAndroid Build Coastguard Worker }
307*d83cc019SAndroid Build Coastguard Worker 
single_timeline(int i915)308*d83cc019SAndroid Build Coastguard Worker static void single_timeline(int i915)
309*d83cc019SAndroid Build Coastguard Worker {
310*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
311*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = {
312*d83cc019SAndroid Build Coastguard Worker 		.handle = gem_create(i915, 4096),
313*d83cc019SAndroid Build Coastguard Worker 	};
314*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf = {
315*d83cc019SAndroid Build Coastguard Worker 		.buffers_ptr = to_user_pointer(&obj),
316*d83cc019SAndroid Build Coastguard Worker 		.buffer_count = 1,
317*d83cc019SAndroid Build Coastguard Worker 	};
318*d83cc019SAndroid Build Coastguard Worker 	struct sync_fence_info rings[16];
319*d83cc019SAndroid Build Coastguard Worker 	struct sync_file_info sync_file_info = {
320*d83cc019SAndroid Build Coastguard Worker 		.num_fences = 1,
321*d83cc019SAndroid Build Coastguard Worker 	};
322*d83cc019SAndroid Build Coastguard Worker 	unsigned int engine;
323*d83cc019SAndroid Build Coastguard Worker 	int n;
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_single_timeline(i915));
326*d83cc019SAndroid Build Coastguard Worker 
327*d83cc019SAndroid Build Coastguard Worker 	gem_write(i915, obj.handle, 0, &bbe, sizeof(bbe));
328*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
329*d83cc019SAndroid Build Coastguard Worker 	gem_sync(i915, obj.handle);
330*d83cc019SAndroid Build Coastguard Worker 
331*d83cc019SAndroid Build Coastguard Worker 	/*
332*d83cc019SAndroid Build Coastguard Worker 	 * For a "single timeline" context, each ring is on the common
333*d83cc019SAndroid Build Coastguard Worker 	 * timeline, unlike a normal context where each ring has an
334*d83cc019SAndroid Build Coastguard Worker 	 * independent timeline. That is no matter which engine we submit
335*d83cc019SAndroid Build Coastguard Worker 	 * to, it reports the same timeline name and fence context. However,
336*d83cc019SAndroid Build Coastguard Worker 	 * the fence context is not reported through the sync_fence_info.
337*d83cc019SAndroid Build Coastguard Worker 	 */
338*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd1 =
339*d83cc019SAndroid Build Coastguard Worker 		gem_context_clone(i915, 0, 0,
340*d83cc019SAndroid Build Coastguard Worker 				  I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE);
341*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = I915_EXEC_FENCE_OUT;
342*d83cc019SAndroid Build Coastguard Worker 	n = 0;
343*d83cc019SAndroid Build Coastguard Worker 	for_each_engine(i915, engine) {
344*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf_wr(i915, &execbuf);
345*d83cc019SAndroid Build Coastguard Worker 		sync_file_info.sync_fence_info = to_user_pointer(&rings[n]);
346*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(execbuf.rsvd2 >> 32, SYNC_IOC_FILE_INFO, &sync_file_info);
347*d83cc019SAndroid Build Coastguard Worker 		close(execbuf.rsvd2 >> 32);
348*d83cc019SAndroid Build Coastguard Worker 
349*d83cc019SAndroid Build Coastguard Worker 		igt_info("ring[%d] fence: %s %s\n",
350*d83cc019SAndroid Build Coastguard Worker 			 n, rings[n].driver_name, rings[n].obj_name);
351*d83cc019SAndroid Build Coastguard Worker 		n++;
352*d83cc019SAndroid Build Coastguard Worker 	}
353*d83cc019SAndroid Build Coastguard Worker 	gem_sync(i915, obj.handle);
354*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, obj.handle);
355*d83cc019SAndroid Build Coastguard Worker 
356*d83cc019SAndroid Build Coastguard Worker 	for (int i = 1; i < n; i++) {
357*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!strcmp(rings[0].driver_name, rings[i].driver_name));
358*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!strcmp(rings[0].obj_name, rings[i].obj_name));
359*d83cc019SAndroid Build Coastguard Worker 	}
360*d83cc019SAndroid Build Coastguard Worker }
361*d83cc019SAndroid Build Coastguard Worker 
exec_single_timeline(int i915,unsigned int engine)362*d83cc019SAndroid Build Coastguard Worker static void exec_single_timeline(int i915, unsigned int engine)
363*d83cc019SAndroid Build Coastguard Worker {
364*d83cc019SAndroid Build Coastguard Worker 	unsigned int other;
365*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
366*d83cc019SAndroid Build Coastguard Worker 	uint32_t ctx;
367*d83cc019SAndroid Build Coastguard Worker 
368*d83cc019SAndroid Build Coastguard Worker 	igt_require(gem_ring_has_physical_engine(i915, engine));
369*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_single_timeline(i915));
370*d83cc019SAndroid Build Coastguard Worker 
371*d83cc019SAndroid Build Coastguard Worker 	/*
372*d83cc019SAndroid Build Coastguard Worker 	 * On an ordinary context, a blockage on one engine doesn't prevent
373*d83cc019SAndroid Build Coastguard Worker 	 * execution on an other.
374*d83cc019SAndroid Build Coastguard Worker 	 */
375*d83cc019SAndroid Build Coastguard Worker 	ctx = 0;
376*d83cc019SAndroid Build Coastguard Worker 	spin = NULL;
377*d83cc019SAndroid Build Coastguard Worker 	for_each_physical_engine(i915, other) {
378*d83cc019SAndroid Build Coastguard Worker 		if (other == engine)
379*d83cc019SAndroid Build Coastguard Worker 			continue;
380*d83cc019SAndroid Build Coastguard Worker 
381*d83cc019SAndroid Build Coastguard Worker 		if (spin == NULL) {
382*d83cc019SAndroid Build Coastguard Worker 			spin = __igt_spin_new(i915, .ctx = ctx, .engine = other);
383*d83cc019SAndroid Build Coastguard Worker 		} else {
384*d83cc019SAndroid Build Coastguard Worker 			struct drm_i915_gem_execbuffer2 execbuf = {
385*d83cc019SAndroid Build Coastguard Worker 				.buffers_ptr = spin->execbuf.buffers_ptr,
386*d83cc019SAndroid Build Coastguard Worker 				.buffer_count = spin->execbuf.buffer_count,
387*d83cc019SAndroid Build Coastguard Worker 				.flags = other,
388*d83cc019SAndroid Build Coastguard Worker 				.rsvd1 = ctx,
389*d83cc019SAndroid Build Coastguard Worker 			};
390*d83cc019SAndroid Build Coastguard Worker 			gem_execbuf(i915, &execbuf);
391*d83cc019SAndroid Build Coastguard Worker 		}
392*d83cc019SAndroid Build Coastguard Worker 	}
393*d83cc019SAndroid Build Coastguard Worker 	igt_require(spin);
394*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(nop_sync(i915, ctx, engine, NSEC_PER_SEC), 0);
395*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(i915, spin);
396*d83cc019SAndroid Build Coastguard Worker 
397*d83cc019SAndroid Build Coastguard Worker 	/*
398*d83cc019SAndroid Build Coastguard Worker 	 * But if we create a context with just a single shared timeline,
399*d83cc019SAndroid Build Coastguard Worker 	 * then it will block waiting for the earlier requests on the
400*d83cc019SAndroid Build Coastguard Worker 	 * other engines.
401*d83cc019SAndroid Build Coastguard Worker 	 */
402*d83cc019SAndroid Build Coastguard Worker 	ctx = gem_context_clone(i915, 0, 0,
403*d83cc019SAndroid Build Coastguard Worker 				I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE);
404*d83cc019SAndroid Build Coastguard Worker 	spin = NULL;
405*d83cc019SAndroid Build Coastguard Worker 	for_each_physical_engine(i915, other) {
406*d83cc019SAndroid Build Coastguard Worker 		if (other == engine)
407*d83cc019SAndroid Build Coastguard Worker 			continue;
408*d83cc019SAndroid Build Coastguard Worker 
409*d83cc019SAndroid Build Coastguard Worker 		if (spin == NULL) {
410*d83cc019SAndroid Build Coastguard Worker 			spin = __igt_spin_new(i915, .ctx = ctx, .engine = other);
411*d83cc019SAndroid Build Coastguard Worker 		} else {
412*d83cc019SAndroid Build Coastguard Worker 			struct drm_i915_gem_execbuffer2 execbuf = {
413*d83cc019SAndroid Build Coastguard Worker 				.buffers_ptr = spin->execbuf.buffers_ptr,
414*d83cc019SAndroid Build Coastguard Worker 				.buffer_count = spin->execbuf.buffer_count,
415*d83cc019SAndroid Build Coastguard Worker 				.flags = other,
416*d83cc019SAndroid Build Coastguard Worker 				.rsvd1 = ctx,
417*d83cc019SAndroid Build Coastguard Worker 			};
418*d83cc019SAndroid Build Coastguard Worker 			gem_execbuf(i915, &execbuf);
419*d83cc019SAndroid Build Coastguard Worker 		}
420*d83cc019SAndroid Build Coastguard Worker 	}
421*d83cc019SAndroid Build Coastguard Worker 	igt_assert(spin);
422*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(nop_sync(i915, ctx, engine, NSEC_PER_SEC), -ETIME);
423*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(i915, spin);
424*d83cc019SAndroid Build Coastguard Worker }
425*d83cc019SAndroid Build Coastguard Worker 
store_dword(int i915,uint32_t ctx,unsigned ring,uint32_t target,uint32_t offset,uint32_t value,uint32_t cork,unsigned write_domain)426*d83cc019SAndroid Build Coastguard Worker static void store_dword(int i915, uint32_t ctx, unsigned ring,
427*d83cc019SAndroid Build Coastguard Worker 			uint32_t target, uint32_t offset, uint32_t value,
428*d83cc019SAndroid Build Coastguard Worker 			uint32_t cork, unsigned write_domain)
429*d83cc019SAndroid Build Coastguard Worker {
430*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(i915));
431*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[3];
432*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc;
433*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
434*d83cc019SAndroid Build Coastguard Worker 	uint32_t batch[16];
435*d83cc019SAndroid Build Coastguard Worker 	int i;
436*d83cc019SAndroid Build Coastguard Worker 
437*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
438*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj + !cork);
439*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 2 + !!cork;
440*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = ring;
441*d83cc019SAndroid Build Coastguard Worker 	if (gen < 6)
442*d83cc019SAndroid Build Coastguard Worker 		execbuf.flags |= I915_EXEC_SECURE;
443*d83cc019SAndroid Build Coastguard Worker 	execbuf.rsvd1 = ctx;
444*d83cc019SAndroid Build Coastguard Worker 
445*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
446*d83cc019SAndroid Build Coastguard Worker 	obj[0].handle = cork;
447*d83cc019SAndroid Build Coastguard Worker 	obj[1].handle = target;
448*d83cc019SAndroid Build Coastguard Worker 	obj[2].handle = gem_create(i915, 4096);
449*d83cc019SAndroid Build Coastguard Worker 
450*d83cc019SAndroid Build Coastguard Worker 	memset(&reloc, 0, sizeof(reloc));
451*d83cc019SAndroid Build Coastguard Worker 	reloc.target_handle = obj[1].handle;
452*d83cc019SAndroid Build Coastguard Worker 	reloc.presumed_offset = 0;
453*d83cc019SAndroid Build Coastguard Worker 	reloc.offset = sizeof(uint32_t);
454*d83cc019SAndroid Build Coastguard Worker 	reloc.delta = offset;
455*d83cc019SAndroid Build Coastguard Worker 	reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
456*d83cc019SAndroid Build Coastguard Worker 	reloc.write_domain = write_domain;
457*d83cc019SAndroid Build Coastguard Worker 	obj[2].relocs_ptr = to_user_pointer(&reloc);
458*d83cc019SAndroid Build Coastguard Worker 	obj[2].relocation_count = 1;
459*d83cc019SAndroid Build Coastguard Worker 
460*d83cc019SAndroid Build Coastguard Worker 	i = 0;
461*d83cc019SAndroid Build Coastguard Worker 	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
462*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
463*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = offset;
464*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
465*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 4) {
466*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = 0;
467*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = offset;
468*d83cc019SAndroid Build Coastguard Worker 		reloc.offset += sizeof(uint32_t);
469*d83cc019SAndroid Build Coastguard Worker 	} else {
470*d83cc019SAndroid Build Coastguard Worker 		batch[i]--;
471*d83cc019SAndroid Build Coastguard Worker 		batch[++i] = offset;
472*d83cc019SAndroid Build Coastguard Worker 	}
473*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = value;
474*d83cc019SAndroid Build Coastguard Worker 	batch[++i] = MI_BATCH_BUFFER_END;
475*d83cc019SAndroid Build Coastguard Worker 	gem_write(i915, obj[2].handle, 0, batch, sizeof(batch));
476*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
477*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, obj[2].handle);
478*d83cc019SAndroid Build Coastguard Worker }
479*d83cc019SAndroid Build Coastguard Worker 
create_highest_priority(int i915)480*d83cc019SAndroid Build Coastguard Worker static uint32_t create_highest_priority(int i915)
481*d83cc019SAndroid Build Coastguard Worker {
482*d83cc019SAndroid Build Coastguard Worker 	uint32_t ctx = gem_context_create(i915);
483*d83cc019SAndroid Build Coastguard Worker 
484*d83cc019SAndroid Build Coastguard Worker 	/*
485*d83cc019SAndroid Build Coastguard Worker 	 * If there is no priority support, all contexts will have equal
486*d83cc019SAndroid Build Coastguard Worker 	 * priority (and therefore the max user priority), so no context
487*d83cc019SAndroid Build Coastguard Worker 	 * can overtake us, and we effectively can form a plug.
488*d83cc019SAndroid Build Coastguard Worker 	 */
489*d83cc019SAndroid Build Coastguard Worker 	__gem_context_set_priority(i915, ctx, MAX_PRIO);
490*d83cc019SAndroid Build Coastguard Worker 
491*d83cc019SAndroid Build Coastguard Worker 	return ctx;
492*d83cc019SAndroid Build Coastguard Worker }
493*d83cc019SAndroid Build Coastguard Worker 
unplug_show_queue(int i915,struct igt_cork * c,unsigned int engine)494*d83cc019SAndroid Build Coastguard Worker static void unplug_show_queue(int i915, struct igt_cork *c, unsigned int engine)
495*d83cc019SAndroid Build Coastguard Worker {
496*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin[MAX_ELSP_QLEN];
497*d83cc019SAndroid Build Coastguard Worker 
498*d83cc019SAndroid Build Coastguard Worker 	for (int n = 0; n < ARRAY_SIZE(spin); n++) {
499*d83cc019SAndroid Build Coastguard Worker 		const struct igt_spin_factory opts = {
500*d83cc019SAndroid Build Coastguard Worker 			.ctx = create_highest_priority(i915),
501*d83cc019SAndroid Build Coastguard Worker 			.engine = engine,
502*d83cc019SAndroid Build Coastguard Worker 		};
503*d83cc019SAndroid Build Coastguard Worker 		spin[n] = __igt_spin_factory(i915, &opts);
504*d83cc019SAndroid Build Coastguard Worker 		gem_context_destroy(i915, opts.ctx);
505*d83cc019SAndroid Build Coastguard Worker 	}
506*d83cc019SAndroid Build Coastguard Worker 
507*d83cc019SAndroid Build Coastguard Worker 	igt_cork_unplug(c); /* batches will now be queued on the engine */
508*d83cc019SAndroid Build Coastguard Worker 	igt_debugfs_dump(i915, "i915_engine_info");
509*d83cc019SAndroid Build Coastguard Worker 
510*d83cc019SAndroid Build Coastguard Worker 	for (int n = 0; n < ARRAY_SIZE(spin); n++)
511*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(i915, spin[n]);
512*d83cc019SAndroid Build Coastguard Worker }
513*d83cc019SAndroid Build Coastguard Worker 
store_timestamp(int i915,uint32_t ctx,unsigned ring,unsigned mmio_base,int offset)514*d83cc019SAndroid Build Coastguard Worker static uint32_t store_timestamp(int i915,
515*d83cc019SAndroid Build Coastguard Worker 				uint32_t ctx, unsigned ring,
516*d83cc019SAndroid Build Coastguard Worker 				unsigned mmio_base,
517*d83cc019SAndroid Build Coastguard Worker 				int offset)
518*d83cc019SAndroid Build Coastguard Worker {
519*d83cc019SAndroid Build Coastguard Worker 	const bool r64b = intel_gen(intel_get_drm_devid(i915)) >= 8;
520*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = {
521*d83cc019SAndroid Build Coastguard Worker 		.handle = gem_create(i915, 4096),
522*d83cc019SAndroid Build Coastguard Worker 		.relocation_count = 1,
523*d83cc019SAndroid Build Coastguard Worker 	};
524*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc = {
525*d83cc019SAndroid Build Coastguard Worker 		.target_handle = obj.handle,
526*d83cc019SAndroid Build Coastguard Worker 		.offset = 2 * sizeof(uint32_t),
527*d83cc019SAndroid Build Coastguard Worker 		.delta = offset * sizeof(uint32_t),
528*d83cc019SAndroid Build Coastguard Worker 		.read_domains = I915_GEM_DOMAIN_INSTRUCTION,
529*d83cc019SAndroid Build Coastguard Worker 	};
530*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf = {
531*d83cc019SAndroid Build Coastguard Worker 		.buffers_ptr = to_user_pointer(&obj),
532*d83cc019SAndroid Build Coastguard Worker 		.buffer_count = 1,
533*d83cc019SAndroid Build Coastguard Worker 		.flags = ring,
534*d83cc019SAndroid Build Coastguard Worker 		.rsvd1 = ctx,
535*d83cc019SAndroid Build Coastguard Worker 	};
536*d83cc019SAndroid Build Coastguard Worker 	uint32_t batch[] = {
537*d83cc019SAndroid Build Coastguard Worker 		0x24 << 23 | (1 + r64b), /* SRM */
538*d83cc019SAndroid Build Coastguard Worker 		mmio_base + 0x358,
539*d83cc019SAndroid Build Coastguard Worker 		offset * sizeof(uint32_t),
540*d83cc019SAndroid Build Coastguard Worker 		0,
541*d83cc019SAndroid Build Coastguard Worker 		MI_BATCH_BUFFER_END
542*d83cc019SAndroid Build Coastguard Worker 	};
543*d83cc019SAndroid Build Coastguard Worker 
544*d83cc019SAndroid Build Coastguard Worker 	igt_require(intel_gen(intel_get_drm_devid(i915)) >= 7);
545*d83cc019SAndroid Build Coastguard Worker 
546*d83cc019SAndroid Build Coastguard Worker 	gem_write(i915, obj.handle, 0, batch, sizeof(batch));
547*d83cc019SAndroid Build Coastguard Worker 	obj.relocs_ptr = to_user_pointer(&reloc);
548*d83cc019SAndroid Build Coastguard Worker 
549*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(i915, &execbuf);
550*d83cc019SAndroid Build Coastguard Worker 
551*d83cc019SAndroid Build Coastguard Worker 	return obj.handle;
552*d83cc019SAndroid Build Coastguard Worker }
553*d83cc019SAndroid Build Coastguard Worker 
independent(int i915,unsigned ring,unsigned flags)554*d83cc019SAndroid Build Coastguard Worker static void independent(int i915, unsigned ring, unsigned flags)
555*d83cc019SAndroid Build Coastguard Worker {
556*d83cc019SAndroid Build Coastguard Worker 	const int TIMESTAMP = 1023;
557*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle[ARRAY_SIZE(priorities)];
558*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin[MAX_ELSP_QLEN];
559*d83cc019SAndroid Build Coastguard Worker 	unsigned int mmio_base;
560*d83cc019SAndroid Build Coastguard Worker 
561*d83cc019SAndroid Build Coastguard Worker 	/* XXX i915_query()! */
562*d83cc019SAndroid Build Coastguard Worker 	switch (ring) {
563*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_DEFAULT:
564*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_RENDER:
565*d83cc019SAndroid Build Coastguard Worker 		mmio_base = 0x2000;
566*d83cc019SAndroid Build Coastguard Worker 		break;
567*d83cc019SAndroid Build Coastguard Worker #if 0
568*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_BSD:
569*d83cc019SAndroid Build Coastguard Worker 		mmio_base = 0x12000;
570*d83cc019SAndroid Build Coastguard Worker 		break;
571*d83cc019SAndroid Build Coastguard Worker #endif
572*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_BLT:
573*d83cc019SAndroid Build Coastguard Worker 		mmio_base = 0x22000;
574*d83cc019SAndroid Build Coastguard Worker 		break;
575*d83cc019SAndroid Build Coastguard Worker 
576*d83cc019SAndroid Build Coastguard Worker #define GEN11_VECS0_BASE 0x1c8000
577*d83cc019SAndroid Build Coastguard Worker #define GEN11_VECS1_BASE 0x1d8000
578*d83cc019SAndroid Build Coastguard Worker 	case I915_EXEC_VEBOX:
579*d83cc019SAndroid Build Coastguard Worker 		if (intel_gen(intel_get_drm_devid(i915)) >= 11)
580*d83cc019SAndroid Build Coastguard Worker 			mmio_base = GEN11_VECS0_BASE;
581*d83cc019SAndroid Build Coastguard Worker 		else
582*d83cc019SAndroid Build Coastguard Worker 			mmio_base = 0x1a000;
583*d83cc019SAndroid Build Coastguard Worker 		break;
584*d83cc019SAndroid Build Coastguard Worker 
585*d83cc019SAndroid Build Coastguard Worker 	default:
586*d83cc019SAndroid Build Coastguard Worker 		igt_skip("mmio base not known\n");
587*d83cc019SAndroid Build Coastguard Worker 	}
588*d83cc019SAndroid Build Coastguard Worker 
589*d83cc019SAndroid Build Coastguard Worker 	for (int n = 0; n < ARRAY_SIZE(spin); n++) {
590*d83cc019SAndroid Build Coastguard Worker 		const struct igt_spin_factory opts = {
591*d83cc019SAndroid Build Coastguard Worker 			.ctx = create_highest_priority(i915),
592*d83cc019SAndroid Build Coastguard Worker 			.engine = ring,
593*d83cc019SAndroid Build Coastguard Worker 		};
594*d83cc019SAndroid Build Coastguard Worker 		spin[n] = __igt_spin_factory(i915, &opts);
595*d83cc019SAndroid Build Coastguard Worker 		gem_context_destroy(i915, opts.ctx);
596*d83cc019SAndroid Build Coastguard Worker 	}
597*d83cc019SAndroid Build Coastguard Worker 
598*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < ARRAY_SIZE(priorities); i++) {
599*d83cc019SAndroid Build Coastguard Worker 		uint32_t ctx = gem_queue_create(i915);
600*d83cc019SAndroid Build Coastguard Worker 		gem_context_set_priority(i915, ctx, priorities[i]);
601*d83cc019SAndroid Build Coastguard Worker 		handle[i] = store_timestamp(i915, ctx, ring, mmio_base, TIMESTAMP);
602*d83cc019SAndroid Build Coastguard Worker 		gem_context_destroy(i915, ctx);
603*d83cc019SAndroid Build Coastguard Worker 	}
604*d83cc019SAndroid Build Coastguard Worker 
605*d83cc019SAndroid Build Coastguard Worker 	for (int n = 0; n < ARRAY_SIZE(spin); n++)
606*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(i915, spin[n]);
607*d83cc019SAndroid Build Coastguard Worker 
608*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < ARRAY_SIZE(priorities); i++) {
609*d83cc019SAndroid Build Coastguard Worker 		uint32_t *ptr;
610*d83cc019SAndroid Build Coastguard Worker 
611*d83cc019SAndroid Build Coastguard Worker 		ptr = gem_mmap__gtt(i915, handle[i], 4096, PROT_READ);
612*d83cc019SAndroid Build Coastguard Worker 		gem_set_domain(i915, handle[i], /* no write hazard lies! */
613*d83cc019SAndroid Build Coastguard Worker 			       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
614*d83cc019SAndroid Build Coastguard Worker 		gem_close(i915, handle[i]);
615*d83cc019SAndroid Build Coastguard Worker 
616*d83cc019SAndroid Build Coastguard Worker 		handle[i] = ptr[TIMESTAMP];
617*d83cc019SAndroid Build Coastguard Worker 		munmap(ptr, 4096);
618*d83cc019SAndroid Build Coastguard Worker 
619*d83cc019SAndroid Build Coastguard Worker 		igt_debug("ctx[%d] .prio=%d, timestamp=%u\n",
620*d83cc019SAndroid Build Coastguard Worker 			  i, priorities[i], handle[i]);
621*d83cc019SAndroid Build Coastguard Worker 	}
622*d83cc019SAndroid Build Coastguard Worker 
623*d83cc019SAndroid Build Coastguard Worker 	igt_assert((int32_t)(handle[HI] - handle[LO]) < 0);
624*d83cc019SAndroid Build Coastguard Worker }
625*d83cc019SAndroid Build Coastguard Worker 
reorder(int i915,unsigned ring,unsigned flags)626*d83cc019SAndroid Build Coastguard Worker static void reorder(int i915, unsigned ring, unsigned flags)
627*d83cc019SAndroid Build Coastguard Worker #define EQUAL 1
628*d83cc019SAndroid Build Coastguard Worker {
629*d83cc019SAndroid Build Coastguard Worker 	IGT_CORK_HANDLE(cork);
630*d83cc019SAndroid Build Coastguard Worker 	uint32_t scratch;
631*d83cc019SAndroid Build Coastguard Worker 	uint32_t *ptr;
632*d83cc019SAndroid Build Coastguard Worker 	uint32_t ctx[2];
633*d83cc019SAndroid Build Coastguard Worker 	uint32_t plug;
634*d83cc019SAndroid Build Coastguard Worker 
635*d83cc019SAndroid Build Coastguard Worker 	ctx[LO] = gem_queue_create(i915);
636*d83cc019SAndroid Build Coastguard Worker 	gem_context_set_priority(i915, ctx[LO], MIN_PRIO);
637*d83cc019SAndroid Build Coastguard Worker 
638*d83cc019SAndroid Build Coastguard Worker 	ctx[HI] = gem_queue_create(i915);
639*d83cc019SAndroid Build Coastguard Worker 	gem_context_set_priority(i915, ctx[HI], flags & EQUAL ? MIN_PRIO : 0);
640*d83cc019SAndroid Build Coastguard Worker 
641*d83cc019SAndroid Build Coastguard Worker 	scratch = gem_create(i915, 4096);
642*d83cc019SAndroid Build Coastguard Worker 	plug = igt_cork_plug(&cork, i915);
643*d83cc019SAndroid Build Coastguard Worker 
644*d83cc019SAndroid Build Coastguard Worker 	/* We expect the high priority context to be executed first, and
645*d83cc019SAndroid Build Coastguard Worker 	 * so the final result will be value from the low priority context.
646*d83cc019SAndroid Build Coastguard Worker 	 */
647*d83cc019SAndroid Build Coastguard Worker 	store_dword(i915, ctx[LO], ring, scratch, 0, ctx[LO], plug, 0);
648*d83cc019SAndroid Build Coastguard Worker 	store_dword(i915, ctx[HI], ring, scratch, 0, ctx[HI], plug, 0);
649*d83cc019SAndroid Build Coastguard Worker 
650*d83cc019SAndroid Build Coastguard Worker 	unplug_show_queue(i915, &cork, ring);
651*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, plug);
652*d83cc019SAndroid Build Coastguard Worker 
653*d83cc019SAndroid Build Coastguard Worker 	gem_context_destroy(i915, ctx[LO]);
654*d83cc019SAndroid Build Coastguard Worker 	gem_context_destroy(i915, ctx[HI]);
655*d83cc019SAndroid Build Coastguard Worker 
656*d83cc019SAndroid Build Coastguard Worker 	ptr = gem_mmap__gtt(i915, scratch, 4096, PROT_READ);
657*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(i915, scratch, /* no write hazard lies! */
658*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
659*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, scratch);
660*d83cc019SAndroid Build Coastguard Worker 
661*d83cc019SAndroid Build Coastguard Worker 	if (flags & EQUAL) /* equal priority, result will be fifo */
662*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(ptr[0], ctx[HI]);
663*d83cc019SAndroid Build Coastguard Worker 	else
664*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(ptr[0], ctx[LO]);
665*d83cc019SAndroid Build Coastguard Worker 	munmap(ptr, 4096);
666*d83cc019SAndroid Build Coastguard Worker }
667*d83cc019SAndroid Build Coastguard Worker 
promotion(int i915,unsigned ring)668*d83cc019SAndroid Build Coastguard Worker static void promotion(int i915, unsigned ring)
669*d83cc019SAndroid Build Coastguard Worker {
670*d83cc019SAndroid Build Coastguard Worker 	IGT_CORK_HANDLE(cork);
671*d83cc019SAndroid Build Coastguard Worker 	uint32_t result, dep;
672*d83cc019SAndroid Build Coastguard Worker 	uint32_t *ptr;
673*d83cc019SAndroid Build Coastguard Worker 	uint32_t ctx[3];
674*d83cc019SAndroid Build Coastguard Worker 	uint32_t plug;
675*d83cc019SAndroid Build Coastguard Worker 
676*d83cc019SAndroid Build Coastguard Worker 	ctx[LO] = gem_queue_create(i915);
677*d83cc019SAndroid Build Coastguard Worker 	gem_context_set_priority(i915, ctx[LO], MIN_PRIO);
678*d83cc019SAndroid Build Coastguard Worker 
679*d83cc019SAndroid Build Coastguard Worker 	ctx[HI] = gem_queue_create(i915);
680*d83cc019SAndroid Build Coastguard Worker 	gem_context_set_priority(i915, ctx[HI], 0);
681*d83cc019SAndroid Build Coastguard Worker 
682*d83cc019SAndroid Build Coastguard Worker 	ctx[NOISE] = gem_queue_create(i915);
683*d83cc019SAndroid Build Coastguard Worker 	gem_context_set_priority(i915, ctx[NOISE], MIN_PRIO/2);
684*d83cc019SAndroid Build Coastguard Worker 
685*d83cc019SAndroid Build Coastguard Worker 	result = gem_create(i915, 4096);
686*d83cc019SAndroid Build Coastguard Worker 	dep = gem_create(i915, 4096);
687*d83cc019SAndroid Build Coastguard Worker 
688*d83cc019SAndroid Build Coastguard Worker 	plug = igt_cork_plug(&cork, i915);
689*d83cc019SAndroid Build Coastguard Worker 
690*d83cc019SAndroid Build Coastguard Worker 	/* Expect that HI promotes LO, so the order will be LO, HI, NOISE.
691*d83cc019SAndroid Build Coastguard Worker 	 *
692*d83cc019SAndroid Build Coastguard Worker 	 * fifo would be NOISE, LO, HI.
693*d83cc019SAndroid Build Coastguard Worker 	 * strict priority would be  HI, NOISE, LO
694*d83cc019SAndroid Build Coastguard Worker 	 */
695*d83cc019SAndroid Build Coastguard Worker 	store_dword(i915, ctx[NOISE], ring, result, 0, ctx[NOISE], plug, 0);
696*d83cc019SAndroid Build Coastguard Worker 	store_dword(i915, ctx[LO], ring, result, 0, ctx[LO], plug, 0);
697*d83cc019SAndroid Build Coastguard Worker 
698*d83cc019SAndroid Build Coastguard Worker 	/* link LO <-> HI via a dependency on another buffer */
699*d83cc019SAndroid Build Coastguard Worker 	store_dword(i915, ctx[LO], ring, dep, 0, ctx[LO], 0, I915_GEM_DOMAIN_INSTRUCTION);
700*d83cc019SAndroid Build Coastguard Worker 	store_dword(i915, ctx[HI], ring, dep, 0, ctx[HI], 0, 0);
701*d83cc019SAndroid Build Coastguard Worker 
702*d83cc019SAndroid Build Coastguard Worker 	store_dword(i915, ctx[HI], ring, result, 0, ctx[HI], 0, 0);
703*d83cc019SAndroid Build Coastguard Worker 
704*d83cc019SAndroid Build Coastguard Worker 	unplug_show_queue(i915, &cork, ring);
705*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, plug);
706*d83cc019SAndroid Build Coastguard Worker 
707*d83cc019SAndroid Build Coastguard Worker 	gem_context_destroy(i915, ctx[NOISE]);
708*d83cc019SAndroid Build Coastguard Worker 	gem_context_destroy(i915, ctx[LO]);
709*d83cc019SAndroid Build Coastguard Worker 	gem_context_destroy(i915, ctx[HI]);
710*d83cc019SAndroid Build Coastguard Worker 
711*d83cc019SAndroid Build Coastguard Worker 	ptr = gem_mmap__gtt(i915, dep, 4096, PROT_READ);
712*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(i915, dep, /* no write hazard lies! */
713*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
714*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, dep);
715*d83cc019SAndroid Build Coastguard Worker 
716*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u32(ptr[0], ctx[HI]);
717*d83cc019SAndroid Build Coastguard Worker 	munmap(ptr, 4096);
718*d83cc019SAndroid Build Coastguard Worker 
719*d83cc019SAndroid Build Coastguard Worker 	ptr = gem_mmap__gtt(i915, result, 4096, PROT_READ);
720*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(i915, result, /* no write hazard lies! */
721*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
722*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, result);
723*d83cc019SAndroid Build Coastguard Worker 
724*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u32(ptr[0], ctx[NOISE]);
725*d83cc019SAndroid Build Coastguard Worker 	munmap(ptr, 4096);
726*d83cc019SAndroid Build Coastguard Worker }
727*d83cc019SAndroid Build Coastguard Worker 
smoketest(int i915,unsigned ring,unsigned timeout)728*d83cc019SAndroid Build Coastguard Worker static void smoketest(int i915, unsigned ring, unsigned timeout)
729*d83cc019SAndroid Build Coastguard Worker {
730*d83cc019SAndroid Build Coastguard Worker 	const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
731*d83cc019SAndroid Build Coastguard Worker 	unsigned engines[16];
732*d83cc019SAndroid Build Coastguard Worker 	unsigned nengine;
733*d83cc019SAndroid Build Coastguard Worker 	unsigned engine;
734*d83cc019SAndroid Build Coastguard Worker 	uint32_t scratch;
735*d83cc019SAndroid Build Coastguard Worker 	uint32_t *ptr;
736*d83cc019SAndroid Build Coastguard Worker 
737*d83cc019SAndroid Build Coastguard Worker 	nengine = 0;
738*d83cc019SAndroid Build Coastguard Worker 	for_each_physical_engine(i915, engine)
739*d83cc019SAndroid Build Coastguard Worker 		engines[nengine++] = engine;
740*d83cc019SAndroid Build Coastguard Worker 	igt_require(nengine);
741*d83cc019SAndroid Build Coastguard Worker 
742*d83cc019SAndroid Build Coastguard Worker 	scratch = gem_create(i915, 4096);
743*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, ncpus) {
744*d83cc019SAndroid Build Coastguard Worker 		unsigned long count = 0;
745*d83cc019SAndroid Build Coastguard Worker 		uint32_t ctx;
746*d83cc019SAndroid Build Coastguard Worker 
747*d83cc019SAndroid Build Coastguard Worker 		hars_petruska_f54_1_random_perturb(child);
748*d83cc019SAndroid Build Coastguard Worker 
749*d83cc019SAndroid Build Coastguard Worker 		ctx = gem_queue_create(i915);
750*d83cc019SAndroid Build Coastguard Worker 		igt_until_timeout(timeout) {
751*d83cc019SAndroid Build Coastguard Worker 			int prio;
752*d83cc019SAndroid Build Coastguard Worker 
753*d83cc019SAndroid Build Coastguard Worker 			prio = hars_petruska_f54_1_random_unsafe_max(MAX_PRIO - MIN_PRIO) + MIN_PRIO;
754*d83cc019SAndroid Build Coastguard Worker 			gem_context_set_priority(i915, ctx, prio);
755*d83cc019SAndroid Build Coastguard Worker 
756*d83cc019SAndroid Build Coastguard Worker 			engine = engines[hars_petruska_f54_1_random_unsafe_max(nengine)];
757*d83cc019SAndroid Build Coastguard Worker 			store_dword(i915, ctx, engine, scratch,
758*d83cc019SAndroid Build Coastguard Worker 				    8*child + 0, ~child,
759*d83cc019SAndroid Build Coastguard Worker 				    0, 0);
760*d83cc019SAndroid Build Coastguard Worker 			for (unsigned int step = 0; step < 8; step++)
761*d83cc019SAndroid Build Coastguard Worker 				store_dword(i915, ctx, engine, scratch,
762*d83cc019SAndroid Build Coastguard Worker 					    8*child + 4, count++,
763*d83cc019SAndroid Build Coastguard Worker 					    0, 0);
764*d83cc019SAndroid Build Coastguard Worker 		}
765*d83cc019SAndroid Build Coastguard Worker 		gem_context_destroy(i915, ctx);
766*d83cc019SAndroid Build Coastguard Worker 	}
767*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
768*d83cc019SAndroid Build Coastguard Worker 
769*d83cc019SAndroid Build Coastguard Worker 	ptr = gem_mmap__gtt(i915, scratch, 4096, PROT_READ);
770*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(i915, scratch, /* no write hazard lies! */
771*d83cc019SAndroid Build Coastguard Worker 			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
772*d83cc019SAndroid Build Coastguard Worker 	gem_close(i915, scratch);
773*d83cc019SAndroid Build Coastguard Worker 
774*d83cc019SAndroid Build Coastguard Worker 	for (unsigned n = 0; n < ncpus; n++) {
775*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq_u32(ptr[2*n], ~n);
776*d83cc019SAndroid Build Coastguard Worker 		/*
777*d83cc019SAndroid Build Coastguard Worker 		 * Note this count is approximate due to unconstrained
778*d83cc019SAndroid Build Coastguard Worker 		 * ordering of the dword writes between engines.
779*d83cc019SAndroid Build Coastguard Worker 		 *
780*d83cc019SAndroid Build Coastguard Worker 		 * Take the result with a pinch of salt.
781*d83cc019SAndroid Build Coastguard Worker 		 */
782*d83cc019SAndroid Build Coastguard Worker 		igt_info("Child[%d] completed %u cycles\n",  n, ptr[2*n+1]);
783*d83cc019SAndroid Build Coastguard Worker 	}
784*d83cc019SAndroid Build Coastguard Worker 	munmap(ptr, 4096);
785*d83cc019SAndroid Build Coastguard Worker }
786*d83cc019SAndroid Build Coastguard Worker 
787*d83cc019SAndroid Build Coastguard Worker igt_main
788*d83cc019SAndroid Build Coastguard Worker {
789*d83cc019SAndroid Build Coastguard Worker 	const struct intel_execution_engine *e;
790*d83cc019SAndroid Build Coastguard Worker 	int i915 = -1;
791*d83cc019SAndroid Build Coastguard Worker 
792*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
793*d83cc019SAndroid Build Coastguard Worker 		i915 = drm_open_driver(DRIVER_INTEL);
794*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(i915);
795*d83cc019SAndroid Build Coastguard Worker 	}
796*d83cc019SAndroid Build Coastguard Worker 
797*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group {
798*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
799*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_contexts_has_shared_gtt(i915));
800*d83cc019SAndroid Build Coastguard Worker 			igt_fork_hang_detector(i915);
801*d83cc019SAndroid Build Coastguard Worker 		}
802*d83cc019SAndroid Build Coastguard Worker 
803*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("create-shared-gtt")
804*d83cc019SAndroid Build Coastguard Worker 			create_shared_gtt(i915, 0);
805*d83cc019SAndroid Build Coastguard Worker 
806*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("detached-shared-gtt")
807*d83cc019SAndroid Build Coastguard Worker 			create_shared_gtt(i915, DETACHED);
808*d83cc019SAndroid Build Coastguard Worker 
809*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("disjoint-timelines")
810*d83cc019SAndroid Build Coastguard Worker 			disjoint_timelines(i915);
811*d83cc019SAndroid Build Coastguard Worker 
812*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("single-timeline")
813*d83cc019SAndroid Build Coastguard Worker 			single_timeline(i915);
814*d83cc019SAndroid Build Coastguard Worker 
815*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("exhaust-shared-gtt")
816*d83cc019SAndroid Build Coastguard Worker 			exhaust_shared_gtt(i915, 0);
817*d83cc019SAndroid Build Coastguard Worker 
818*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("exhaust-shared-gtt-lrc")
819*d83cc019SAndroid Build Coastguard Worker 			exhaust_shared_gtt(i915, EXHAUST_LRC);
820*d83cc019SAndroid Build Coastguard Worker 
821*d83cc019SAndroid Build Coastguard Worker 		for (e = intel_execution_engines; e->name; e++) {
822*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("exec-shared-gtt-%s", e->name)
823*d83cc019SAndroid Build Coastguard Worker 				exec_shared_gtt(i915, e->exec_id | e->flags);
824*d83cc019SAndroid Build Coastguard Worker 
825*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("exec-single-timeline-%s", e->name)
826*d83cc019SAndroid Build Coastguard Worker 				exec_single_timeline(i915,
827*d83cc019SAndroid Build Coastguard Worker 						     e->exec_id | e->flags);
828*d83cc019SAndroid Build Coastguard Worker 
829*d83cc019SAndroid Build Coastguard Worker 			/*
830*d83cc019SAndroid Build Coastguard Worker 			 * Check that the shared contexts operate independently,
831*d83cc019SAndroid Build Coastguard Worker 			 * that is requests on one ("queue") can be scheduled
832*d83cc019SAndroid Build Coastguard Worker 			 * around another queue. We only check the basics here,
833*d83cc019SAndroid Build Coastguard Worker 			 * enough to reduce the queue into just another context,
834*d83cc019SAndroid Build Coastguard Worker 			 * and so rely on gem_exec_schedule to prove the rest.
835*d83cc019SAndroid Build Coastguard Worker 			 */
836*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_group {
837*d83cc019SAndroid Build Coastguard Worker 				igt_fixture {
838*d83cc019SAndroid Build Coastguard Worker 					gem_require_ring(i915, e->exec_id | e->flags);
839*d83cc019SAndroid Build Coastguard Worker 					igt_require(gem_can_store_dword(i915, e->exec_id | e->flags));
840*d83cc019SAndroid Build Coastguard Worker 					igt_require(gem_scheduler_enabled(i915));
841*d83cc019SAndroid Build Coastguard Worker 					igt_require(gem_scheduler_has_ctx_priority(i915));
842*d83cc019SAndroid Build Coastguard Worker 				}
843*d83cc019SAndroid Build Coastguard Worker 
844*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("Q-independent-%s", e->name)
845*d83cc019SAndroid Build Coastguard Worker 					independent(i915, e->exec_id | e->flags, 0);
846*d83cc019SAndroid Build Coastguard Worker 
847*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("Q-in-order-%s", e->name)
848*d83cc019SAndroid Build Coastguard Worker 					reorder(i915, e->exec_id | e->flags, EQUAL);
849*d83cc019SAndroid Build Coastguard Worker 
850*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("Q-out-order-%s", e->name)
851*d83cc019SAndroid Build Coastguard Worker 					reorder(i915, e->exec_id | e->flags, 0);
852*d83cc019SAndroid Build Coastguard Worker 
853*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("Q-promotion-%s", e->name)
854*d83cc019SAndroid Build Coastguard Worker 					promotion(i915, e->exec_id | e->flags);
855*d83cc019SAndroid Build Coastguard Worker 
856*d83cc019SAndroid Build Coastguard Worker 				igt_subtest_f("Q-smoketest-%s", e->name)
857*d83cc019SAndroid Build Coastguard Worker 					smoketest(i915, e->exec_id | e->flags, 5);
858*d83cc019SAndroid Build Coastguard Worker 			}
859*d83cc019SAndroid Build Coastguard Worker 		}
860*d83cc019SAndroid Build Coastguard Worker 
861*d83cc019SAndroid Build Coastguard Worker 		igt_subtest("Q-smoketest-all") {
862*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_scheduler_enabled(i915));
863*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_scheduler_has_ctx_priority(i915));
864*d83cc019SAndroid Build Coastguard Worker 			smoketest(i915, -1, 30);
865*d83cc019SAndroid Build Coastguard Worker 		}
866*d83cc019SAndroid Build Coastguard Worker 
867*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
868*d83cc019SAndroid Build Coastguard Worker 			igt_stop_hang_detector();
869*d83cc019SAndroid Build Coastguard Worker 		}
870*d83cc019SAndroid Build Coastguard Worker 	}
871*d83cc019SAndroid Build Coastguard Worker }
872