xref: /aosp_15_r20/external/igt-gpu-tools/lib/igt_dummyload.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2016 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  */
24*d83cc019SAndroid Build Coastguard Worker 
25*d83cc019SAndroid Build Coastguard Worker #include <time.h>
26*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
27*d83cc019SAndroid Build Coastguard Worker #include <pthread.h>
28*d83cc019SAndroid Build Coastguard Worker #include <sys/poll.h>
29*d83cc019SAndroid Build Coastguard Worker 
30*d83cc019SAndroid Build Coastguard Worker #include <i915_drm.h>
31*d83cc019SAndroid Build Coastguard Worker 
32*d83cc019SAndroid Build Coastguard Worker #include "igt_core.h"
33*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
34*d83cc019SAndroid Build Coastguard Worker #include "igt_device.h"
35*d83cc019SAndroid Build Coastguard Worker #include "igt_dummyload.h"
36*d83cc019SAndroid Build Coastguard Worker #include "igt_gt.h"
37*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
38*d83cc019SAndroid Build Coastguard Worker #include "intel_reg.h"
39*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
40*d83cc019SAndroid Build Coastguard Worker #include "sw_sync.h"
41*d83cc019SAndroid Build Coastguard Worker #include "igt_vgem.h"
42*d83cc019SAndroid Build Coastguard Worker #include "i915/gem_engine_topology.h"
43*d83cc019SAndroid Build Coastguard Worker #include "i915/gem_mman.h"
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker /**
46*d83cc019SAndroid Build Coastguard Worker  * SECTION:igt_dummyload
47*d83cc019SAndroid Build Coastguard Worker  * @short_description: Library for submitting GPU workloads
48*d83cc019SAndroid Build Coastguard Worker  * @title: Dummyload
49*d83cc019SAndroid Build Coastguard Worker  * @include: igt.h
50*d83cc019SAndroid Build Coastguard Worker  *
51*d83cc019SAndroid Build Coastguard Worker  * A lot of igt testcases need some GPU workload to make sure a race window is
52*d83cc019SAndroid Build Coastguard Worker  * big enough. Unfortunately having a fixed amount of workload leads to
53*d83cc019SAndroid Build Coastguard Worker  * spurious test failures or overly long runtimes on some fast/slow platforms.
54*d83cc019SAndroid Build Coastguard Worker  * This library contains functionality to submit GPU workloads that should
55*d83cc019SAndroid Build Coastguard Worker  * consume exactly a specific amount of time.
56*d83cc019SAndroid Build Coastguard Worker  */
57*d83cc019SAndroid Build Coastguard Worker 
58*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_SHIFT      (13)
59*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_MASK       (3 << LOCAL_I915_EXEC_BSD_SHIFT)
60*d83cc019SAndroid Build Coastguard Worker 
61*d83cc019SAndroid Build Coastguard Worker #define ENGINE_MASK  (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
62*d83cc019SAndroid Build Coastguard Worker 
63*d83cc019SAndroid Build Coastguard Worker #define MI_ARB_CHK (0x5 << 23)
64*d83cc019SAndroid Build Coastguard Worker 
65*d83cc019SAndroid Build Coastguard Worker static const int BATCH_SIZE = 4096;
66*d83cc019SAndroid Build Coastguard Worker static const int LOOP_START_OFFSET = 64;
67*d83cc019SAndroid Build Coastguard Worker 
68*d83cc019SAndroid Build Coastguard Worker static IGT_LIST(spin_list);
69*d83cc019SAndroid Build Coastguard Worker static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker static int
emit_recursive_batch(igt_spin_t * spin,int fd,const struct igt_spin_factory * opts)72*d83cc019SAndroid Build Coastguard Worker emit_recursive_batch(igt_spin_t *spin,
73*d83cc019SAndroid Build Coastguard Worker 		     int fd, const struct igt_spin_factory *opts)
74*d83cc019SAndroid Build Coastguard Worker {
75*d83cc019SAndroid Build Coastguard Worker #define SCRATCH 0
76*d83cc019SAndroid Build Coastguard Worker #define BATCH IGT_SPIN_BATCH
77*d83cc019SAndroid Build Coastguard Worker 	const int gen = intel_gen(intel_get_drm_devid(fd));
78*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry relocs[2], *r;
79*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 *execbuf;
80*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 *obj;
81*d83cc019SAndroid Build Coastguard Worker 	unsigned int flags[GEM_MAX_ENGINES];
82*d83cc019SAndroid Build Coastguard Worker 	unsigned int nengine;
83*d83cc019SAndroid Build Coastguard Worker 	int fence_fd = -1;
84*d83cc019SAndroid Build Coastguard Worker 	uint32_t *cs, *batch;
85*d83cc019SAndroid Build Coastguard Worker 	int i;
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker 	nengine = 0;
88*d83cc019SAndroid Build Coastguard Worker 	if (opts->engine == ALL_ENGINES) {
89*d83cc019SAndroid Build Coastguard Worker 		struct intel_execution_engine2 *engine;
90*d83cc019SAndroid Build Coastguard Worker 
91*d83cc019SAndroid Build Coastguard Worker 		for_each_context_engine(fd, opts->ctx, engine) {
92*d83cc019SAndroid Build Coastguard Worker 			if (opts->flags & IGT_SPIN_POLL_RUN &&
93*d83cc019SAndroid Build Coastguard Worker 			    !gem_class_can_store_dword(fd, engine->engine_class))
94*d83cc019SAndroid Build Coastguard Worker 				continue;
95*d83cc019SAndroid Build Coastguard Worker 
96*d83cc019SAndroid Build Coastguard Worker 			flags[nengine++] = engine->flags;
97*d83cc019SAndroid Build Coastguard Worker 		}
98*d83cc019SAndroid Build Coastguard Worker 	} else {
99*d83cc019SAndroid Build Coastguard Worker 		flags[nengine++] = opts->engine;
100*d83cc019SAndroid Build Coastguard Worker 	}
101*d83cc019SAndroid Build Coastguard Worker 	igt_require(nengine);
102*d83cc019SAndroid Build Coastguard Worker 
103*d83cc019SAndroid Build Coastguard Worker 	memset(&spin->execbuf, 0, sizeof(spin->execbuf));
104*d83cc019SAndroid Build Coastguard Worker 	execbuf = &spin->execbuf;
105*d83cc019SAndroid Build Coastguard Worker 	memset(spin->obj, 0, sizeof(spin->obj));
106*d83cc019SAndroid Build Coastguard Worker 	obj = spin->obj;
107*d83cc019SAndroid Build Coastguard Worker 	memset(relocs, 0, sizeof(relocs));
108*d83cc019SAndroid Build Coastguard Worker 
109*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].handle = gem_create(fd, BATCH_SIZE);
110*d83cc019SAndroid Build Coastguard Worker 	batch = __gem_mmap__wc(fd, obj[BATCH].handle,
111*d83cc019SAndroid Build Coastguard Worker 			       0, BATCH_SIZE, PROT_WRITE);
112*d83cc019SAndroid Build Coastguard Worker 	if (!batch)
113*d83cc019SAndroid Build Coastguard Worker 		batch = gem_mmap__gtt(fd, obj[BATCH].handle,
114*d83cc019SAndroid Build Coastguard Worker 				      BATCH_SIZE, PROT_WRITE);
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, obj[BATCH].handle,
117*d83cc019SAndroid Build Coastguard Worker 		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
118*d83cc019SAndroid Build Coastguard Worker 	execbuf->buffer_count++;
119*d83cc019SAndroid Build Coastguard Worker 	cs = batch;
120*d83cc019SAndroid Build Coastguard Worker 
121*d83cc019SAndroid Build Coastguard Worker 	if (opts->dependency) {
122*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!(opts->flags & IGT_SPIN_POLL_RUN));
123*d83cc019SAndroid Build Coastguard Worker 
124*d83cc019SAndroid Build Coastguard Worker 		r = &relocs[obj[BATCH].relocation_count++];
125*d83cc019SAndroid Build Coastguard Worker 
126*d83cc019SAndroid Build Coastguard Worker 		/* dummy write to dependency */
127*d83cc019SAndroid Build Coastguard Worker 		obj[SCRATCH].handle = opts->dependency;
128*d83cc019SAndroid Build Coastguard Worker 		r->presumed_offset = 0;
129*d83cc019SAndroid Build Coastguard Worker 		r->target_handle = obj[SCRATCH].handle;
130*d83cc019SAndroid Build Coastguard Worker 		r->offset = sizeof(uint32_t) * 1020;
131*d83cc019SAndroid Build Coastguard Worker 		r->delta = 0;
132*d83cc019SAndroid Build Coastguard Worker 		r->read_domains = I915_GEM_DOMAIN_RENDER;
133*d83cc019SAndroid Build Coastguard Worker 		r->write_domain = I915_GEM_DOMAIN_RENDER;
134*d83cc019SAndroid Build Coastguard Worker 
135*d83cc019SAndroid Build Coastguard Worker 		execbuf->buffer_count++;
136*d83cc019SAndroid Build Coastguard Worker 	} else if (opts->flags & IGT_SPIN_POLL_RUN) {
137*d83cc019SAndroid Build Coastguard Worker 		r = &relocs[obj[BATCH].relocation_count++];
138*d83cc019SAndroid Build Coastguard Worker 
139*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!opts->dependency);
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker 		if (gen == 4 || gen == 5) {
142*d83cc019SAndroid Build Coastguard Worker 			execbuf->flags |= I915_EXEC_SECURE;
143*d83cc019SAndroid Build Coastguard Worker 			igt_require(__igt_device_set_master(fd) == 0);
144*d83cc019SAndroid Build Coastguard Worker 		}
145*d83cc019SAndroid Build Coastguard Worker 
146*d83cc019SAndroid Build Coastguard Worker 		spin->poll_handle = gem_create(fd, 4096);
147*d83cc019SAndroid Build Coastguard Worker 		obj[SCRATCH].handle = spin->poll_handle;
148*d83cc019SAndroid Build Coastguard Worker 
149*d83cc019SAndroid Build Coastguard Worker 		if (__gem_set_caching(fd, spin->poll_handle,
150*d83cc019SAndroid Build Coastguard Worker 				      I915_CACHING_CACHED) == 0)
151*d83cc019SAndroid Build Coastguard Worker 			spin->poll = gem_mmap__cpu(fd, spin->poll_handle,
152*d83cc019SAndroid Build Coastguard Worker 						   0, 4096,
153*d83cc019SAndroid Build Coastguard Worker 						   PROT_READ | PROT_WRITE);
154*d83cc019SAndroid Build Coastguard Worker 		else
155*d83cc019SAndroid Build Coastguard Worker 			spin->poll = gem_mmap__wc(fd, spin->poll_handle,
156*d83cc019SAndroid Build Coastguard Worker 						  0, 4096,
157*d83cc019SAndroid Build Coastguard Worker 						  PROT_READ | PROT_WRITE);
158*d83cc019SAndroid Build Coastguard Worker 
159*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(spin->poll[SPIN_POLL_START_IDX], 0);
160*d83cc019SAndroid Build Coastguard Worker 
161*d83cc019SAndroid Build Coastguard Worker 		/* batch is first */
162*d83cc019SAndroid Build Coastguard Worker 		r->presumed_offset = 4096;
163*d83cc019SAndroid Build Coastguard Worker 		r->target_handle = obj[SCRATCH].handle;
164*d83cc019SAndroid Build Coastguard Worker 		r->offset = sizeof(uint32_t) * 1;
165*d83cc019SAndroid Build Coastguard Worker 		r->delta = sizeof(uint32_t) * SPIN_POLL_START_IDX;
166*d83cc019SAndroid Build Coastguard Worker 
167*d83cc019SAndroid Build Coastguard Worker 		*cs++ = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
168*d83cc019SAndroid Build Coastguard Worker 
169*d83cc019SAndroid Build Coastguard Worker 		if (gen >= 8) {
170*d83cc019SAndroid Build Coastguard Worker 			*cs++ = r->presumed_offset + r->delta;
171*d83cc019SAndroid Build Coastguard Worker 			*cs++ = 0;
172*d83cc019SAndroid Build Coastguard Worker 		} else if (gen >= 4) {
173*d83cc019SAndroid Build Coastguard Worker 			*cs++ = 0;
174*d83cc019SAndroid Build Coastguard Worker 			*cs++ = r->presumed_offset + r->delta;
175*d83cc019SAndroid Build Coastguard Worker 			r->offset += sizeof(uint32_t);
176*d83cc019SAndroid Build Coastguard Worker 		} else {
177*d83cc019SAndroid Build Coastguard Worker 			cs[-1]--;
178*d83cc019SAndroid Build Coastguard Worker 			*cs++ = r->presumed_offset + r->delta;
179*d83cc019SAndroid Build Coastguard Worker 		}
180*d83cc019SAndroid Build Coastguard Worker 
181*d83cc019SAndroid Build Coastguard Worker 		*cs++ = 1;
182*d83cc019SAndroid Build Coastguard Worker 
183*d83cc019SAndroid Build Coastguard Worker 		execbuf->buffer_count++;
184*d83cc019SAndroid Build Coastguard Worker 	}
185*d83cc019SAndroid Build Coastguard Worker 
186*d83cc019SAndroid Build Coastguard Worker 	spin->handle = obj[BATCH].handle;
187*d83cc019SAndroid Build Coastguard Worker 
188*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lt(cs - batch, LOOP_START_OFFSET / sizeof(*cs));
189*d83cc019SAndroid Build Coastguard Worker 	spin->condition = batch + LOOP_START_OFFSET / sizeof(*cs);
190*d83cc019SAndroid Build Coastguard Worker 	cs = spin->condition;
191*d83cc019SAndroid Build Coastguard Worker 
192*d83cc019SAndroid Build Coastguard Worker 	/* Allow ourselves to be preempted */
193*d83cc019SAndroid Build Coastguard Worker 	if (!(opts->flags & IGT_SPIN_NO_PREEMPTION))
194*d83cc019SAndroid Build Coastguard Worker 		*cs++ = MI_ARB_CHK;
195*d83cc019SAndroid Build Coastguard Worker 
196*d83cc019SAndroid Build Coastguard Worker 	/* Pad with a few nops so that we do not completely hog the system.
197*d83cc019SAndroid Build Coastguard Worker 	 *
198*d83cc019SAndroid Build Coastguard Worker 	 * Part of the attraction of using a recursive batch is that it is
199*d83cc019SAndroid Build Coastguard Worker 	 * hard on the system (executing the "function" call is apparently
200*d83cc019SAndroid Build Coastguard Worker 	 * quite expensive). However, the GPU may hog the entire system for
201*d83cc019SAndroid Build Coastguard Worker 	 * a few minutes, preventing even NMI. Quite why this is so is unclear,
202*d83cc019SAndroid Build Coastguard Worker 	 * but presumably it relates to the PM_INTRMSK workaround on gen6/gen7.
203*d83cc019SAndroid Build Coastguard Worker 	 * If we give the system a break by having the GPU execute a few nops
204*d83cc019SAndroid Build Coastguard Worker 	 * between function calls, that appears enough to keep SNB out of
205*d83cc019SAndroid Build Coastguard Worker 	 * trouble. See https://bugs.freedesktop.org/show_bug.cgi?id=102262
206*d83cc019SAndroid Build Coastguard Worker 	 */
207*d83cc019SAndroid Build Coastguard Worker 	if (!(opts->flags & IGT_SPIN_FAST))
208*d83cc019SAndroid Build Coastguard Worker 		cs += 1000;
209*d83cc019SAndroid Build Coastguard Worker 
210*d83cc019SAndroid Build Coastguard Worker 	/* recurse */
211*d83cc019SAndroid Build Coastguard Worker 	r = &relocs[obj[BATCH].relocation_count++];
212*d83cc019SAndroid Build Coastguard Worker 	r->target_handle = obj[BATCH].handle;
213*d83cc019SAndroid Build Coastguard Worker 	r->offset = (cs + 1 - batch) * sizeof(*cs);
214*d83cc019SAndroid Build Coastguard Worker 	r->read_domains = I915_GEM_DOMAIN_COMMAND;
215*d83cc019SAndroid Build Coastguard Worker 	r->delta = LOOP_START_OFFSET;
216*d83cc019SAndroid Build Coastguard Worker 	if (gen >= 8) {
217*d83cc019SAndroid Build Coastguard Worker 		*cs++ = MI_BATCH_BUFFER_START | 1 << 8 | 1;
218*d83cc019SAndroid Build Coastguard Worker 		*cs++ = r->delta;
219*d83cc019SAndroid Build Coastguard Worker 		*cs++ = 0;
220*d83cc019SAndroid Build Coastguard Worker 	} else if (gen >= 6) {
221*d83cc019SAndroid Build Coastguard Worker 		*cs++ = MI_BATCH_BUFFER_START | 1 << 8;
222*d83cc019SAndroid Build Coastguard Worker 		*cs++ = r->delta;
223*d83cc019SAndroid Build Coastguard Worker 	} else {
224*d83cc019SAndroid Build Coastguard Worker 		*cs++ = MI_BATCH_BUFFER_START | 2 << 6;
225*d83cc019SAndroid Build Coastguard Worker 		if (gen < 4)
226*d83cc019SAndroid Build Coastguard Worker 			r->delta |= 1;
227*d83cc019SAndroid Build Coastguard Worker 		*cs = r->delta;
228*d83cc019SAndroid Build Coastguard Worker 		cs++;
229*d83cc019SAndroid Build Coastguard Worker 	}
230*d83cc019SAndroid Build Coastguard Worker 	obj[BATCH].relocs_ptr = to_user_pointer(relocs);
231*d83cc019SAndroid Build Coastguard Worker 
232*d83cc019SAndroid Build Coastguard Worker 	execbuf->buffers_ptr = to_user_pointer(obj +
233*d83cc019SAndroid Build Coastguard Worker 					       (2 - execbuf->buffer_count));
234*d83cc019SAndroid Build Coastguard Worker 	execbuf->rsvd1 = opts->ctx;
235*d83cc019SAndroid Build Coastguard Worker 
236*d83cc019SAndroid Build Coastguard Worker 	if (opts->flags & IGT_SPIN_FENCE_OUT)
237*d83cc019SAndroid Build Coastguard Worker 		execbuf->flags |= I915_EXEC_FENCE_OUT;
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < nengine; i++) {
240*d83cc019SAndroid Build Coastguard Worker 		execbuf->flags &= ~ENGINE_MASK;
241*d83cc019SAndroid Build Coastguard Worker 		execbuf->flags |= flags[i];
242*d83cc019SAndroid Build Coastguard Worker 
243*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf_wr(fd, execbuf);
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 		if (opts->flags & IGT_SPIN_FENCE_OUT) {
246*d83cc019SAndroid Build Coastguard Worker 			int _fd = execbuf->rsvd2 >> 32;
247*d83cc019SAndroid Build Coastguard Worker 
248*d83cc019SAndroid Build Coastguard Worker 			igt_assert(_fd >= 0);
249*d83cc019SAndroid Build Coastguard Worker 			if (fence_fd == -1) {
250*d83cc019SAndroid Build Coastguard Worker 				fence_fd = _fd;
251*d83cc019SAndroid Build Coastguard Worker 			} else {
252*d83cc019SAndroid Build Coastguard Worker 				int old_fd = fence_fd;
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 				fence_fd = sync_fence_merge(old_fd, _fd);
255*d83cc019SAndroid Build Coastguard Worker 				close(old_fd);
256*d83cc019SAndroid Build Coastguard Worker 				close(_fd);
257*d83cc019SAndroid Build Coastguard Worker 			}
258*d83cc019SAndroid Build Coastguard Worker 			igt_assert(fence_fd >= 0);
259*d83cc019SAndroid Build Coastguard Worker 		}
260*d83cc019SAndroid Build Coastguard Worker 	}
261*d83cc019SAndroid Build Coastguard Worker 
262*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lt(cs - batch, BATCH_SIZE / sizeof(*cs));
263*d83cc019SAndroid Build Coastguard Worker 
264*d83cc019SAndroid Build Coastguard Worker 	/* Make it easier for callers to resubmit. */
265*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(spin->obj); i++) {
266*d83cc019SAndroid Build Coastguard Worker 		spin->obj[i].relocation_count = 0;
267*d83cc019SAndroid Build Coastguard Worker 		spin->obj[i].relocs_ptr = 0;
268*d83cc019SAndroid Build Coastguard Worker 		spin->obj[i].flags = EXEC_OBJECT_PINNED;
269*d83cc019SAndroid Build Coastguard Worker 	}
270*d83cc019SAndroid Build Coastguard Worker 
271*d83cc019SAndroid Build Coastguard Worker 	spin->cmd_precondition = *spin->condition;
272*d83cc019SAndroid Build Coastguard Worker 
273*d83cc019SAndroid Build Coastguard Worker 	return fence_fd;
274*d83cc019SAndroid Build Coastguard Worker }
275*d83cc019SAndroid Build Coastguard Worker 
276*d83cc019SAndroid Build Coastguard Worker static igt_spin_t *
spin_create(int fd,const struct igt_spin_factory * opts)277*d83cc019SAndroid Build Coastguard Worker spin_create(int fd, const struct igt_spin_factory *opts)
278*d83cc019SAndroid Build Coastguard Worker {
279*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
280*d83cc019SAndroid Build Coastguard Worker 
281*d83cc019SAndroid Build Coastguard Worker 	spin = calloc(1, sizeof(struct igt_spin));
282*d83cc019SAndroid Build Coastguard Worker 	igt_assert(spin);
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker 	spin->out_fence = emit_recursive_batch(spin, fd, opts);
285*d83cc019SAndroid Build Coastguard Worker 
286*d83cc019SAndroid Build Coastguard Worker 	pthread_mutex_lock(&list_lock);
287*d83cc019SAndroid Build Coastguard Worker 	igt_list_add(&spin->link, &spin_list);
288*d83cc019SAndroid Build Coastguard Worker 	pthread_mutex_unlock(&list_lock);
289*d83cc019SAndroid Build Coastguard Worker 
290*d83cc019SAndroid Build Coastguard Worker 	return spin;
291*d83cc019SAndroid Build Coastguard Worker }
292*d83cc019SAndroid Build Coastguard Worker 
293*d83cc019SAndroid Build Coastguard Worker igt_spin_t *
__igt_spin_factory(int fd,const struct igt_spin_factory * opts)294*d83cc019SAndroid Build Coastguard Worker __igt_spin_factory(int fd, const struct igt_spin_factory *opts)
295*d83cc019SAndroid Build Coastguard Worker {
296*d83cc019SAndroid Build Coastguard Worker 	return spin_create(fd, opts);
297*d83cc019SAndroid Build Coastguard Worker }
298*d83cc019SAndroid Build Coastguard Worker 
299*d83cc019SAndroid Build Coastguard Worker /**
300*d83cc019SAndroid Build Coastguard Worker  * igt_spin_factory:
301*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
302*d83cc019SAndroid Build Coastguard Worker  * @opts: controlling options such as context, engine, dependencies etc
303*d83cc019SAndroid Build Coastguard Worker  *
304*d83cc019SAndroid Build Coastguard Worker  * Start a recursive batch on a ring. Immediately returns a #igt_spin_t that
305*d83cc019SAndroid Build Coastguard Worker  * contains the batch's handle that can be waited upon. The returned structure
306*d83cc019SAndroid Build Coastguard Worker  * must be passed to igt_spin_free() for post-processing.
307*d83cc019SAndroid Build Coastguard Worker  *
308*d83cc019SAndroid Build Coastguard Worker  * Returns:
309*d83cc019SAndroid Build Coastguard Worker  * Structure with helper internal state for igt_spin_free().
310*d83cc019SAndroid Build Coastguard Worker  */
311*d83cc019SAndroid Build Coastguard Worker igt_spin_t *
igt_spin_factory(int fd,const struct igt_spin_factory * opts)312*d83cc019SAndroid Build Coastguard Worker igt_spin_factory(int fd, const struct igt_spin_factory *opts)
313*d83cc019SAndroid Build Coastguard Worker {
314*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
315*d83cc019SAndroid Build Coastguard Worker 
316*d83cc019SAndroid Build Coastguard Worker 	igt_require_gem(fd);
317*d83cc019SAndroid Build Coastguard Worker 
318*d83cc019SAndroid Build Coastguard Worker 	if (opts->engine != ALL_ENGINES) {
319*d83cc019SAndroid Build Coastguard Worker 		struct intel_execution_engine2 e;
320*d83cc019SAndroid Build Coastguard Worker 		int class;
321*d83cc019SAndroid Build Coastguard Worker 
322*d83cc019SAndroid Build Coastguard Worker 		if (!gem_context_lookup_engine(fd, opts->engine,
323*d83cc019SAndroid Build Coastguard Worker 					       opts->ctx, &e)) {
324*d83cc019SAndroid Build Coastguard Worker 			class = e.engine_class;
325*d83cc019SAndroid Build Coastguard Worker 		} else {
326*d83cc019SAndroid Build Coastguard Worker 			gem_require_ring(fd, opts->engine);
327*d83cc019SAndroid Build Coastguard Worker 			class = gem_execbuf_flags_to_engine_class(opts->engine);
328*d83cc019SAndroid Build Coastguard Worker 		}
329*d83cc019SAndroid Build Coastguard Worker 
330*d83cc019SAndroid Build Coastguard Worker 		if (opts->flags & IGT_SPIN_POLL_RUN)
331*d83cc019SAndroid Build Coastguard Worker 			igt_require(gem_class_can_store_dword(fd, class));
332*d83cc019SAndroid Build Coastguard Worker 	}
333*d83cc019SAndroid Build Coastguard Worker 
334*d83cc019SAndroid Build Coastguard Worker 	spin = spin_create(fd, opts);
335*d83cc019SAndroid Build Coastguard Worker 
336*d83cc019SAndroid Build Coastguard Worker 	igt_assert(gem_bo_busy(fd, spin->handle));
337*d83cc019SAndroid Build Coastguard Worker 	if (opts->flags & IGT_SPIN_FENCE_OUT) {
338*d83cc019SAndroid Build Coastguard Worker 		struct pollfd pfd = { spin->out_fence, POLLIN };
339*d83cc019SAndroid Build Coastguard Worker 
340*d83cc019SAndroid Build Coastguard Worker 		igt_assert(poll(&pfd, 1, 0) == 0);
341*d83cc019SAndroid Build Coastguard Worker 	}
342*d83cc019SAndroid Build Coastguard Worker 
343*d83cc019SAndroid Build Coastguard Worker 	return spin;
344*d83cc019SAndroid Build Coastguard Worker }
345*d83cc019SAndroid Build Coastguard Worker 
notify(union sigval arg)346*d83cc019SAndroid Build Coastguard Worker static void notify(union sigval arg)
347*d83cc019SAndroid Build Coastguard Worker {
348*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = arg.sival_ptr;
349*d83cc019SAndroid Build Coastguard Worker 
350*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(spin);
351*d83cc019SAndroid Build Coastguard Worker }
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker /**
354*d83cc019SAndroid Build Coastguard Worker  * igt_spin_set_timeout:
355*d83cc019SAndroid Build Coastguard Worker  * @spin: spin state from igt_spin_new()
356*d83cc019SAndroid Build Coastguard Worker  * @ns: amount of time in nanoseconds the batch continues to execute
357*d83cc019SAndroid Build Coastguard Worker  *      before finishing.
358*d83cc019SAndroid Build Coastguard Worker  *
359*d83cc019SAndroid Build Coastguard Worker  * Specify a timeout. This ends the recursive batch associated with @spin after
360*d83cc019SAndroid Build Coastguard Worker  * the timeout has elapsed.
361*d83cc019SAndroid Build Coastguard Worker  */
igt_spin_set_timeout(igt_spin_t * spin,int64_t ns)362*d83cc019SAndroid Build Coastguard Worker void igt_spin_set_timeout(igt_spin_t *spin, int64_t ns)
363*d83cc019SAndroid Build Coastguard Worker {
364*d83cc019SAndroid Build Coastguard Worker 	timer_t timer;
365*d83cc019SAndroid Build Coastguard Worker 	struct sigevent sev;
366*d83cc019SAndroid Build Coastguard Worker 	struct itimerspec its;
367*d83cc019SAndroid Build Coastguard Worker 
368*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ns > 0);
369*d83cc019SAndroid Build Coastguard Worker 	if (!spin)
370*d83cc019SAndroid Build Coastguard Worker 		return;
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!spin->timer);
373*d83cc019SAndroid Build Coastguard Worker 
374*d83cc019SAndroid Build Coastguard Worker 	memset(&sev, 0, sizeof(sev));
375*d83cc019SAndroid Build Coastguard Worker 	sev.sigev_notify = SIGEV_THREAD;
376*d83cc019SAndroid Build Coastguard Worker 	sev.sigev_value.sival_ptr = spin;
377*d83cc019SAndroid Build Coastguard Worker 	sev.sigev_notify_function = notify;
378*d83cc019SAndroid Build Coastguard Worker 	igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
379*d83cc019SAndroid Build Coastguard Worker 	igt_assert(timer);
380*d83cc019SAndroid Build Coastguard Worker 
381*d83cc019SAndroid Build Coastguard Worker 	memset(&its, 0, sizeof(its));
382*d83cc019SAndroid Build Coastguard Worker 	its.it_value.tv_sec = ns / NSEC_PER_SEC;
383*d83cc019SAndroid Build Coastguard Worker 	its.it_value.tv_nsec = ns % NSEC_PER_SEC;
384*d83cc019SAndroid Build Coastguard Worker 	igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
385*d83cc019SAndroid Build Coastguard Worker 
386*d83cc019SAndroid Build Coastguard Worker 	spin->timer = timer;
387*d83cc019SAndroid Build Coastguard Worker }
388*d83cc019SAndroid Build Coastguard Worker 
389*d83cc019SAndroid Build Coastguard Worker /**
390*d83cc019SAndroid Build Coastguard Worker  * igt_spin_reset:
391*d83cc019SAndroid Build Coastguard Worker  * @spin: spin state from igt_spin_new()
392*d83cc019SAndroid Build Coastguard Worker  *
393*d83cc019SAndroid Build Coastguard Worker  * Reset the state of spin, allowing its reuse.
394*d83cc019SAndroid Build Coastguard Worker  */
igt_spin_reset(igt_spin_t * spin)395*d83cc019SAndroid Build Coastguard Worker void igt_spin_reset(igt_spin_t *spin)
396*d83cc019SAndroid Build Coastguard Worker {
397*d83cc019SAndroid Build Coastguard Worker 	if (igt_spin_has_poll(spin))
398*d83cc019SAndroid Build Coastguard Worker 		spin->poll[SPIN_POLL_START_IDX] = 0;
399*d83cc019SAndroid Build Coastguard Worker 
400*d83cc019SAndroid Build Coastguard Worker 	*spin->condition = spin->cmd_precondition;
401*d83cc019SAndroid Build Coastguard Worker 	__sync_synchronize();
402*d83cc019SAndroid Build Coastguard Worker }
403*d83cc019SAndroid Build Coastguard Worker 
404*d83cc019SAndroid Build Coastguard Worker /**
405*d83cc019SAndroid Build Coastguard Worker  * igt_spin_end:
406*d83cc019SAndroid Build Coastguard Worker  * @spin: spin state from igt_spin_new()
407*d83cc019SAndroid Build Coastguard Worker  *
408*d83cc019SAndroid Build Coastguard Worker  * End the spinner associated with @spin manually.
409*d83cc019SAndroid Build Coastguard Worker  */
igt_spin_end(igt_spin_t * spin)410*d83cc019SAndroid Build Coastguard Worker void igt_spin_end(igt_spin_t *spin)
411*d83cc019SAndroid Build Coastguard Worker {
412*d83cc019SAndroid Build Coastguard Worker 	if (!spin)
413*d83cc019SAndroid Build Coastguard Worker 		return;
414*d83cc019SAndroid Build Coastguard Worker 
415*d83cc019SAndroid Build Coastguard Worker 	*spin->condition = MI_BATCH_BUFFER_END;
416*d83cc019SAndroid Build Coastguard Worker 	__sync_synchronize();
417*d83cc019SAndroid Build Coastguard Worker }
418*d83cc019SAndroid Build Coastguard Worker 
419*d83cc019SAndroid Build Coastguard Worker /**
420*d83cc019SAndroid Build Coastguard Worker  * igt_spin_free:
421*d83cc019SAndroid Build Coastguard Worker  * @fd: open i915 drm file descriptor
422*d83cc019SAndroid Build Coastguard Worker  * @spin: spin state from igt_spin_new()
423*d83cc019SAndroid Build Coastguard Worker  *
424*d83cc019SAndroid Build Coastguard Worker  * This function does the necessary post-processing after starting a
425*d83cc019SAndroid Build Coastguard Worker  * spin with igt_spin_new() and then frees it.
426*d83cc019SAndroid Build Coastguard Worker  */
igt_spin_free(int fd,igt_spin_t * spin)427*d83cc019SAndroid Build Coastguard Worker void igt_spin_free(int fd, igt_spin_t *spin)
428*d83cc019SAndroid Build Coastguard Worker {
429*d83cc019SAndroid Build Coastguard Worker 	if (!spin)
430*d83cc019SAndroid Build Coastguard Worker 		return;
431*d83cc019SAndroid Build Coastguard Worker 
432*d83cc019SAndroid Build Coastguard Worker 	pthread_mutex_lock(&list_lock);
433*d83cc019SAndroid Build Coastguard Worker 	igt_list_del(&spin->link);
434*d83cc019SAndroid Build Coastguard Worker 	pthread_mutex_unlock(&list_lock);
435*d83cc019SAndroid Build Coastguard Worker 
436*d83cc019SAndroid Build Coastguard Worker 	if (spin->timer)
437*d83cc019SAndroid Build Coastguard Worker 		timer_delete(spin->timer);
438*d83cc019SAndroid Build Coastguard Worker 
439*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(spin);
440*d83cc019SAndroid Build Coastguard Worker 	gem_munmap((void *)((unsigned long)spin->condition & (~4095UL)),
441*d83cc019SAndroid Build Coastguard Worker 		   BATCH_SIZE);
442*d83cc019SAndroid Build Coastguard Worker 
443*d83cc019SAndroid Build Coastguard Worker 	if (spin->poll) {
444*d83cc019SAndroid Build Coastguard Worker 		gem_munmap(spin->poll, 4096);
445*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, spin->poll_handle);
446*d83cc019SAndroid Build Coastguard Worker 	}
447*d83cc019SAndroid Build Coastguard Worker 
448*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, spin->handle);
449*d83cc019SAndroid Build Coastguard Worker 
450*d83cc019SAndroid Build Coastguard Worker 	if (spin->out_fence >= 0)
451*d83cc019SAndroid Build Coastguard Worker 		close(spin->out_fence);
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker 	free(spin);
454*d83cc019SAndroid Build Coastguard Worker }
455*d83cc019SAndroid Build Coastguard Worker 
igt_terminate_spins(void)456*d83cc019SAndroid Build Coastguard Worker void igt_terminate_spins(void)
457*d83cc019SAndroid Build Coastguard Worker {
458*d83cc019SAndroid Build Coastguard Worker 	struct igt_spin *iter;
459*d83cc019SAndroid Build Coastguard Worker 
460*d83cc019SAndroid Build Coastguard Worker 	pthread_mutex_lock(&list_lock);
461*d83cc019SAndroid Build Coastguard Worker 	igt_list_for_each(iter, &spin_list, link)
462*d83cc019SAndroid Build Coastguard Worker 		igt_spin_end(iter);
463*d83cc019SAndroid Build Coastguard Worker 	pthread_mutex_unlock(&list_lock);
464*d83cc019SAndroid Build Coastguard Worker }
465*d83cc019SAndroid Build Coastguard Worker 
igt_unshare_spins(void)466*d83cc019SAndroid Build Coastguard Worker void igt_unshare_spins(void)
467*d83cc019SAndroid Build Coastguard Worker {
468*d83cc019SAndroid Build Coastguard Worker 	struct igt_spin *it, *n;
469*d83cc019SAndroid Build Coastguard Worker 
470*d83cc019SAndroid Build Coastguard Worker 	/* Disable the automatic termination on inherited spinners */
471*d83cc019SAndroid Build Coastguard Worker 	igt_list_for_each_safe(it, n, &spin_list, link)
472*d83cc019SAndroid Build Coastguard Worker 		igt_list_init(&it->link);
473*d83cc019SAndroid Build Coastguard Worker 	igt_list_init(&spin_list);
474*d83cc019SAndroid Build Coastguard Worker }
475*d83cc019SAndroid Build Coastguard Worker 
plug_vgem_handle(struct igt_cork * cork,int fd)476*d83cc019SAndroid Build Coastguard Worker static uint32_t plug_vgem_handle(struct igt_cork *cork, int fd)
477*d83cc019SAndroid Build Coastguard Worker {
478*d83cc019SAndroid Build Coastguard Worker 	struct vgem_bo bo;
479*d83cc019SAndroid Build Coastguard Worker 	int dmabuf;
480*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
481*d83cc019SAndroid Build Coastguard Worker 
482*d83cc019SAndroid Build Coastguard Worker 	cork->vgem.device = drm_open_driver(DRIVER_VGEM);
483*d83cc019SAndroid Build Coastguard Worker 	igt_require(vgem_has_fences(cork->vgem.device));
484*d83cc019SAndroid Build Coastguard Worker 
485*d83cc019SAndroid Build Coastguard Worker 	bo.width = bo.height = 1;
486*d83cc019SAndroid Build Coastguard Worker 	bo.bpp = 4;
487*d83cc019SAndroid Build Coastguard Worker 	vgem_create(cork->vgem.device, &bo);
488*d83cc019SAndroid Build Coastguard Worker 	cork->vgem.fence = vgem_fence_attach(cork->vgem.device, &bo, VGEM_FENCE_WRITE);
489*d83cc019SAndroid Build Coastguard Worker 
490*d83cc019SAndroid Build Coastguard Worker 	dmabuf = prime_handle_to_fd(cork->vgem.device, bo.handle);
491*d83cc019SAndroid Build Coastguard Worker 	handle = prime_fd_to_handle(fd, dmabuf);
492*d83cc019SAndroid Build Coastguard Worker 	close(dmabuf);
493*d83cc019SAndroid Build Coastguard Worker 
494*d83cc019SAndroid Build Coastguard Worker 	return handle;
495*d83cc019SAndroid Build Coastguard Worker }
496*d83cc019SAndroid Build Coastguard Worker 
unplug_vgem_handle(struct igt_cork * cork)497*d83cc019SAndroid Build Coastguard Worker static void unplug_vgem_handle(struct igt_cork *cork)
498*d83cc019SAndroid Build Coastguard Worker {
499*d83cc019SAndroid Build Coastguard Worker 	vgem_fence_signal(cork->vgem.device, cork->vgem.fence);
500*d83cc019SAndroid Build Coastguard Worker 	close(cork->vgem.device);
501*d83cc019SAndroid Build Coastguard Worker }
502*d83cc019SAndroid Build Coastguard Worker 
plug_sync_fd(struct igt_cork * cork)503*d83cc019SAndroid Build Coastguard Worker static uint32_t plug_sync_fd(struct igt_cork *cork)
504*d83cc019SAndroid Build Coastguard Worker {
505*d83cc019SAndroid Build Coastguard Worker 	int fence;
506*d83cc019SAndroid Build Coastguard Worker 
507*d83cc019SAndroid Build Coastguard Worker 	igt_require_sw_sync();
508*d83cc019SAndroid Build Coastguard Worker 
509*d83cc019SAndroid Build Coastguard Worker 	cork->sw_sync.timeline = sw_sync_timeline_create();
510*d83cc019SAndroid Build Coastguard Worker 	fence = sw_sync_timeline_create_fence(cork->sw_sync.timeline, 1);
511*d83cc019SAndroid Build Coastguard Worker 
512*d83cc019SAndroid Build Coastguard Worker 	return fence;
513*d83cc019SAndroid Build Coastguard Worker }
514*d83cc019SAndroid Build Coastguard Worker 
unplug_sync_fd(struct igt_cork * cork)515*d83cc019SAndroid Build Coastguard Worker static void unplug_sync_fd(struct igt_cork *cork)
516*d83cc019SAndroid Build Coastguard Worker {
517*d83cc019SAndroid Build Coastguard Worker 	sw_sync_timeline_inc(cork->sw_sync.timeline, 1);
518*d83cc019SAndroid Build Coastguard Worker 	close(cork->sw_sync.timeline);
519*d83cc019SAndroid Build Coastguard Worker }
520*d83cc019SAndroid Build Coastguard Worker 
521*d83cc019SAndroid Build Coastguard Worker /**
522*d83cc019SAndroid Build Coastguard Worker  * igt_cork_plug:
523*d83cc019SAndroid Build Coastguard Worker  * @fd: open drm file descriptor
524*d83cc019SAndroid Build Coastguard Worker  * @method: method to utilize for corking.
525*d83cc019SAndroid Build Coastguard Worker  * @cork: structure that will be filled with the state of the cork bo.
526*d83cc019SAndroid Build Coastguard Worker  * Note: this has to match the corking method.
527*d83cc019SAndroid Build Coastguard Worker  *
528*d83cc019SAndroid Build Coastguard Worker  * This function provides a mechanism to stall submission. It provides two
529*d83cc019SAndroid Build Coastguard Worker  * blocking methods:
530*d83cc019SAndroid Build Coastguard Worker  *
531*d83cc019SAndroid Build Coastguard Worker  * VGEM_BO.
532*d83cc019SAndroid Build Coastguard Worker  * Imports a vgem bo with a fence attached to it. This bo can be used as a
533*d83cc019SAndroid Build Coastguard Worker  * dependency during submission to stall execution until the fence is signaled.
534*d83cc019SAndroid Build Coastguard Worker  *
535*d83cc019SAndroid Build Coastguard Worker  * SW_SYNC:
536*d83cc019SAndroid Build Coastguard Worker  * Creates a timeline and then a fence on that timeline. The fence can be used
537*d83cc019SAndroid Build Coastguard Worker  * as an input fence to a request, the request will be stalled until the fence
538*d83cc019SAndroid Build Coastguard Worker  * is signaled.
539*d83cc019SAndroid Build Coastguard Worker  *
540*d83cc019SAndroid Build Coastguard Worker  * The parameters required to unblock the execution and to cleanup are stored in
541*d83cc019SAndroid Build Coastguard Worker  * the provided cork structure.
542*d83cc019SAndroid Build Coastguard Worker  *
543*d83cc019SAndroid Build Coastguard Worker  * Returns:
544*d83cc019SAndroid Build Coastguard Worker  * Handle of the imported BO / Sw sync fence FD.
545*d83cc019SAndroid Build Coastguard Worker  */
igt_cork_plug(struct igt_cork * cork,int fd)546*d83cc019SAndroid Build Coastguard Worker uint32_t igt_cork_plug(struct igt_cork *cork, int fd)
547*d83cc019SAndroid Build Coastguard Worker {
548*d83cc019SAndroid Build Coastguard Worker 	igt_assert(cork->fd == -1);
549*d83cc019SAndroid Build Coastguard Worker 
550*d83cc019SAndroid Build Coastguard Worker 	switch (cork->type) {
551*d83cc019SAndroid Build Coastguard Worker 	case CORK_SYNC_FD:
552*d83cc019SAndroid Build Coastguard Worker 		return plug_sync_fd(cork);
553*d83cc019SAndroid Build Coastguard Worker 
554*d83cc019SAndroid Build Coastguard Worker 	case CORK_VGEM_HANDLE:
555*d83cc019SAndroid Build Coastguard Worker 		return plug_vgem_handle(cork, fd);
556*d83cc019SAndroid Build Coastguard Worker 
557*d83cc019SAndroid Build Coastguard Worker 	default:
558*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(0, "Invalid cork type!\n");
559*d83cc019SAndroid Build Coastguard Worker 		return 0;
560*d83cc019SAndroid Build Coastguard Worker 	}
561*d83cc019SAndroid Build Coastguard Worker }
562*d83cc019SAndroid Build Coastguard Worker 
563*d83cc019SAndroid Build Coastguard Worker /**
564*d83cc019SAndroid Build Coastguard Worker  * igt_cork_unplug:
565*d83cc019SAndroid Build Coastguard Worker  * @method: method to utilize for corking.
566*d83cc019SAndroid Build Coastguard Worker  * @cork: cork state from igt_cork_plug()
567*d83cc019SAndroid Build Coastguard Worker  *
568*d83cc019SAndroid Build Coastguard Worker  * This function unblocks the execution by signaling the fence attached to the
569*d83cc019SAndroid Build Coastguard Worker  * imported bo and does the necessary post-processing.
570*d83cc019SAndroid Build Coastguard Worker  *
571*d83cc019SAndroid Build Coastguard Worker  * NOTE: the handle returned by igt_cork_plug is not closed during this phase.
572*d83cc019SAndroid Build Coastguard Worker  */
igt_cork_unplug(struct igt_cork * cork)573*d83cc019SAndroid Build Coastguard Worker void igt_cork_unplug(struct igt_cork *cork)
574*d83cc019SAndroid Build Coastguard Worker {
575*d83cc019SAndroid Build Coastguard Worker 	igt_assert(cork->fd != -1);
576*d83cc019SAndroid Build Coastguard Worker 
577*d83cc019SAndroid Build Coastguard Worker 	switch (cork->type) {
578*d83cc019SAndroid Build Coastguard Worker 	case CORK_SYNC_FD:
579*d83cc019SAndroid Build Coastguard Worker 		unplug_sync_fd(cork);
580*d83cc019SAndroid Build Coastguard Worker 		break;
581*d83cc019SAndroid Build Coastguard Worker 
582*d83cc019SAndroid Build Coastguard Worker 	case CORK_VGEM_HANDLE:
583*d83cc019SAndroid Build Coastguard Worker 		unplug_vgem_handle(cork);
584*d83cc019SAndroid Build Coastguard Worker 		break;
585*d83cc019SAndroid Build Coastguard Worker 
586*d83cc019SAndroid Build Coastguard Worker 	default:
587*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(0, "Invalid cork type!\n");
588*d83cc019SAndroid Build Coastguard Worker 	}
589*d83cc019SAndroid Build Coastguard Worker 
590*d83cc019SAndroid Build Coastguard Worker 	cork->fd = -1; /* Reset cork */
591*d83cc019SAndroid Build Coastguard Worker }
592