xref: /aosp_15_r20/external/igt-gpu-tools/tests/perf_pmu.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2017 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 <stdlib.h>
26*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
27*d83cc019SAndroid Build Coastguard Worker #include <string.h>
28*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
29*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
30*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
31*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
32*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
33*d83cc019SAndroid Build Coastguard Worker #include <sys/times.h>
34*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
35*d83cc019SAndroid Build Coastguard Worker #include <dirent.h>
36*d83cc019SAndroid Build Coastguard Worker #include <time.h>
37*d83cc019SAndroid Build Coastguard Worker #include <poll.h>
38*d83cc019SAndroid Build Coastguard Worker #include <sched.h>
39*d83cc019SAndroid Build Coastguard Worker 
40*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
41*d83cc019SAndroid Build Coastguard Worker #include "igt_core.h"
42*d83cc019SAndroid Build Coastguard Worker #include "igt_perf.h"
43*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
44*d83cc019SAndroid Build Coastguard Worker #include "igt_pm.h"
45*d83cc019SAndroid Build Coastguard Worker #include "sw_sync.h"
46*d83cc019SAndroid Build Coastguard Worker 
47*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Test the i915 pmu perf interface");
48*d83cc019SAndroid Build Coastguard Worker 
49*d83cc019SAndroid Build Coastguard Worker const double tolerance = 0.05f;
50*d83cc019SAndroid Build Coastguard Worker const unsigned long batch_duration_ns = 500e6;
51*d83cc019SAndroid Build Coastguard Worker 
open_pmu(uint64_t config)52*d83cc019SAndroid Build Coastguard Worker static int open_pmu(uint64_t config)
53*d83cc019SAndroid Build Coastguard Worker {
54*d83cc019SAndroid Build Coastguard Worker 	int fd;
55*d83cc019SAndroid Build Coastguard Worker 
56*d83cc019SAndroid Build Coastguard Worker 	fd = perf_i915_open(config);
57*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on(fd < 0 && errno == ENODEV);
58*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fd >= 0);
59*d83cc019SAndroid Build Coastguard Worker 
60*d83cc019SAndroid Build Coastguard Worker 	return fd;
61*d83cc019SAndroid Build Coastguard Worker }
62*d83cc019SAndroid Build Coastguard Worker 
open_group(uint64_t config,int group)63*d83cc019SAndroid Build Coastguard Worker static int open_group(uint64_t config, int group)
64*d83cc019SAndroid Build Coastguard Worker {
65*d83cc019SAndroid Build Coastguard Worker 	int fd;
66*d83cc019SAndroid Build Coastguard Worker 
67*d83cc019SAndroid Build Coastguard Worker 	fd = perf_i915_open_group(config, group);
68*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on(fd < 0 && errno == ENODEV);
69*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fd >= 0);
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker 	return fd;
72*d83cc019SAndroid Build Coastguard Worker }
73*d83cc019SAndroid Build Coastguard Worker 
74*d83cc019SAndroid Build Coastguard Worker static void
init(int gem_fd,const struct intel_execution_engine2 * e,uint8_t sample)75*d83cc019SAndroid Build Coastguard Worker init(int gem_fd, const struct intel_execution_engine2 *e, uint8_t sample)
76*d83cc019SAndroid Build Coastguard Worker {
77*d83cc019SAndroid Build Coastguard Worker 	int fd, err = 0;
78*d83cc019SAndroid Build Coastguard Worker 	bool exists;
79*d83cc019SAndroid Build Coastguard Worker 
80*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
81*d83cc019SAndroid Build Coastguard Worker 	fd = perf_i915_open(__I915_PMU_ENGINE(e->class, e->instance, sample));
82*d83cc019SAndroid Build Coastguard Worker 	if (fd < 0)
83*d83cc019SAndroid Build Coastguard Worker 		err = errno;
84*d83cc019SAndroid Build Coastguard Worker 
85*d83cc019SAndroid Build Coastguard Worker 	exists = gem_context_has_engine(gem_fd, 0, e->flags);
86*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(intel_get_drm_devid(gem_fd)) < 6 &&
87*d83cc019SAndroid Build Coastguard Worker 	    sample == I915_SAMPLE_SEMA)
88*d83cc019SAndroid Build Coastguard Worker 		exists = false;
89*d83cc019SAndroid Build Coastguard Worker 
90*d83cc019SAndroid Build Coastguard Worker 	if (exists) {
91*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(err, 0);
92*d83cc019SAndroid Build Coastguard Worker 		igt_assert_fd(fd);
93*d83cc019SAndroid Build Coastguard Worker 		close(fd);
94*d83cc019SAndroid Build Coastguard Worker 	} else {
95*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lt(fd, 0);
96*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(err, ENODEV);
97*d83cc019SAndroid Build Coastguard Worker 	}
98*d83cc019SAndroid Build Coastguard Worker }
99*d83cc019SAndroid Build Coastguard Worker 
__pmu_read_single(int fd,uint64_t * ts)100*d83cc019SAndroid Build Coastguard Worker static uint64_t __pmu_read_single(int fd, uint64_t *ts)
101*d83cc019SAndroid Build Coastguard Worker {
102*d83cc019SAndroid Build Coastguard Worker 	uint64_t data[2];
103*d83cc019SAndroid Build Coastguard Worker 
104*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(read(fd, data, sizeof(data)), sizeof(data));
105*d83cc019SAndroid Build Coastguard Worker 
106*d83cc019SAndroid Build Coastguard Worker 	if (ts)
107*d83cc019SAndroid Build Coastguard Worker 		*ts = data[1];
108*d83cc019SAndroid Build Coastguard Worker 
109*d83cc019SAndroid Build Coastguard Worker 	return data[0];
110*d83cc019SAndroid Build Coastguard Worker }
111*d83cc019SAndroid Build Coastguard Worker 
pmu_read_single(int fd)112*d83cc019SAndroid Build Coastguard Worker static uint64_t pmu_read_single(int fd)
113*d83cc019SAndroid Build Coastguard Worker {
114*d83cc019SAndroid Build Coastguard Worker 	return __pmu_read_single(fd, NULL);
115*d83cc019SAndroid Build Coastguard Worker }
116*d83cc019SAndroid Build Coastguard Worker 
pmu_read_multi(int fd,unsigned int num,uint64_t * val)117*d83cc019SAndroid Build Coastguard Worker static uint64_t pmu_read_multi(int fd, unsigned int num, uint64_t *val)
118*d83cc019SAndroid Build Coastguard Worker {
119*d83cc019SAndroid Build Coastguard Worker 	uint64_t buf[2 + num];
120*d83cc019SAndroid Build Coastguard Worker 	unsigned int i;
121*d83cc019SAndroid Build Coastguard Worker 
122*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(read(fd, buf, sizeof(buf)), sizeof(buf));
123*d83cc019SAndroid Build Coastguard Worker 
124*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num; i++)
125*d83cc019SAndroid Build Coastguard Worker 		val[i] = buf[2 + i];
126*d83cc019SAndroid Build Coastguard Worker 
127*d83cc019SAndroid Build Coastguard Worker 	return buf[1];
128*d83cc019SAndroid Build Coastguard Worker }
129*d83cc019SAndroid Build Coastguard Worker 
130*d83cc019SAndroid Build Coastguard Worker #define __assert_within_epsilon(x, ref, tol_up, tol_down) \
131*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f((double)(x) <= (1.0 + (tol_up)) * (double)(ref) && \
132*d83cc019SAndroid Build Coastguard Worker 		     (double)(x) >= (1.0 - (tol_down)) * (double)(ref), \
133*d83cc019SAndroid Build Coastguard Worker 		     "'%s' != '%s' (%f not within +%f%%/-%f%% tolerance of %f)\n",\
134*d83cc019SAndroid Build Coastguard Worker 		     #x, #ref, (double)(x), \
135*d83cc019SAndroid Build Coastguard Worker 		     (tol_up) * 100.0, (tol_down) * 100.0, \
136*d83cc019SAndroid Build Coastguard Worker 		     (double)(ref))
137*d83cc019SAndroid Build Coastguard Worker 
138*d83cc019SAndroid Build Coastguard Worker #define assert_within_epsilon(x, ref, tolerance) \
139*d83cc019SAndroid Build Coastguard Worker 	__assert_within_epsilon(x, ref, tolerance, tolerance)
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker /*
142*d83cc019SAndroid Build Coastguard Worker  * Helper for cases where we assert on time spent sleeping (directly or
143*d83cc019SAndroid Build Coastguard Worker  * indirectly), so make it more robust by ensuring the system sleep time
144*d83cc019SAndroid Build Coastguard Worker  * is within test tolerance to start with.
145*d83cc019SAndroid Build Coastguard Worker  */
measured_usleep(unsigned int usec)146*d83cc019SAndroid Build Coastguard Worker static unsigned int measured_usleep(unsigned int usec)
147*d83cc019SAndroid Build Coastguard Worker {
148*d83cc019SAndroid Build Coastguard Worker 	struct timespec ts = { };
149*d83cc019SAndroid Build Coastguard Worker 	unsigned int slept;
150*d83cc019SAndroid Build Coastguard Worker 
151*d83cc019SAndroid Build Coastguard Worker 	slept = igt_nsec_elapsed(&ts);
152*d83cc019SAndroid Build Coastguard Worker 	igt_assert(slept == 0);
153*d83cc019SAndroid Build Coastguard Worker 	do {
154*d83cc019SAndroid Build Coastguard Worker 		usleep(usec - slept);
155*d83cc019SAndroid Build Coastguard Worker 		slept = igt_nsec_elapsed(&ts) / 1000;
156*d83cc019SAndroid Build Coastguard Worker 	} while (slept < usec);
157*d83cc019SAndroid Build Coastguard Worker 
158*d83cc019SAndroid Build Coastguard Worker 	return igt_nsec_elapsed(&ts);
159*d83cc019SAndroid Build Coastguard Worker }
160*d83cc019SAndroid Build Coastguard Worker 
161*d83cc019SAndroid Build Coastguard Worker #define TEST_BUSY (1)
162*d83cc019SAndroid Build Coastguard Worker #define FLAG_SYNC (2)
163*d83cc019SAndroid Build Coastguard Worker #define TEST_TRAILING_IDLE (4)
164*d83cc019SAndroid Build Coastguard Worker #define TEST_RUNTIME_PM (8)
165*d83cc019SAndroid Build Coastguard Worker #define FLAG_LONG (16)
166*d83cc019SAndroid Build Coastguard Worker #define FLAG_HANG (32)
167*d83cc019SAndroid Build Coastguard Worker 
__spin_poll(int fd,uint32_t ctx,const struct intel_execution_engine2 * e)168*d83cc019SAndroid Build Coastguard Worker static igt_spin_t * __spin_poll(int fd, uint32_t ctx,
169*d83cc019SAndroid Build Coastguard Worker 				const struct intel_execution_engine2 *e)
170*d83cc019SAndroid Build Coastguard Worker {
171*d83cc019SAndroid Build Coastguard Worker 	struct igt_spin_factory opts = {
172*d83cc019SAndroid Build Coastguard Worker 		.ctx = ctx,
173*d83cc019SAndroid Build Coastguard Worker 		.engine = e->flags,
174*d83cc019SAndroid Build Coastguard Worker 	};
175*d83cc019SAndroid Build Coastguard Worker 
176*d83cc019SAndroid Build Coastguard Worker 	if (gem_class_can_store_dword(fd, e->class))
177*d83cc019SAndroid Build Coastguard Worker 		opts.flags |= IGT_SPIN_POLL_RUN;
178*d83cc019SAndroid Build Coastguard Worker 
179*d83cc019SAndroid Build Coastguard Worker 	return __igt_spin_factory(fd, &opts);
180*d83cc019SAndroid Build Coastguard Worker }
181*d83cc019SAndroid Build Coastguard Worker 
__spin_wait(int fd,igt_spin_t * spin)182*d83cc019SAndroid Build Coastguard Worker static unsigned long __spin_wait(int fd, igt_spin_t *spin)
183*d83cc019SAndroid Build Coastguard Worker {
184*d83cc019SAndroid Build Coastguard Worker 	struct timespec start = { };
185*d83cc019SAndroid Build Coastguard Worker 
186*d83cc019SAndroid Build Coastguard Worker 	igt_nsec_elapsed(&start);
187*d83cc019SAndroid Build Coastguard Worker 
188*d83cc019SAndroid Build Coastguard Worker 	if (igt_spin_has_poll(spin)) {
189*d83cc019SAndroid Build Coastguard Worker 		unsigned long timeout = 0;
190*d83cc019SAndroid Build Coastguard Worker 
191*d83cc019SAndroid Build Coastguard Worker 		while (!igt_spin_has_started(spin)) {
192*d83cc019SAndroid Build Coastguard Worker 			unsigned long t = igt_nsec_elapsed(&start);
193*d83cc019SAndroid Build Coastguard Worker 
194*d83cc019SAndroid Build Coastguard Worker 			if ((t - timeout) > 250e6) {
195*d83cc019SAndroid Build Coastguard Worker 				timeout = t;
196*d83cc019SAndroid Build Coastguard Worker 				igt_warn("Spinner not running after %.2fms\n",
197*d83cc019SAndroid Build Coastguard Worker 					 (double)t / 1e6);
198*d83cc019SAndroid Build Coastguard Worker 			}
199*d83cc019SAndroid Build Coastguard Worker 		}
200*d83cc019SAndroid Build Coastguard Worker 	} else {
201*d83cc019SAndroid Build Coastguard Worker 		igt_debug("__spin_wait - usleep mode\n");
202*d83cc019SAndroid Build Coastguard Worker 		usleep(500e3); /* Better than nothing! */
203*d83cc019SAndroid Build Coastguard Worker 	}
204*d83cc019SAndroid Build Coastguard Worker 
205*d83cc019SAndroid Build Coastguard Worker 	return igt_nsec_elapsed(&start);
206*d83cc019SAndroid Build Coastguard Worker }
207*d83cc019SAndroid Build Coastguard Worker 
__spin_sync(int fd,uint32_t ctx,const struct intel_execution_engine2 * e)208*d83cc019SAndroid Build Coastguard Worker static igt_spin_t * __spin_sync(int fd, uint32_t ctx,
209*d83cc019SAndroid Build Coastguard Worker 				const struct intel_execution_engine2 *e)
210*d83cc019SAndroid Build Coastguard Worker {
211*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = __spin_poll(fd, ctx, e);
212*d83cc019SAndroid Build Coastguard Worker 
213*d83cc019SAndroid Build Coastguard Worker 	__spin_wait(fd, spin);
214*d83cc019SAndroid Build Coastguard Worker 
215*d83cc019SAndroid Build Coastguard Worker 	return spin;
216*d83cc019SAndroid Build Coastguard Worker }
217*d83cc019SAndroid Build Coastguard Worker 
spin_sync(int fd,uint32_t ctx,const struct intel_execution_engine2 * e)218*d83cc019SAndroid Build Coastguard Worker static igt_spin_t * spin_sync(int fd, uint32_t ctx,
219*d83cc019SAndroid Build Coastguard Worker 			      const struct intel_execution_engine2 *e)
220*d83cc019SAndroid Build Coastguard Worker {
221*d83cc019SAndroid Build Coastguard Worker 	igt_require_gem(fd);
222*d83cc019SAndroid Build Coastguard Worker 
223*d83cc019SAndroid Build Coastguard Worker 	return __spin_sync(fd, ctx, e);
224*d83cc019SAndroid Build Coastguard Worker }
225*d83cc019SAndroid Build Coastguard Worker 
spin_sync_flags(int fd,uint32_t ctx,unsigned int flags)226*d83cc019SAndroid Build Coastguard Worker static igt_spin_t * spin_sync_flags(int fd, uint32_t ctx, unsigned int flags)
227*d83cc019SAndroid Build Coastguard Worker {
228*d83cc019SAndroid Build Coastguard Worker 	struct intel_execution_engine2 e = { };
229*d83cc019SAndroid Build Coastguard Worker 
230*d83cc019SAndroid Build Coastguard Worker 	e.class = gem_execbuf_flags_to_engine_class(flags);
231*d83cc019SAndroid Build Coastguard Worker 	e.instance = (flags & (I915_EXEC_BSD_MASK | I915_EXEC_RING_MASK)) ==
232*d83cc019SAndroid Build Coastguard Worker 		     (I915_EXEC_BSD | I915_EXEC_BSD_RING2) ? 1 : 0;
233*d83cc019SAndroid Build Coastguard Worker 	e.flags = flags;
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 	return spin_sync(fd, ctx, &e);
236*d83cc019SAndroid Build Coastguard Worker }
237*d83cc019SAndroid Build Coastguard Worker 
end_spin(int fd,igt_spin_t * spin,unsigned int flags)238*d83cc019SAndroid Build Coastguard Worker static void end_spin(int fd, igt_spin_t *spin, unsigned int flags)
239*d83cc019SAndroid Build Coastguard Worker {
240*d83cc019SAndroid Build Coastguard Worker 	if (!spin)
241*d83cc019SAndroid Build Coastguard Worker 		return;
242*d83cc019SAndroid Build Coastguard Worker 
243*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(spin);
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 	if (flags & FLAG_SYNC)
246*d83cc019SAndroid Build Coastguard Worker 		gem_sync(fd, spin->handle);
247*d83cc019SAndroid Build Coastguard Worker 
248*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_TRAILING_IDLE) {
249*d83cc019SAndroid Build Coastguard Worker 		unsigned long t, timeout = 0;
250*d83cc019SAndroid Build Coastguard Worker 		struct timespec start = { };
251*d83cc019SAndroid Build Coastguard Worker 
252*d83cc019SAndroid Build Coastguard Worker 		igt_nsec_elapsed(&start);
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 		do {
255*d83cc019SAndroid Build Coastguard Worker 			t = igt_nsec_elapsed(&start);
256*d83cc019SAndroid Build Coastguard Worker 
257*d83cc019SAndroid Build Coastguard Worker 			if (gem_bo_busy(fd, spin->handle) &&
258*d83cc019SAndroid Build Coastguard Worker 			    (t - timeout) > 10e6) {
259*d83cc019SAndroid Build Coastguard Worker 				timeout = t;
260*d83cc019SAndroid Build Coastguard Worker 				igt_warn("Spinner not idle after %.2fms\n",
261*d83cc019SAndroid Build Coastguard Worker 					 (double)t / 1e6);
262*d83cc019SAndroid Build Coastguard Worker 			}
263*d83cc019SAndroid Build Coastguard Worker 
264*d83cc019SAndroid Build Coastguard Worker 			usleep(1e3);
265*d83cc019SAndroid Build Coastguard Worker 		} while (t < batch_duration_ns / 5);
266*d83cc019SAndroid Build Coastguard Worker 	}
267*d83cc019SAndroid Build Coastguard Worker }
268*d83cc019SAndroid Build Coastguard Worker 
269*d83cc019SAndroid Build Coastguard Worker static void
single(int gem_fd,const struct intel_execution_engine2 * e,unsigned int flags)270*d83cc019SAndroid Build Coastguard Worker single(int gem_fd, const struct intel_execution_engine2 *e, unsigned int flags)
271*d83cc019SAndroid Build Coastguard Worker {
272*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept;
273*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
274*d83cc019SAndroid Build Coastguard Worker 	uint64_t val;
275*d83cc019SAndroid Build Coastguard Worker 	int fd;
276*d83cc019SAndroid Build Coastguard Worker 
277*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_ENGINE_BUSY(e->class, e->instance));
278*d83cc019SAndroid Build Coastguard Worker 
279*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_BUSY)
280*d83cc019SAndroid Build Coastguard Worker 		spin = spin_sync(gem_fd, 0, e);
281*d83cc019SAndroid Build Coastguard Worker 	else
282*d83cc019SAndroid Build Coastguard Worker 		spin = NULL;
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker 	val = pmu_read_single(fd);
285*d83cc019SAndroid Build Coastguard Worker 	slept = measured_usleep(batch_duration_ns / 1000);
286*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_TRAILING_IDLE)
287*d83cc019SAndroid Build Coastguard Worker 		end_spin(gem_fd, spin, flags);
288*d83cc019SAndroid Build Coastguard Worker 	val = pmu_read_single(fd) - val;
289*d83cc019SAndroid Build Coastguard Worker 
290*d83cc019SAndroid Build Coastguard Worker 	if (flags & FLAG_HANG)
291*d83cc019SAndroid Build Coastguard Worker 		igt_force_gpu_reset(gem_fd);
292*d83cc019SAndroid Build Coastguard Worker 	else
293*d83cc019SAndroid Build Coastguard Worker 		end_spin(gem_fd, spin, FLAG_SYNC);
294*d83cc019SAndroid Build Coastguard Worker 
295*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val, flags & TEST_BUSY ? slept : 0.f, tolerance);
296*d83cc019SAndroid Build Coastguard Worker 
297*d83cc019SAndroid Build Coastguard Worker 	/* Check for idle after hang. */
298*d83cc019SAndroid Build Coastguard Worker 	if (flags & FLAG_HANG) {
299*d83cc019SAndroid Build Coastguard Worker 		gem_quiescent_gpu(gem_fd);
300*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!gem_bo_busy(gem_fd, spin->handle));
301*d83cc019SAndroid Build Coastguard Worker 
302*d83cc019SAndroid Build Coastguard Worker 		val = pmu_read_single(fd);
303*d83cc019SAndroid Build Coastguard Worker 		slept = measured_usleep(batch_duration_ns / 1000);
304*d83cc019SAndroid Build Coastguard Worker 		val = pmu_read_single(fd) - val;
305*d83cc019SAndroid Build Coastguard Worker 
306*d83cc019SAndroid Build Coastguard Worker 		assert_within_epsilon(val, 0, tolerance);
307*d83cc019SAndroid Build Coastguard Worker 	}
308*d83cc019SAndroid Build Coastguard Worker 
309*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin);
310*d83cc019SAndroid Build Coastguard Worker 	close(fd);
311*d83cc019SAndroid Build Coastguard Worker 
312*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
313*d83cc019SAndroid Build Coastguard Worker }
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker static void
busy_start(int gem_fd,const struct intel_execution_engine2 * e)316*d83cc019SAndroid Build Coastguard Worker busy_start(int gem_fd, const struct intel_execution_engine2 *e)
317*d83cc019SAndroid Build Coastguard Worker {
318*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept;
319*d83cc019SAndroid Build Coastguard Worker 	uint64_t val, ts[2];
320*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
321*d83cc019SAndroid Build Coastguard Worker 	int fd;
322*d83cc019SAndroid Build Coastguard Worker 
323*d83cc019SAndroid Build Coastguard Worker 	/*
324*d83cc019SAndroid Build Coastguard Worker 	 * Defeat the busy stats delayed disable, we need to guarantee we are
325*d83cc019SAndroid Build Coastguard Worker 	 * the first user.
326*d83cc019SAndroid Build Coastguard Worker 	 */
327*d83cc019SAndroid Build Coastguard Worker 	sleep(2);
328*d83cc019SAndroid Build Coastguard Worker 
329*d83cc019SAndroid Build Coastguard Worker 	spin = __spin_sync(gem_fd, 0, e);
330*d83cc019SAndroid Build Coastguard Worker 
331*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_ENGINE_BUSY(e->class, e->instance));
332*d83cc019SAndroid Build Coastguard Worker 
333*d83cc019SAndroid Build Coastguard Worker 	val = __pmu_read_single(fd, &ts[0]);
334*d83cc019SAndroid Build Coastguard Worker 	slept = measured_usleep(batch_duration_ns / 1000);
335*d83cc019SAndroid Build Coastguard Worker 	val = __pmu_read_single(fd, &ts[1]) - val;
336*d83cc019SAndroid Build Coastguard Worker 	igt_debug("slept=%lu perf=%"PRIu64"\n", slept, ts[1] - ts[0]);
337*d83cc019SAndroid Build Coastguard Worker 
338*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin);
339*d83cc019SAndroid Build Coastguard Worker 	close(fd);
340*d83cc019SAndroid Build Coastguard Worker 
341*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val, ts[1] - ts[0], tolerance);
342*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
343*d83cc019SAndroid Build Coastguard Worker }
344*d83cc019SAndroid Build Coastguard Worker 
345*d83cc019SAndroid Build Coastguard Worker /*
346*d83cc019SAndroid Build Coastguard Worker  * This test has a potentially low rate of catching the issue it is trying to
347*d83cc019SAndroid Build Coastguard Worker  * catch. Or in other words, quite high rate of false negative successes. We
348*d83cc019SAndroid Build Coastguard Worker  * will depend on the CI systems running it a lot to detect issues.
349*d83cc019SAndroid Build Coastguard Worker  */
350*d83cc019SAndroid Build Coastguard Worker static void
busy_double_start(int gem_fd,const struct intel_execution_engine2 * e)351*d83cc019SAndroid Build Coastguard Worker busy_double_start(int gem_fd, const struct intel_execution_engine2 *e)
352*d83cc019SAndroid Build Coastguard Worker {
353*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept;
354*d83cc019SAndroid Build Coastguard Worker 	uint64_t val, val2, ts[2];
355*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin[2];
356*d83cc019SAndroid Build Coastguard Worker 	uint32_t ctx;
357*d83cc019SAndroid Build Coastguard Worker 	int fd;
358*d83cc019SAndroid Build Coastguard Worker 
359*d83cc019SAndroid Build Coastguard Worker 	ctx = gem_context_create(gem_fd);
360*d83cc019SAndroid Build Coastguard Worker 	gem_context_set_all_engines(gem_fd, ctx);
361*d83cc019SAndroid Build Coastguard Worker 
362*d83cc019SAndroid Build Coastguard Worker 	/*
363*d83cc019SAndroid Build Coastguard Worker 	 * Defeat the busy stats delayed disable, we need to guarantee we are
364*d83cc019SAndroid Build Coastguard Worker 	 * the first user.
365*d83cc019SAndroid Build Coastguard Worker 	 */
366*d83cc019SAndroid Build Coastguard Worker 	sleep(2);
367*d83cc019SAndroid Build Coastguard Worker 
368*d83cc019SAndroid Build Coastguard Worker 	/*
369*d83cc019SAndroid Build Coastguard Worker 	 * Submit two contexts, with a pause in between targeting the ELSP
370*d83cc019SAndroid Build Coastguard Worker 	 * re-submission in execlists mode. Make sure busyness is correctly
371*d83cc019SAndroid Build Coastguard Worker 	 * reported with the engine busy, and after the engine went idle.
372*d83cc019SAndroid Build Coastguard Worker 	 */
373*d83cc019SAndroid Build Coastguard Worker 	spin[0] = __spin_sync(gem_fd, 0, e);
374*d83cc019SAndroid Build Coastguard Worker 	usleep(500e3);
375*d83cc019SAndroid Build Coastguard Worker 	spin[1] = __igt_spin_new(gem_fd,
376*d83cc019SAndroid Build Coastguard Worker 				 .ctx = ctx,
377*d83cc019SAndroid Build Coastguard Worker 				 .engine = e->flags);
378*d83cc019SAndroid Build Coastguard Worker 
379*d83cc019SAndroid Build Coastguard Worker 	/*
380*d83cc019SAndroid Build Coastguard Worker 	 * Open PMU as fast as possible after the second spin batch in attempt
381*d83cc019SAndroid Build Coastguard Worker 	 * to be faster than the driver handling lite-restore.
382*d83cc019SAndroid Build Coastguard Worker 	 */
383*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_ENGINE_BUSY(e->class, e->instance));
384*d83cc019SAndroid Build Coastguard Worker 
385*d83cc019SAndroid Build Coastguard Worker 	val = __pmu_read_single(fd, &ts[0]);
386*d83cc019SAndroid Build Coastguard Worker 	slept = measured_usleep(batch_duration_ns / 1000);
387*d83cc019SAndroid Build Coastguard Worker 	val = __pmu_read_single(fd, &ts[1]) - val;
388*d83cc019SAndroid Build Coastguard Worker 	igt_debug("slept=%lu perf=%"PRIu64"\n", slept, ts[1] - ts[0]);
389*d83cc019SAndroid Build Coastguard Worker 
390*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(spin[0]);
391*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(spin[1]);
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker 	/* Wait for GPU idle to verify PMU reports idle. */
394*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
395*d83cc019SAndroid Build Coastguard Worker 
396*d83cc019SAndroid Build Coastguard Worker 	val2 = pmu_read_single(fd);
397*d83cc019SAndroid Build Coastguard Worker 	usleep(batch_duration_ns / 1000);
398*d83cc019SAndroid Build Coastguard Worker 	val2 = pmu_read_single(fd) - val2;
399*d83cc019SAndroid Build Coastguard Worker 
400*d83cc019SAndroid Build Coastguard Worker 	igt_info("busy=%"PRIu64" idle=%"PRIu64"\n", val, val2);
401*d83cc019SAndroid Build Coastguard Worker 
402*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin[0]);
403*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin[1]);
404*d83cc019SAndroid Build Coastguard Worker 
405*d83cc019SAndroid Build Coastguard Worker 	close(fd);
406*d83cc019SAndroid Build Coastguard Worker 
407*d83cc019SAndroid Build Coastguard Worker 	gem_context_destroy(gem_fd, ctx);
408*d83cc019SAndroid Build Coastguard Worker 
409*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val, ts[1] - ts[0], tolerance);
410*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(val2, 0);
411*d83cc019SAndroid Build Coastguard Worker 
412*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
413*d83cc019SAndroid Build Coastguard Worker }
414*d83cc019SAndroid Build Coastguard Worker 
log_busy(unsigned int num_engines,uint64_t * val)415*d83cc019SAndroid Build Coastguard Worker static void log_busy(unsigned int num_engines, uint64_t *val)
416*d83cc019SAndroid Build Coastguard Worker {
417*d83cc019SAndroid Build Coastguard Worker 	char buf[1024];
418*d83cc019SAndroid Build Coastguard Worker 	int rem = sizeof(buf);
419*d83cc019SAndroid Build Coastguard Worker 	unsigned int i;
420*d83cc019SAndroid Build Coastguard Worker 	char *p = buf;
421*d83cc019SAndroid Build Coastguard Worker 
422*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++) {
423*d83cc019SAndroid Build Coastguard Worker 		int len;
424*d83cc019SAndroid Build Coastguard Worker 
425*d83cc019SAndroid Build Coastguard Worker 		len = snprintf(p, rem, "%u=%" PRIu64 "\n",  i, val[i]);
426*d83cc019SAndroid Build Coastguard Worker 		igt_assert(len > 0);
427*d83cc019SAndroid Build Coastguard Worker 		rem -= len;
428*d83cc019SAndroid Build Coastguard Worker 		p += len;
429*d83cc019SAndroid Build Coastguard Worker 	}
430*d83cc019SAndroid Build Coastguard Worker 
431*d83cc019SAndroid Build Coastguard Worker 	igt_info("%s", buf);
432*d83cc019SAndroid Build Coastguard Worker }
433*d83cc019SAndroid Build Coastguard Worker 
434*d83cc019SAndroid Build Coastguard Worker static void
busy_check_all(int gem_fd,const struct intel_execution_engine2 * e,const unsigned int num_engines,unsigned int flags)435*d83cc019SAndroid Build Coastguard Worker busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
436*d83cc019SAndroid Build Coastguard Worker 	       const unsigned int num_engines, unsigned int flags)
437*d83cc019SAndroid Build Coastguard Worker {
438*d83cc019SAndroid Build Coastguard Worker 	struct intel_execution_engine2 *e_;
439*d83cc019SAndroid Build Coastguard Worker 	uint64_t tval[2][num_engines];
440*d83cc019SAndroid Build Coastguard Worker 	unsigned int busy_idx = 0, i;
441*d83cc019SAndroid Build Coastguard Worker 	uint64_t val[num_engines];
442*d83cc019SAndroid Build Coastguard Worker 	int fd[num_engines];
443*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept;
444*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
445*d83cc019SAndroid Build Coastguard Worker 
446*d83cc019SAndroid Build Coastguard Worker 	i = 0;
447*d83cc019SAndroid Build Coastguard Worker 	fd[0] = -1;
448*d83cc019SAndroid Build Coastguard Worker 	__for_each_physical_engine(gem_fd, e_) {
449*d83cc019SAndroid Build Coastguard Worker 		if (e->class == e_->class && e->instance == e_->instance)
450*d83cc019SAndroid Build Coastguard Worker 			busy_idx = i;
451*d83cc019SAndroid Build Coastguard Worker 
452*d83cc019SAndroid Build Coastguard Worker 		fd[i++] = open_group(I915_PMU_ENGINE_BUSY(e_->class,
453*d83cc019SAndroid Build Coastguard Worker 							  e_->instance),
454*d83cc019SAndroid Build Coastguard Worker 				     fd[0]);
455*d83cc019SAndroid Build Coastguard Worker 	}
456*d83cc019SAndroid Build Coastguard Worker 
457*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(i, num_engines);
458*d83cc019SAndroid Build Coastguard Worker 
459*d83cc019SAndroid Build Coastguard Worker 	spin = spin_sync(gem_fd, 0, e);
460*d83cc019SAndroid Build Coastguard Worker 	pmu_read_multi(fd[0], num_engines, tval[0]);
461*d83cc019SAndroid Build Coastguard Worker 	slept = measured_usleep(batch_duration_ns / 1000);
462*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_TRAILING_IDLE)
463*d83cc019SAndroid Build Coastguard Worker 		end_spin(gem_fd, spin, flags);
464*d83cc019SAndroid Build Coastguard Worker 	pmu_read_multi(fd[0], num_engines, tval[1]);
465*d83cc019SAndroid Build Coastguard Worker 
466*d83cc019SAndroid Build Coastguard Worker 	end_spin(gem_fd, spin, FLAG_SYNC);
467*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin);
468*d83cc019SAndroid Build Coastguard Worker 	close(fd[0]);
469*d83cc019SAndroid Build Coastguard Worker 
470*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++)
471*d83cc019SAndroid Build Coastguard Worker 		val[i] = tval[1][i] - tval[0][i];
472*d83cc019SAndroid Build Coastguard Worker 
473*d83cc019SAndroid Build Coastguard Worker 	log_busy(num_engines, val);
474*d83cc019SAndroid Build Coastguard Worker 
475*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val[busy_idx], slept, tolerance);
476*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++) {
477*d83cc019SAndroid Build Coastguard Worker 		if (i == busy_idx)
478*d83cc019SAndroid Build Coastguard Worker 			continue;
479*d83cc019SAndroid Build Coastguard Worker 		assert_within_epsilon(val[i], 0.0f, tolerance);
480*d83cc019SAndroid Build Coastguard Worker 	}
481*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
482*d83cc019SAndroid Build Coastguard Worker }
483*d83cc019SAndroid Build Coastguard Worker 
484*d83cc019SAndroid Build Coastguard Worker static void
__submit_spin(int gem_fd,igt_spin_t * spin,const struct intel_execution_engine2 * e,int offset)485*d83cc019SAndroid Build Coastguard Worker __submit_spin(int gem_fd, igt_spin_t *spin,
486*d83cc019SAndroid Build Coastguard Worker 	      const struct intel_execution_engine2 *e,
487*d83cc019SAndroid Build Coastguard Worker 	      int offset)
488*d83cc019SAndroid Build Coastguard Worker {
489*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 eb = spin->execbuf;
490*d83cc019SAndroid Build Coastguard Worker 
491*d83cc019SAndroid Build Coastguard Worker 	eb.flags &= ~(0x3f | I915_EXEC_BSD_MASK);
492*d83cc019SAndroid Build Coastguard Worker 	eb.flags |= e->flags | I915_EXEC_NO_RELOC;
493*d83cc019SAndroid Build Coastguard Worker 	eb.batch_start_offset += offset;
494*d83cc019SAndroid Build Coastguard Worker 
495*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(gem_fd, &eb);
496*d83cc019SAndroid Build Coastguard Worker }
497*d83cc019SAndroid Build Coastguard Worker 
498*d83cc019SAndroid Build Coastguard Worker static void
most_busy_check_all(int gem_fd,const struct intel_execution_engine2 * e,const unsigned int num_engines,unsigned int flags)499*d83cc019SAndroid Build Coastguard Worker most_busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
500*d83cc019SAndroid Build Coastguard Worker 		    const unsigned int num_engines, unsigned int flags)
501*d83cc019SAndroid Build Coastguard Worker {
502*d83cc019SAndroid Build Coastguard Worker 	struct intel_execution_engine2 *e_;
503*d83cc019SAndroid Build Coastguard Worker 	uint64_t tval[2][num_engines];
504*d83cc019SAndroid Build Coastguard Worker 	uint64_t val[num_engines];
505*d83cc019SAndroid Build Coastguard Worker 	int fd[num_engines];
506*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept;
507*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = NULL;
508*d83cc019SAndroid Build Coastguard Worker 	unsigned int idle_idx, i;
509*d83cc019SAndroid Build Coastguard Worker 
510*d83cc019SAndroid Build Coastguard Worker 	i = 0;
511*d83cc019SAndroid Build Coastguard Worker 	__for_each_physical_engine(gem_fd, e_) {
512*d83cc019SAndroid Build Coastguard Worker 		if (e->class == e_->class && e->instance == e_->instance)
513*d83cc019SAndroid Build Coastguard Worker 			idle_idx = i;
514*d83cc019SAndroid Build Coastguard Worker 		else if (spin)
515*d83cc019SAndroid Build Coastguard Worker 			__submit_spin(gem_fd, spin, e_, 64);
516*d83cc019SAndroid Build Coastguard Worker 		else
517*d83cc019SAndroid Build Coastguard Worker 			spin = __spin_poll(gem_fd, 0, e_);
518*d83cc019SAndroid Build Coastguard Worker 
519*d83cc019SAndroid Build Coastguard Worker 		val[i++] = I915_PMU_ENGINE_BUSY(e_->class, e_->instance);
520*d83cc019SAndroid Build Coastguard Worker 	}
521*d83cc019SAndroid Build Coastguard Worker 	igt_assert(i == num_engines);
522*d83cc019SAndroid Build Coastguard Worker 	igt_require(spin); /* at least one busy engine */
523*d83cc019SAndroid Build Coastguard Worker 
524*d83cc019SAndroid Build Coastguard Worker 	fd[0] = -1;
525*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++)
526*d83cc019SAndroid Build Coastguard Worker 		fd[i] = open_group(val[i], fd[0]);
527*d83cc019SAndroid Build Coastguard Worker 
528*d83cc019SAndroid Build Coastguard Worker 	/* Small delay to allow engines to start. */
529*d83cc019SAndroid Build Coastguard Worker 	usleep(__spin_wait(gem_fd, spin) * num_engines / 1e3);
530*d83cc019SAndroid Build Coastguard Worker 
531*d83cc019SAndroid Build Coastguard Worker 	pmu_read_multi(fd[0], num_engines, tval[0]);
532*d83cc019SAndroid Build Coastguard Worker 	slept = measured_usleep(batch_duration_ns / 1000);
533*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_TRAILING_IDLE)
534*d83cc019SAndroid Build Coastguard Worker 		end_spin(gem_fd, spin, flags);
535*d83cc019SAndroid Build Coastguard Worker 	pmu_read_multi(fd[0], num_engines, tval[1]);
536*d83cc019SAndroid Build Coastguard Worker 
537*d83cc019SAndroid Build Coastguard Worker 	end_spin(gem_fd, spin, FLAG_SYNC);
538*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin);
539*d83cc019SAndroid Build Coastguard Worker 	close(fd[0]);
540*d83cc019SAndroid Build Coastguard Worker 
541*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++)
542*d83cc019SAndroid Build Coastguard Worker 		val[i] = tval[1][i] - tval[0][i];
543*d83cc019SAndroid Build Coastguard Worker 
544*d83cc019SAndroid Build Coastguard Worker 	log_busy(num_engines, val);
545*d83cc019SAndroid Build Coastguard Worker 
546*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++) {
547*d83cc019SAndroid Build Coastguard Worker 		if (i == idle_idx)
548*d83cc019SAndroid Build Coastguard Worker 			assert_within_epsilon(val[i], 0.0f, tolerance);
549*d83cc019SAndroid Build Coastguard Worker 		else
550*d83cc019SAndroid Build Coastguard Worker 			assert_within_epsilon(val[i], slept, tolerance);
551*d83cc019SAndroid Build Coastguard Worker 	}
552*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
553*d83cc019SAndroid Build Coastguard Worker }
554*d83cc019SAndroid Build Coastguard Worker 
555*d83cc019SAndroid Build Coastguard Worker static void
all_busy_check_all(int gem_fd,const unsigned int num_engines,unsigned int flags)556*d83cc019SAndroid Build Coastguard Worker all_busy_check_all(int gem_fd, const unsigned int num_engines,
557*d83cc019SAndroid Build Coastguard Worker 		   unsigned int flags)
558*d83cc019SAndroid Build Coastguard Worker {
559*d83cc019SAndroid Build Coastguard Worker 	struct intel_execution_engine2 *e;
560*d83cc019SAndroid Build Coastguard Worker 	uint64_t tval[2][num_engines];
561*d83cc019SAndroid Build Coastguard Worker 	uint64_t val[num_engines];
562*d83cc019SAndroid Build Coastguard Worker 	int fd[num_engines];
563*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept;
564*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin = NULL;
565*d83cc019SAndroid Build Coastguard Worker 	unsigned int i;
566*d83cc019SAndroid Build Coastguard Worker 
567*d83cc019SAndroid Build Coastguard Worker 	i = 0;
568*d83cc019SAndroid Build Coastguard Worker 	__for_each_physical_engine(gem_fd, e) {
569*d83cc019SAndroid Build Coastguard Worker 		if (spin)
570*d83cc019SAndroid Build Coastguard Worker 			__submit_spin(gem_fd, spin, e, 64);
571*d83cc019SAndroid Build Coastguard Worker 		else
572*d83cc019SAndroid Build Coastguard Worker 			spin = __spin_poll(gem_fd, 0, e);
573*d83cc019SAndroid Build Coastguard Worker 
574*d83cc019SAndroid Build Coastguard Worker 		val[i++] = I915_PMU_ENGINE_BUSY(e->class, e->instance);
575*d83cc019SAndroid Build Coastguard Worker 	}
576*d83cc019SAndroid Build Coastguard Worker 	igt_assert(i == num_engines);
577*d83cc019SAndroid Build Coastguard Worker 
578*d83cc019SAndroid Build Coastguard Worker 	fd[0] = -1;
579*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++)
580*d83cc019SAndroid Build Coastguard Worker 		fd[i] = open_group(val[i], fd[0]);
581*d83cc019SAndroid Build Coastguard Worker 
582*d83cc019SAndroid Build Coastguard Worker 	/* Small delay to allow engines to start. */
583*d83cc019SAndroid Build Coastguard Worker 	usleep(__spin_wait(gem_fd, spin) * num_engines / 1e3);
584*d83cc019SAndroid Build Coastguard Worker 
585*d83cc019SAndroid Build Coastguard Worker 	pmu_read_multi(fd[0], num_engines, tval[0]);
586*d83cc019SAndroid Build Coastguard Worker 	slept = measured_usleep(batch_duration_ns / 1000);
587*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_TRAILING_IDLE)
588*d83cc019SAndroid Build Coastguard Worker 		end_spin(gem_fd, spin, flags);
589*d83cc019SAndroid Build Coastguard Worker 	pmu_read_multi(fd[0], num_engines, tval[1]);
590*d83cc019SAndroid Build Coastguard Worker 
591*d83cc019SAndroid Build Coastguard Worker 	end_spin(gem_fd, spin, FLAG_SYNC);
592*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin);
593*d83cc019SAndroid Build Coastguard Worker 	close(fd[0]);
594*d83cc019SAndroid Build Coastguard Worker 
595*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++)
596*d83cc019SAndroid Build Coastguard Worker 		val[i] = tval[1][i] - tval[0][i];
597*d83cc019SAndroid Build Coastguard Worker 
598*d83cc019SAndroid Build Coastguard Worker 	log_busy(num_engines, val);
599*d83cc019SAndroid Build Coastguard Worker 
600*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_engines; i++)
601*d83cc019SAndroid Build Coastguard Worker 		assert_within_epsilon(val[i], slept, tolerance);
602*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
603*d83cc019SAndroid Build Coastguard Worker }
604*d83cc019SAndroid Build Coastguard Worker 
605*d83cc019SAndroid Build Coastguard Worker static void
no_sema(int gem_fd,const struct intel_execution_engine2 * e,unsigned int flags)606*d83cc019SAndroid Build Coastguard Worker no_sema(int gem_fd, const struct intel_execution_engine2 *e, unsigned int flags)
607*d83cc019SAndroid Build Coastguard Worker {
608*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
609*d83cc019SAndroid Build Coastguard Worker 	uint64_t val[2][2];
610*d83cc019SAndroid Build Coastguard Worker 	int fd;
611*d83cc019SAndroid Build Coastguard Worker 
612*d83cc019SAndroid Build Coastguard Worker 	fd = open_group(I915_PMU_ENGINE_SEMA(e->class, e->instance), -1);
613*d83cc019SAndroid Build Coastguard Worker 	open_group(I915_PMU_ENGINE_WAIT(e->class, e->instance), fd);
614*d83cc019SAndroid Build Coastguard Worker 
615*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_BUSY)
616*d83cc019SAndroid Build Coastguard Worker 		spin = spin_sync(gem_fd, 0, e);
617*d83cc019SAndroid Build Coastguard Worker 	else
618*d83cc019SAndroid Build Coastguard Worker 		spin = NULL;
619*d83cc019SAndroid Build Coastguard Worker 
620*d83cc019SAndroid Build Coastguard Worker 	pmu_read_multi(fd, 2, val[0]);
621*d83cc019SAndroid Build Coastguard Worker 	measured_usleep(batch_duration_ns / 1000);
622*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_TRAILING_IDLE)
623*d83cc019SAndroid Build Coastguard Worker 		end_spin(gem_fd, spin, flags);
624*d83cc019SAndroid Build Coastguard Worker 	pmu_read_multi(fd, 2, val[1]);
625*d83cc019SAndroid Build Coastguard Worker 
626*d83cc019SAndroid Build Coastguard Worker 	val[0][0] = val[1][0] - val[0][0];
627*d83cc019SAndroid Build Coastguard Worker 	val[0][1] = val[1][1] - val[0][1];
628*d83cc019SAndroid Build Coastguard Worker 
629*d83cc019SAndroid Build Coastguard Worker 	if (spin) {
630*d83cc019SAndroid Build Coastguard Worker 		end_spin(gem_fd, spin, FLAG_SYNC);
631*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(gem_fd, spin);
632*d83cc019SAndroid Build Coastguard Worker 	}
633*d83cc019SAndroid Build Coastguard Worker 	close(fd);
634*d83cc019SAndroid Build Coastguard Worker 
635*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val[0][0], 0.0f, tolerance);
636*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val[0][1], 0.0f, tolerance);
637*d83cc019SAndroid Build Coastguard Worker }
638*d83cc019SAndroid Build Coastguard Worker 
639*d83cc019SAndroid Build Coastguard Worker #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
640*d83cc019SAndroid Build Coastguard Worker #define MI_SEMAPHORE_WAIT	MI_INSTR(0x1c, 2) /* GEN8+ */
641*d83cc019SAndroid Build Coastguard Worker #define   MI_SEMAPHORE_POLL		(1<<15)
642*d83cc019SAndroid Build Coastguard Worker #define   MI_SEMAPHORE_SAD_GTE_SDD	(1<<12)
643*d83cc019SAndroid Build Coastguard Worker 
644*d83cc019SAndroid Build Coastguard Worker static void
sema_wait(int gem_fd,const struct intel_execution_engine2 * e,unsigned int flags)645*d83cc019SAndroid Build Coastguard Worker sema_wait(int gem_fd, const struct intel_execution_engine2 *e,
646*d83cc019SAndroid Build Coastguard Worker 	  unsigned int flags)
647*d83cc019SAndroid Build Coastguard Worker {
648*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc[2] = {};
649*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[2] = {};
650*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 eb = {};
651*d83cc019SAndroid Build Coastguard Worker 	uint32_t bb_handle, obj_handle;
652*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept;
653*d83cc019SAndroid Build Coastguard Worker 	uint32_t *obj_ptr;
654*d83cc019SAndroid Build Coastguard Worker 	uint32_t batch[16];
655*d83cc019SAndroid Build Coastguard Worker 	uint64_t val[2], ts[2];
656*d83cc019SAndroid Build Coastguard Worker 	int fd;
657*d83cc019SAndroid Build Coastguard Worker 
658*d83cc019SAndroid Build Coastguard Worker 	igt_require(intel_gen(intel_get_drm_devid(gem_fd)) >= 8);
659*d83cc019SAndroid Build Coastguard Worker 
660*d83cc019SAndroid Build Coastguard Worker 	/**
661*d83cc019SAndroid Build Coastguard Worker 	 * Setup up a batchbuffer with a polling semaphore wait command which
662*d83cc019SAndroid Build Coastguard Worker 	 * will wait on an value in a shared bo to change. This way we are able
663*d83cc019SAndroid Build Coastguard Worker 	 * to control how much time we will spend in this bb.
664*d83cc019SAndroid Build Coastguard Worker 	 */
665*d83cc019SAndroid Build Coastguard Worker 
666*d83cc019SAndroid Build Coastguard Worker 	bb_handle = gem_create(gem_fd, 4096);
667*d83cc019SAndroid Build Coastguard Worker 	obj_handle = gem_create(gem_fd, 4096);
668*d83cc019SAndroid Build Coastguard Worker 
669*d83cc019SAndroid Build Coastguard Worker 	obj_ptr = gem_mmap__wc(gem_fd, obj_handle, 0, 4096, PROT_WRITE);
670*d83cc019SAndroid Build Coastguard Worker 
671*d83cc019SAndroid Build Coastguard Worker 	batch[0] = MI_STORE_DWORD_IMM;
672*d83cc019SAndroid Build Coastguard Worker 	batch[1] = sizeof(*obj_ptr);
673*d83cc019SAndroid Build Coastguard Worker 	batch[2] = 0;
674*d83cc019SAndroid Build Coastguard Worker 	batch[3] = 1;
675*d83cc019SAndroid Build Coastguard Worker 	batch[4] = MI_SEMAPHORE_WAIT |
676*d83cc019SAndroid Build Coastguard Worker 		   MI_SEMAPHORE_POLL |
677*d83cc019SAndroid Build Coastguard Worker 		   MI_SEMAPHORE_SAD_GTE_SDD;
678*d83cc019SAndroid Build Coastguard Worker 	batch[5] = 1;
679*d83cc019SAndroid Build Coastguard Worker 	batch[6] = 0x0;
680*d83cc019SAndroid Build Coastguard Worker 	batch[7] = 0x0;
681*d83cc019SAndroid Build Coastguard Worker 	batch[8] = MI_BATCH_BUFFER_END;
682*d83cc019SAndroid Build Coastguard Worker 
683*d83cc019SAndroid Build Coastguard Worker 	gem_write(gem_fd, bb_handle, 0, batch, sizeof(batch));
684*d83cc019SAndroid Build Coastguard Worker 
685*d83cc019SAndroid Build Coastguard Worker 	reloc[0].target_handle = obj_handle;
686*d83cc019SAndroid Build Coastguard Worker 	reloc[0].offset = 1 * sizeof(uint32_t);
687*d83cc019SAndroid Build Coastguard Worker 	reloc[0].read_domains = I915_GEM_DOMAIN_RENDER;
688*d83cc019SAndroid Build Coastguard Worker 	reloc[0].write_domain = I915_GEM_DOMAIN_RENDER;
689*d83cc019SAndroid Build Coastguard Worker 	reloc[0].delta = sizeof(*obj_ptr);
690*d83cc019SAndroid Build Coastguard Worker 
691*d83cc019SAndroid Build Coastguard Worker 	reloc[1].target_handle = obj_handle;
692*d83cc019SAndroid Build Coastguard Worker 	reloc[1].offset = 6 * sizeof(uint32_t);
693*d83cc019SAndroid Build Coastguard Worker 	reloc[1].read_domains = I915_GEM_DOMAIN_RENDER;
694*d83cc019SAndroid Build Coastguard Worker 
695*d83cc019SAndroid Build Coastguard Worker 	obj[0].handle = obj_handle;
696*d83cc019SAndroid Build Coastguard Worker 
697*d83cc019SAndroid Build Coastguard Worker 	obj[1].handle = bb_handle;
698*d83cc019SAndroid Build Coastguard Worker 	obj[1].relocation_count = 2;
699*d83cc019SAndroid Build Coastguard Worker 	obj[1].relocs_ptr = to_user_pointer(reloc);
700*d83cc019SAndroid Build Coastguard Worker 
701*d83cc019SAndroid Build Coastguard Worker 	eb.buffer_count = 2;
702*d83cc019SAndroid Build Coastguard Worker 	eb.buffers_ptr = to_user_pointer(obj);
703*d83cc019SAndroid Build Coastguard Worker 	eb.flags = e->flags;
704*d83cc019SAndroid Build Coastguard Worker 
705*d83cc019SAndroid Build Coastguard Worker 	/**
706*d83cc019SAndroid Build Coastguard Worker 	 * Start the semaphore wait PMU and after some known time let the above
707*d83cc019SAndroid Build Coastguard Worker 	 * semaphore wait command finish. Then check that the PMU is reporting
708*d83cc019SAndroid Build Coastguard Worker 	 * to expected time spent in semaphore wait state.
709*d83cc019SAndroid Build Coastguard Worker 	 */
710*d83cc019SAndroid Build Coastguard Worker 
711*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_ENGINE_SEMA(e->class, e->instance));
712*d83cc019SAndroid Build Coastguard Worker 
713*d83cc019SAndroid Build Coastguard Worker 	val[0] = pmu_read_single(fd);
714*d83cc019SAndroid Build Coastguard Worker 
715*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(gem_fd, &eb);
716*d83cc019SAndroid Build Coastguard Worker 	do { /* wait for the batch to start executing */
717*d83cc019SAndroid Build Coastguard Worker 		usleep(5e3);
718*d83cc019SAndroid Build Coastguard Worker 	} while (!obj_ptr[1]);
719*d83cc019SAndroid Build Coastguard Worker 
720*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(igt_wait(pmu_read_single(fd) != val[0], 10, 1),
721*d83cc019SAndroid Build Coastguard Worker 		     "sampling failed to start withing 10ms\n");
722*d83cc019SAndroid Build Coastguard Worker 
723*d83cc019SAndroid Build Coastguard Worker 	val[0] = __pmu_read_single(fd, &ts[0]);
724*d83cc019SAndroid Build Coastguard Worker 	slept = measured_usleep(batch_duration_ns / 1000);
725*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_TRAILING_IDLE)
726*d83cc019SAndroid Build Coastguard Worker 		obj_ptr[0] = 1;
727*d83cc019SAndroid Build Coastguard Worker 	val[1] = __pmu_read_single(fd, &ts[1]);
728*d83cc019SAndroid Build Coastguard Worker 	igt_debug("slept %.3fms (perf %.3fms), sampled %.3fms\n",
729*d83cc019SAndroid Build Coastguard Worker 		  slept * 1e-6,
730*d83cc019SAndroid Build Coastguard Worker 		  (ts[1] - ts[0]) * 1e-6,
731*d83cc019SAndroid Build Coastguard Worker 		  (val[1] - val[0]) * 1e-6);
732*d83cc019SAndroid Build Coastguard Worker 
733*d83cc019SAndroid Build Coastguard Worker 	obj_ptr[0] = 1;
734*d83cc019SAndroid Build Coastguard Worker 	gem_sync(gem_fd, bb_handle);
735*d83cc019SAndroid Build Coastguard Worker 
736*d83cc019SAndroid Build Coastguard Worker 	munmap(obj_ptr, 4096);
737*d83cc019SAndroid Build Coastguard Worker 	gem_close(gem_fd, obj_handle);
738*d83cc019SAndroid Build Coastguard Worker 	gem_close(gem_fd, bb_handle);
739*d83cc019SAndroid Build Coastguard Worker 	close(fd);
740*d83cc019SAndroid Build Coastguard Worker 
741*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val[1] - val[0], slept, tolerance);
742*d83cc019SAndroid Build Coastguard Worker }
743*d83cc019SAndroid Build Coastguard Worker 
744*d83cc019SAndroid Build Coastguard Worker #define   MI_WAIT_FOR_PIPE_C_VBLANK (1<<21)
745*d83cc019SAndroid Build Coastguard Worker #define   MI_WAIT_FOR_PIPE_B_VBLANK (1<<11)
746*d83cc019SAndroid Build Coastguard Worker #define   MI_WAIT_FOR_PIPE_A_VBLANK (1<<3)
747*d83cc019SAndroid Build Coastguard Worker 
748*d83cc019SAndroid Build Coastguard Worker typedef struct {
749*d83cc019SAndroid Build Coastguard Worker 	igt_display_t display;
750*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb primary_fb;
751*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
752*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
753*d83cc019SAndroid Build Coastguard Worker } data_t;
754*d83cc019SAndroid Build Coastguard Worker 
prepare_crtc(data_t * data,int fd,igt_output_t * output)755*d83cc019SAndroid Build Coastguard Worker static void prepare_crtc(data_t *data, int fd, igt_output_t *output)
756*d83cc019SAndroid Build Coastguard Worker {
757*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
758*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
759*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
760*d83cc019SAndroid Build Coastguard Worker 
761*d83cc019SAndroid Build Coastguard Worker 	/* select the pipe we want to use */
762*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_pipe(output, data->pipe);
763*d83cc019SAndroid Build Coastguard Worker 
764*d83cc019SAndroid Build Coastguard Worker 	/* create and set the primary plane fb */
765*d83cc019SAndroid Build Coastguard Worker 	mode = igt_output_get_mode(output);
766*d83cc019SAndroid Build Coastguard Worker 	igt_create_color_fb(fd, mode->hdisplay, mode->vdisplay,
767*d83cc019SAndroid Build Coastguard Worker 			    DRM_FORMAT_XRGB8888,
768*d83cc019SAndroid Build Coastguard Worker 			    LOCAL_DRM_FORMAT_MOD_NONE,
769*d83cc019SAndroid Build Coastguard Worker 			    0.0, 0.0, 0.0,
770*d83cc019SAndroid Build Coastguard Worker 			    &data->primary_fb);
771*d83cc019SAndroid Build Coastguard Worker 
772*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
773*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, &data->primary_fb);
774*d83cc019SAndroid Build Coastguard Worker 
775*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit(display);
776*d83cc019SAndroid Build Coastguard Worker 
777*d83cc019SAndroid Build Coastguard Worker 	igt_wait_for_vblank(fd, data->pipe);
778*d83cc019SAndroid Build Coastguard Worker }
779*d83cc019SAndroid Build Coastguard Worker 
cleanup_crtc(data_t * data,int fd,igt_output_t * output)780*d83cc019SAndroid Build Coastguard Worker static void cleanup_crtc(data_t *data, int fd, igt_output_t *output)
781*d83cc019SAndroid Build Coastguard Worker {
782*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
783*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
784*d83cc019SAndroid Build Coastguard Worker 
785*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(fd, &data->primary_fb);
786*d83cc019SAndroid Build Coastguard Worker 
787*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
788*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, NULL);
789*d83cc019SAndroid Build Coastguard Worker 
790*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_pipe(output, PIPE_ANY);
791*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit(display);
792*d83cc019SAndroid Build Coastguard Worker }
793*d83cc019SAndroid Build Coastguard Worker 
wait_vblank(int fd,union drm_wait_vblank * vbl)794*d83cc019SAndroid Build Coastguard Worker static int wait_vblank(int fd, union drm_wait_vblank *vbl)
795*d83cc019SAndroid Build Coastguard Worker {
796*d83cc019SAndroid Build Coastguard Worker 	int err;
797*d83cc019SAndroid Build Coastguard Worker 
798*d83cc019SAndroid Build Coastguard Worker 	err = 0;
799*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl))
800*d83cc019SAndroid Build Coastguard Worker 		err = -errno;
801*d83cc019SAndroid Build Coastguard Worker 
802*d83cc019SAndroid Build Coastguard Worker 	return err;
803*d83cc019SAndroid Build Coastguard Worker }
804*d83cc019SAndroid Build Coastguard Worker 
805*d83cc019SAndroid Build Coastguard Worker static void
event_wait(int gem_fd,const struct intel_execution_engine2 * e)806*d83cc019SAndroid Build Coastguard Worker event_wait(int gem_fd, const struct intel_execution_engine2 *e)
807*d83cc019SAndroid Build Coastguard Worker {
808*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = { };
809*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 eb = { };
810*d83cc019SAndroid Build Coastguard Worker 	const uint32_t DERRMR = 0x44050;
811*d83cc019SAndroid Build Coastguard Worker 	const uint32_t FORCEWAKE_MT = 0xa188;
812*d83cc019SAndroid Build Coastguard Worker 	unsigned int valid_tests = 0;
813*d83cc019SAndroid Build Coastguard Worker 	uint32_t batch[16], *b;
814*d83cc019SAndroid Build Coastguard Worker 	uint16_t devid;
815*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
816*d83cc019SAndroid Build Coastguard Worker 	data_t data;
817*d83cc019SAndroid Build Coastguard Worker 	enum pipe p;
818*d83cc019SAndroid Build Coastguard Worker 	int fd;
819*d83cc019SAndroid Build Coastguard Worker 
820*d83cc019SAndroid Build Coastguard Worker 	devid = intel_get_drm_devid(gem_fd);
821*d83cc019SAndroid Build Coastguard Worker 	igt_require(intel_gen(devid) >= 7);
822*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on(IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid));
823*d83cc019SAndroid Build Coastguard Worker 
824*d83cc019SAndroid Build Coastguard Worker 	kmstest_set_vt_graphics_mode();
825*d83cc019SAndroid Build Coastguard Worker 	igt_display_require(&data.display, gem_fd);
826*d83cc019SAndroid Build Coastguard Worker 
827*d83cc019SAndroid Build Coastguard Worker 	/**
828*d83cc019SAndroid Build Coastguard Worker 	 * We will use the display to render event forwarind so need to
829*d83cc019SAndroid Build Coastguard Worker 	 * program the DERRMR register and restore it at exit.
830*d83cc019SAndroid Build Coastguard Worker 	 * Note we assume that the default/desired value for DERRMR will always
831*d83cc019SAndroid Build Coastguard Worker 	 * be ~0u (all routing disable). To be fancy, we could do a SRM of the
832*d83cc019SAndroid Build Coastguard Worker 	 * reg beforehand and then LRM at the end.
833*d83cc019SAndroid Build Coastguard Worker 	 *
834*d83cc019SAndroid Build Coastguard Worker 	 * We will emit a MI_WAIT_FOR_EVENT listening for vblank events,
835*d83cc019SAndroid Build Coastguard Worker 	 * have a background helper to indirectly enable vblank irqs, and
836*d83cc019SAndroid Build Coastguard Worker 	 * listen to the recorded time spent in engine wait state as reported
837*d83cc019SAndroid Build Coastguard Worker 	 * by the PMU.
838*d83cc019SAndroid Build Coastguard Worker 	 */
839*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(gem_fd, 4096);
840*d83cc019SAndroid Build Coastguard Worker 
841*d83cc019SAndroid Build Coastguard Worker 	b = batch;
842*d83cc019SAndroid Build Coastguard Worker 	*b++ = MI_LOAD_REGISTER_IMM;
843*d83cc019SAndroid Build Coastguard Worker 	*b++ = FORCEWAKE_MT;
844*d83cc019SAndroid Build Coastguard Worker 	*b++ = 2 << 16 | 2;
845*d83cc019SAndroid Build Coastguard Worker 	*b++ = MI_LOAD_REGISTER_IMM;
846*d83cc019SAndroid Build Coastguard Worker 	*b++ = DERRMR;
847*d83cc019SAndroid Build Coastguard Worker 	*b++ = ~0u;
848*d83cc019SAndroid Build Coastguard Worker 	*b++ = MI_WAIT_FOR_EVENT;
849*d83cc019SAndroid Build Coastguard Worker 	*b++ = MI_LOAD_REGISTER_IMM;
850*d83cc019SAndroid Build Coastguard Worker 	*b++ = DERRMR;
851*d83cc019SAndroid Build Coastguard Worker 	*b++ = ~0u;
852*d83cc019SAndroid Build Coastguard Worker 	*b++ = MI_LOAD_REGISTER_IMM;
853*d83cc019SAndroid Build Coastguard Worker 	*b++ = FORCEWAKE_MT;
854*d83cc019SAndroid Build Coastguard Worker 	*b++ = 2 << 16;
855*d83cc019SAndroid Build Coastguard Worker 	*b++ = MI_BATCH_BUFFER_END;
856*d83cc019SAndroid Build Coastguard Worker 
857*d83cc019SAndroid Build Coastguard Worker 	eb.buffer_count = 1;
858*d83cc019SAndroid Build Coastguard Worker 	eb.buffers_ptr = to_user_pointer(&obj);
859*d83cc019SAndroid Build Coastguard Worker 	eb.flags = e->flags | I915_EXEC_SECURE;
860*d83cc019SAndroid Build Coastguard Worker 
861*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe_with_valid_output(&data.display, p, output) {
862*d83cc019SAndroid Build Coastguard Worker 		struct igt_helper_process waiter = { };
863*d83cc019SAndroid Build Coastguard Worker 		const unsigned int frames = 3;
864*d83cc019SAndroid Build Coastguard Worker 		uint64_t val[2];
865*d83cc019SAndroid Build Coastguard Worker 
866*d83cc019SAndroid Build Coastguard Worker 		batch[6] = MI_WAIT_FOR_EVENT;
867*d83cc019SAndroid Build Coastguard Worker 		switch (p) {
868*d83cc019SAndroid Build Coastguard Worker 		case PIPE_A:
869*d83cc019SAndroid Build Coastguard Worker 			batch[6] |= MI_WAIT_FOR_PIPE_A_VBLANK;
870*d83cc019SAndroid Build Coastguard Worker 			batch[5] = ~(1 << 3);
871*d83cc019SAndroid Build Coastguard Worker 			break;
872*d83cc019SAndroid Build Coastguard Worker 		case PIPE_B:
873*d83cc019SAndroid Build Coastguard Worker 			batch[6] |= MI_WAIT_FOR_PIPE_B_VBLANK;
874*d83cc019SAndroid Build Coastguard Worker 			batch[5] = ~(1 << 11);
875*d83cc019SAndroid Build Coastguard Worker 			break;
876*d83cc019SAndroid Build Coastguard Worker 		case PIPE_C:
877*d83cc019SAndroid Build Coastguard Worker 			batch[6] |= MI_WAIT_FOR_PIPE_C_VBLANK;
878*d83cc019SAndroid Build Coastguard Worker 			batch[5] = ~(1 << 21);
879*d83cc019SAndroid Build Coastguard Worker 			break;
880*d83cc019SAndroid Build Coastguard Worker 		default:
881*d83cc019SAndroid Build Coastguard Worker 			continue;
882*d83cc019SAndroid Build Coastguard Worker 		}
883*d83cc019SAndroid Build Coastguard Worker 
884*d83cc019SAndroid Build Coastguard Worker 		gem_write(gem_fd, obj.handle, 0, batch, sizeof(batch));
885*d83cc019SAndroid Build Coastguard Worker 
886*d83cc019SAndroid Build Coastguard Worker 		data.pipe = p;
887*d83cc019SAndroid Build Coastguard Worker 		prepare_crtc(&data, gem_fd, output);
888*d83cc019SAndroid Build Coastguard Worker 
889*d83cc019SAndroid Build Coastguard Worker 		fd = open_pmu(I915_PMU_ENGINE_WAIT(e->class, e->instance));
890*d83cc019SAndroid Build Coastguard Worker 
891*d83cc019SAndroid Build Coastguard Worker 		val[0] = pmu_read_single(fd);
892*d83cc019SAndroid Build Coastguard Worker 
893*d83cc019SAndroid Build Coastguard Worker 		igt_fork_helper(&waiter) {
894*d83cc019SAndroid Build Coastguard Worker 			const uint32_t pipe_id_flag =
895*d83cc019SAndroid Build Coastguard Worker 					kmstest_get_vbl_flag(data.pipe);
896*d83cc019SAndroid Build Coastguard Worker 
897*d83cc019SAndroid Build Coastguard Worker 			for (;;) {
898*d83cc019SAndroid Build Coastguard Worker 				union drm_wait_vblank vbl = { };
899*d83cc019SAndroid Build Coastguard Worker 
900*d83cc019SAndroid Build Coastguard Worker 				vbl.request.type = DRM_VBLANK_RELATIVE;
901*d83cc019SAndroid Build Coastguard Worker 				vbl.request.type |= pipe_id_flag;
902*d83cc019SAndroid Build Coastguard Worker 				vbl.request.sequence = 1;
903*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq(wait_vblank(gem_fd, &vbl), 0);
904*d83cc019SAndroid Build Coastguard Worker 			}
905*d83cc019SAndroid Build Coastguard Worker 		}
906*d83cc019SAndroid Build Coastguard Worker 
907*d83cc019SAndroid Build Coastguard Worker 		for (unsigned int frame = 0; frame < frames; frame++) {
908*d83cc019SAndroid Build Coastguard Worker 			gem_execbuf(gem_fd, &eb);
909*d83cc019SAndroid Build Coastguard Worker 			gem_sync(gem_fd, obj.handle);
910*d83cc019SAndroid Build Coastguard Worker 		}
911*d83cc019SAndroid Build Coastguard Worker 
912*d83cc019SAndroid Build Coastguard Worker 		igt_stop_helper(&waiter);
913*d83cc019SAndroid Build Coastguard Worker 
914*d83cc019SAndroid Build Coastguard Worker 		val[1] = pmu_read_single(fd);
915*d83cc019SAndroid Build Coastguard Worker 
916*d83cc019SAndroid Build Coastguard Worker 		close(fd);
917*d83cc019SAndroid Build Coastguard Worker 
918*d83cc019SAndroid Build Coastguard Worker 		cleanup_crtc(&data, gem_fd, output);
919*d83cc019SAndroid Build Coastguard Worker 		valid_tests++;
920*d83cc019SAndroid Build Coastguard Worker 
921*d83cc019SAndroid Build Coastguard Worker 		igt_assert(val[1] - val[0] > 0);
922*d83cc019SAndroid Build Coastguard Worker 	}
923*d83cc019SAndroid Build Coastguard Worker 
924*d83cc019SAndroid Build Coastguard Worker 	gem_close(gem_fd, obj.handle);
925*d83cc019SAndroid Build Coastguard Worker 
926*d83cc019SAndroid Build Coastguard Worker 	igt_require_f(valid_tests,
927*d83cc019SAndroid Build Coastguard Worker 		      "no valid crtc/connector combinations found\n");
928*d83cc019SAndroid Build Coastguard Worker }
929*d83cc019SAndroid Build Coastguard Worker 
930*d83cc019SAndroid Build Coastguard Worker static void
multi_client(int gem_fd,const struct intel_execution_engine2 * e)931*d83cc019SAndroid Build Coastguard Worker multi_client(int gem_fd, const struct intel_execution_engine2 *e)
932*d83cc019SAndroid Build Coastguard Worker {
933*d83cc019SAndroid Build Coastguard Worker 	uint64_t config = I915_PMU_ENGINE_BUSY(e->class, e->instance);
934*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept[2];
935*d83cc019SAndroid Build Coastguard Worker 	uint64_t val[2], ts[2], perf_slept[2];
936*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
937*d83cc019SAndroid Build Coastguard Worker 	int fd[2];
938*d83cc019SAndroid Build Coastguard Worker 
939*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
940*d83cc019SAndroid Build Coastguard Worker 
941*d83cc019SAndroid Build Coastguard Worker 	fd[0] = open_pmu(config);
942*d83cc019SAndroid Build Coastguard Worker 
943*d83cc019SAndroid Build Coastguard Worker 	/*
944*d83cc019SAndroid Build Coastguard Worker 	 * Second PMU client which is initialized after the first one,
945*d83cc019SAndroid Build Coastguard Worker 	 * and exists before it, should not affect accounting as reported
946*d83cc019SAndroid Build Coastguard Worker 	 * in the first client.
947*d83cc019SAndroid Build Coastguard Worker 	 */
948*d83cc019SAndroid Build Coastguard Worker 	fd[1] = open_pmu(config);
949*d83cc019SAndroid Build Coastguard Worker 
950*d83cc019SAndroid Build Coastguard Worker 	spin = spin_sync(gem_fd, 0, e);
951*d83cc019SAndroid Build Coastguard Worker 
952*d83cc019SAndroid Build Coastguard Worker 	val[0] = val[1] = __pmu_read_single(fd[0], &ts[0]);
953*d83cc019SAndroid Build Coastguard Worker 	slept[1] = measured_usleep(batch_duration_ns / 1000);
954*d83cc019SAndroid Build Coastguard Worker 	val[1] = __pmu_read_single(fd[1], &ts[1]) - val[1];
955*d83cc019SAndroid Build Coastguard Worker 	perf_slept[1] = ts[1] - ts[0];
956*d83cc019SAndroid Build Coastguard Worker 	igt_debug("slept=%lu perf=%"PRIu64"\n", slept[1], perf_slept[1]);
957*d83cc019SAndroid Build Coastguard Worker 	close(fd[1]);
958*d83cc019SAndroid Build Coastguard Worker 
959*d83cc019SAndroid Build Coastguard Worker 	slept[0] = measured_usleep(batch_duration_ns / 1000) + slept[1];
960*d83cc019SAndroid Build Coastguard Worker 	val[0] = __pmu_read_single(fd[0], &ts[1]) - val[0];
961*d83cc019SAndroid Build Coastguard Worker 	perf_slept[0] = ts[1] - ts[0];
962*d83cc019SAndroid Build Coastguard Worker 	igt_debug("slept=%lu perf=%"PRIu64"\n", slept[0], perf_slept[0]);
963*d83cc019SAndroid Build Coastguard Worker 
964*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(spin);
965*d83cc019SAndroid Build Coastguard Worker 	gem_sync(gem_fd, spin->handle);
966*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin);
967*d83cc019SAndroid Build Coastguard Worker 	close(fd[0]);
968*d83cc019SAndroid Build Coastguard Worker 
969*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val[0], perf_slept[0], tolerance);
970*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val[1], perf_slept[1], tolerance);
971*d83cc019SAndroid Build Coastguard Worker }
972*d83cc019SAndroid Build Coastguard Worker 
973*d83cc019SAndroid Build Coastguard Worker /**
974*d83cc019SAndroid Build Coastguard Worker  * Tests that i915 PMU corectly errors out in invalid initialization.
975*d83cc019SAndroid Build Coastguard Worker  * i915 PMU is uncore PMU, thus:
976*d83cc019SAndroid Build Coastguard Worker  *  - sampling period is not supported
977*d83cc019SAndroid Build Coastguard Worker  *  - pid > 0 is not supported since we can't count per-process (we count
978*d83cc019SAndroid Build Coastguard Worker  *    per whole system)
979*d83cc019SAndroid Build Coastguard Worker  *  - cpu != 0 is not supported since i915 PMU only allows running on one cpu
980*d83cc019SAndroid Build Coastguard Worker  *    and that is normally CPU0.
981*d83cc019SAndroid Build Coastguard Worker  */
invalid_init(void)982*d83cc019SAndroid Build Coastguard Worker static void invalid_init(void)
983*d83cc019SAndroid Build Coastguard Worker {
984*d83cc019SAndroid Build Coastguard Worker 	struct perf_event_attr attr;
985*d83cc019SAndroid Build Coastguard Worker 
986*d83cc019SAndroid Build Coastguard Worker #define ATTR_INIT() \
987*d83cc019SAndroid Build Coastguard Worker do { \
988*d83cc019SAndroid Build Coastguard Worker 	memset(&attr, 0, sizeof (attr)); \
989*d83cc019SAndroid Build Coastguard Worker 	attr.config = I915_PMU_ENGINE_BUSY(I915_ENGINE_CLASS_RENDER, 0); \
990*d83cc019SAndroid Build Coastguard Worker 	attr.type = i915_type_id(); \
991*d83cc019SAndroid Build Coastguard Worker 	igt_assert(attr.type != 0); \
992*d83cc019SAndroid Build Coastguard Worker 	errno = 0; \
993*d83cc019SAndroid Build Coastguard Worker } while(0)
994*d83cc019SAndroid Build Coastguard Worker 
995*d83cc019SAndroid Build Coastguard Worker 	ATTR_INIT();
996*d83cc019SAndroid Build Coastguard Worker 	attr.sample_period = 100;
997*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(perf_event_open(&attr, -1, 0, -1, 0), -1);
998*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(errno, EINVAL);
999*d83cc019SAndroid Build Coastguard Worker 
1000*d83cc019SAndroid Build Coastguard Worker 	ATTR_INIT();
1001*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(perf_event_open(&attr, 0, 0, -1, 0), -1);
1002*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(errno, EINVAL);
1003*d83cc019SAndroid Build Coastguard Worker 
1004*d83cc019SAndroid Build Coastguard Worker 	ATTR_INIT();
1005*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(perf_event_open(&attr, -1, 1, -1, 0), -1);
1006*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(errno, EINVAL);
1007*d83cc019SAndroid Build Coastguard Worker }
1008*d83cc019SAndroid Build Coastguard Worker 
init_other(unsigned int i,bool valid)1009*d83cc019SAndroid Build Coastguard Worker static void init_other(unsigned int i, bool valid)
1010*d83cc019SAndroid Build Coastguard Worker {
1011*d83cc019SAndroid Build Coastguard Worker 	int fd;
1012*d83cc019SAndroid Build Coastguard Worker 
1013*d83cc019SAndroid Build Coastguard Worker 	fd = perf_i915_open(__I915_PMU_OTHER(i));
1014*d83cc019SAndroid Build Coastguard Worker 	igt_require(!(fd < 0 && errno == ENODEV));
1015*d83cc019SAndroid Build Coastguard Worker 	if (valid) {
1016*d83cc019SAndroid Build Coastguard Worker 		igt_assert(fd >= 0);
1017*d83cc019SAndroid Build Coastguard Worker 	} else {
1018*d83cc019SAndroid Build Coastguard Worker 		igt_assert(fd < 0);
1019*d83cc019SAndroid Build Coastguard Worker 		return;
1020*d83cc019SAndroid Build Coastguard Worker 	}
1021*d83cc019SAndroid Build Coastguard Worker 
1022*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1023*d83cc019SAndroid Build Coastguard Worker }
1024*d83cc019SAndroid Build Coastguard Worker 
read_other(unsigned int i,bool valid)1025*d83cc019SAndroid Build Coastguard Worker static void read_other(unsigned int i, bool valid)
1026*d83cc019SAndroid Build Coastguard Worker {
1027*d83cc019SAndroid Build Coastguard Worker 	int fd;
1028*d83cc019SAndroid Build Coastguard Worker 
1029*d83cc019SAndroid Build Coastguard Worker 	fd = perf_i915_open(__I915_PMU_OTHER(i));
1030*d83cc019SAndroid Build Coastguard Worker 	igt_require(!(fd < 0 && errno == ENODEV));
1031*d83cc019SAndroid Build Coastguard Worker 	if (valid) {
1032*d83cc019SAndroid Build Coastguard Worker 		igt_assert(fd >= 0);
1033*d83cc019SAndroid Build Coastguard Worker 	} else {
1034*d83cc019SAndroid Build Coastguard Worker 		igt_assert(fd < 0);
1035*d83cc019SAndroid Build Coastguard Worker 		return;
1036*d83cc019SAndroid Build Coastguard Worker 	}
1037*d83cc019SAndroid Build Coastguard Worker 
1038*d83cc019SAndroid Build Coastguard Worker 	(void)pmu_read_single(fd);
1039*d83cc019SAndroid Build Coastguard Worker 
1040*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1041*d83cc019SAndroid Build Coastguard Worker }
1042*d83cc019SAndroid Build Coastguard Worker 
cpu0_hotplug_support(void)1043*d83cc019SAndroid Build Coastguard Worker static bool cpu0_hotplug_support(void)
1044*d83cc019SAndroid Build Coastguard Worker {
1045*d83cc019SAndroid Build Coastguard Worker 	return access("/sys/devices/system/cpu/cpu0/online", W_OK) == 0;
1046*d83cc019SAndroid Build Coastguard Worker }
1047*d83cc019SAndroid Build Coastguard Worker 
cpu_hotplug(int gem_fd)1048*d83cc019SAndroid Build Coastguard Worker static void cpu_hotplug(int gem_fd)
1049*d83cc019SAndroid Build Coastguard Worker {
1050*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin[2];
1051*d83cc019SAndroid Build Coastguard Worker 	uint64_t ts[2];
1052*d83cc019SAndroid Build Coastguard Worker 	uint64_t val;
1053*d83cc019SAndroid Build Coastguard Worker 	int link[2];
1054*d83cc019SAndroid Build Coastguard Worker 	int fd, ret;
1055*d83cc019SAndroid Build Coastguard Worker 	int cur = 0;
1056*d83cc019SAndroid Build Coastguard Worker 	char buf;
1057*d83cc019SAndroid Build Coastguard Worker 
1058*d83cc019SAndroid Build Coastguard Worker 	igt_require(cpu0_hotplug_support());
1059*d83cc019SAndroid Build Coastguard Worker 
1060*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_ENGINE_BUSY(I915_ENGINE_CLASS_RENDER, 0));
1061*d83cc019SAndroid Build Coastguard Worker 
1062*d83cc019SAndroid Build Coastguard Worker 	/*
1063*d83cc019SAndroid Build Coastguard Worker 	 * Create two spinners so test can ensure shorter gaps in engine
1064*d83cc019SAndroid Build Coastguard Worker 	 * busyness as it is terminating one and re-starting the other.
1065*d83cc019SAndroid Build Coastguard Worker 	 */
1066*d83cc019SAndroid Build Coastguard Worker 	spin[0] = igt_spin_new(gem_fd, .engine = I915_EXEC_DEFAULT);
1067*d83cc019SAndroid Build Coastguard Worker 	spin[1] = __igt_spin_new(gem_fd, .engine = I915_EXEC_DEFAULT);
1068*d83cc019SAndroid Build Coastguard Worker 
1069*d83cc019SAndroid Build Coastguard Worker 	val = __pmu_read_single(fd, &ts[0]);
1070*d83cc019SAndroid Build Coastguard Worker 
1071*d83cc019SAndroid Build Coastguard Worker 	ret = pipe2(link, O_NONBLOCK);
1072*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
1073*d83cc019SAndroid Build Coastguard Worker 
1074*d83cc019SAndroid Build Coastguard Worker 	/*
1075*d83cc019SAndroid Build Coastguard Worker 	 * Toggle online status of all the CPUs in a child process and ensure
1076*d83cc019SAndroid Build Coastguard Worker 	 * this has not affected busyness stats in the parent.
1077*d83cc019SAndroid Build Coastguard Worker 	 */
1078*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1079*d83cc019SAndroid Build Coastguard Worker 		int cpu = 0;
1080*d83cc019SAndroid Build Coastguard Worker 
1081*d83cc019SAndroid Build Coastguard Worker 		close(link[0]);
1082*d83cc019SAndroid Build Coastguard Worker 
1083*d83cc019SAndroid Build Coastguard Worker 		for (;;) {
1084*d83cc019SAndroid Build Coastguard Worker 			char name[128];
1085*d83cc019SAndroid Build Coastguard Worker 			int cpufd;
1086*d83cc019SAndroid Build Coastguard Worker 
1087*d83cc019SAndroid Build Coastguard Worker 			igt_assert_lt(snprintf(name, sizeof(name),
1088*d83cc019SAndroid Build Coastguard Worker 					       "/sys/devices/system/cpu/cpu%d/online",
1089*d83cc019SAndroid Build Coastguard Worker 					       cpu), sizeof(name));
1090*d83cc019SAndroid Build Coastguard Worker 			cpufd = open(name, O_WRONLY);
1091*d83cc019SAndroid Build Coastguard Worker 			if (cpufd == -1) {
1092*d83cc019SAndroid Build Coastguard Worker 				igt_assert(cpu > 0);
1093*d83cc019SAndroid Build Coastguard Worker 				/*
1094*d83cc019SAndroid Build Coastguard Worker 				 * Signal parent that we cycled through all
1095*d83cc019SAndroid Build Coastguard Worker 				 * CPUs and we are done.
1096*d83cc019SAndroid Build Coastguard Worker 				 */
1097*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq(write(link[1], "*", 1), 1);
1098*d83cc019SAndroid Build Coastguard Worker 				break;
1099*d83cc019SAndroid Build Coastguard Worker 			}
1100*d83cc019SAndroid Build Coastguard Worker 
1101*d83cc019SAndroid Build Coastguard Worker 			/* Offline followed by online a CPU. */
1102*d83cc019SAndroid Build Coastguard Worker 
1103*d83cc019SAndroid Build Coastguard Worker 			ret = write(cpufd, "0", 2);
1104*d83cc019SAndroid Build Coastguard Worker 			if (ret < 0) {
1105*d83cc019SAndroid Build Coastguard Worker 				/*
1106*d83cc019SAndroid Build Coastguard Worker 				 * If we failed to offline a CPU we don't want
1107*d83cc019SAndroid Build Coastguard Worker 				 * to proceed.
1108*d83cc019SAndroid Build Coastguard Worker 				 */
1109*d83cc019SAndroid Build Coastguard Worker 				igt_warn("Failed to offline cpu%u! (%d)\n",
1110*d83cc019SAndroid Build Coastguard Worker 					 cpu, errno);
1111*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq(write(link[1], "s", 1), 1);
1112*d83cc019SAndroid Build Coastguard Worker 				break;
1113*d83cc019SAndroid Build Coastguard Worker 			}
1114*d83cc019SAndroid Build Coastguard Worker 
1115*d83cc019SAndroid Build Coastguard Worker 			usleep(1e6);
1116*d83cc019SAndroid Build Coastguard Worker 
1117*d83cc019SAndroid Build Coastguard Worker 			ret = write(cpufd, "1", 2);
1118*d83cc019SAndroid Build Coastguard Worker 			if (ret < 0) {
1119*d83cc019SAndroid Build Coastguard Worker 				/*
1120*d83cc019SAndroid Build Coastguard Worker 				 * Failed to bring a CPU back online is fatal
1121*d83cc019SAndroid Build Coastguard Worker 				 * for the sanity of a test run so stop further
1122*d83cc019SAndroid Build Coastguard Worker 				 * testing.
1123*d83cc019SAndroid Build Coastguard Worker 				 */
1124*d83cc019SAndroid Build Coastguard Worker 				igt_warn("Failed to online cpu%u! (%d)\n",
1125*d83cc019SAndroid Build Coastguard Worker 					 cpu, errno);
1126*d83cc019SAndroid Build Coastguard Worker 				igt_fatal_error();
1127*d83cc019SAndroid Build Coastguard Worker 			}
1128*d83cc019SAndroid Build Coastguard Worker 
1129*d83cc019SAndroid Build Coastguard Worker 			close(cpufd);
1130*d83cc019SAndroid Build Coastguard Worker 			cpu++;
1131*d83cc019SAndroid Build Coastguard Worker 		}
1132*d83cc019SAndroid Build Coastguard Worker 	}
1133*d83cc019SAndroid Build Coastguard Worker 
1134*d83cc019SAndroid Build Coastguard Worker 	close(link[1]);
1135*d83cc019SAndroid Build Coastguard Worker 
1136*d83cc019SAndroid Build Coastguard Worker 	/*
1137*d83cc019SAndroid Build Coastguard Worker 	 * Very long batches can be declared as GPU hangs so emit shorter ones
1138*d83cc019SAndroid Build Coastguard Worker 	 * until the CPU core shuffler finishes one loop.
1139*d83cc019SAndroid Build Coastguard Worker 	 */
1140*d83cc019SAndroid Build Coastguard Worker 	for (;;) {
1141*d83cc019SAndroid Build Coastguard Worker 		usleep(500e3);
1142*d83cc019SAndroid Build Coastguard Worker 		end_spin(gem_fd, spin[cur], 0);
1143*d83cc019SAndroid Build Coastguard Worker 
1144*d83cc019SAndroid Build Coastguard Worker 		/* Check if the child is signaling completion. */
1145*d83cc019SAndroid Build Coastguard Worker 		ret = read(link[0], &buf, 1);
1146*d83cc019SAndroid Build Coastguard Worker 		if ( ret == 1 || (ret < 0 && errno != EAGAIN))
1147*d83cc019SAndroid Build Coastguard Worker 			break;
1148*d83cc019SAndroid Build Coastguard Worker 
1149*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(gem_fd, spin[cur]);
1150*d83cc019SAndroid Build Coastguard Worker 		spin[cur] = __igt_spin_new(gem_fd,
1151*d83cc019SAndroid Build Coastguard Worker 					   .engine = I915_EXEC_DEFAULT);
1152*d83cc019SAndroid Build Coastguard Worker 		cur ^= 1;
1153*d83cc019SAndroid Build Coastguard Worker 	}
1154*d83cc019SAndroid Build Coastguard Worker 
1155*d83cc019SAndroid Build Coastguard Worker 	val = __pmu_read_single(fd, &ts[1]) - val;
1156*d83cc019SAndroid Build Coastguard Worker 
1157*d83cc019SAndroid Build Coastguard Worker 	end_spin(gem_fd, spin[0], FLAG_SYNC);
1158*d83cc019SAndroid Build Coastguard Worker 	end_spin(gem_fd, spin[1], FLAG_SYNC);
1159*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin[0]);
1160*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin[1]);
1161*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1162*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1163*d83cc019SAndroid Build Coastguard Worker 	close(link[0]);
1164*d83cc019SAndroid Build Coastguard Worker 
1165*d83cc019SAndroid Build Coastguard Worker 	/* Skip if child signals a problem with offlining a CPU. */
1166*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on(buf == 's');
1167*d83cc019SAndroid Build Coastguard Worker 
1168*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(val, ts[1] - ts[0], tolerance);
1169*d83cc019SAndroid Build Coastguard Worker }
1170*d83cc019SAndroid Build Coastguard Worker 
1171*d83cc019SAndroid Build Coastguard Worker static void
test_interrupts(int gem_fd)1172*d83cc019SAndroid Build Coastguard Worker test_interrupts(int gem_fd)
1173*d83cc019SAndroid Build Coastguard Worker {
1174*d83cc019SAndroid Build Coastguard Worker 	const unsigned int test_duration_ms = 1000;
1175*d83cc019SAndroid Build Coastguard Worker 	const int target = 30;
1176*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin[target];
1177*d83cc019SAndroid Build Coastguard Worker 	struct pollfd pfd;
1178*d83cc019SAndroid Build Coastguard Worker 	uint64_t idle, busy;
1179*d83cc019SAndroid Build Coastguard Worker 	int fence_fd;
1180*d83cc019SAndroid Build Coastguard Worker 	int fd;
1181*d83cc019SAndroid Build Coastguard Worker 
1182*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
1183*d83cc019SAndroid Build Coastguard Worker 
1184*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_INTERRUPTS);
1185*d83cc019SAndroid Build Coastguard Worker 
1186*d83cc019SAndroid Build Coastguard Worker 	/* Queue spinning batches. */
1187*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < target; i++) {
1188*d83cc019SAndroid Build Coastguard Worker 		spin[i] = __igt_spin_new(gem_fd,
1189*d83cc019SAndroid Build Coastguard Worker 					 .engine = I915_EXEC_DEFAULT,
1190*d83cc019SAndroid Build Coastguard Worker 					 .flags = IGT_SPIN_FENCE_OUT);
1191*d83cc019SAndroid Build Coastguard Worker 		if (i == 0) {
1192*d83cc019SAndroid Build Coastguard Worker 			fence_fd = spin[i]->out_fence;
1193*d83cc019SAndroid Build Coastguard Worker 		} else {
1194*d83cc019SAndroid Build Coastguard Worker 			int old_fd = fence_fd;
1195*d83cc019SAndroid Build Coastguard Worker 
1196*d83cc019SAndroid Build Coastguard Worker 			fence_fd = sync_fence_merge(old_fd,
1197*d83cc019SAndroid Build Coastguard Worker 						    spin[i]->out_fence);
1198*d83cc019SAndroid Build Coastguard Worker 			close(old_fd);
1199*d83cc019SAndroid Build Coastguard Worker 		}
1200*d83cc019SAndroid Build Coastguard Worker 
1201*d83cc019SAndroid Build Coastguard Worker 		igt_assert(fence_fd >= 0);
1202*d83cc019SAndroid Build Coastguard Worker 	}
1203*d83cc019SAndroid Build Coastguard Worker 
1204*d83cc019SAndroid Build Coastguard Worker 	/* Wait for idle state. */
1205*d83cc019SAndroid Build Coastguard Worker 	idle = pmu_read_single(fd);
1206*d83cc019SAndroid Build Coastguard Worker 	do {
1207*d83cc019SAndroid Build Coastguard Worker 		busy = idle;
1208*d83cc019SAndroid Build Coastguard Worker 		usleep(1e3);
1209*d83cc019SAndroid Build Coastguard Worker 		idle = pmu_read_single(fd);
1210*d83cc019SAndroid Build Coastguard Worker 	} while (idle != busy);
1211*d83cc019SAndroid Build Coastguard Worker 
1212*d83cc019SAndroid Build Coastguard Worker 	/* Arm batch expiration. */
1213*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < target; i++)
1214*d83cc019SAndroid Build Coastguard Worker 		igt_spin_set_timeout(spin[i],
1215*d83cc019SAndroid Build Coastguard Worker 				     (i + 1) * test_duration_ms * 1e6
1216*d83cc019SAndroid Build Coastguard Worker 				     / target);
1217*d83cc019SAndroid Build Coastguard Worker 
1218*d83cc019SAndroid Build Coastguard Worker 	/* Wait for last batch to finish. */
1219*d83cc019SAndroid Build Coastguard Worker 	pfd.events = POLLIN;
1220*d83cc019SAndroid Build Coastguard Worker 	pfd.fd = fence_fd;
1221*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(poll(&pfd, 1, 2 * test_duration_ms), 1);
1222*d83cc019SAndroid Build Coastguard Worker 	close(fence_fd);
1223*d83cc019SAndroid Build Coastguard Worker 
1224*d83cc019SAndroid Build Coastguard Worker 	/* Free batches. */
1225*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < target; i++)
1226*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(gem_fd, spin[i]);
1227*d83cc019SAndroid Build Coastguard Worker 
1228*d83cc019SAndroid Build Coastguard Worker 	/* Check at least as many interrupts has been generated. */
1229*d83cc019SAndroid Build Coastguard Worker 	busy = pmu_read_single(fd) - idle;
1230*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1231*d83cc019SAndroid Build Coastguard Worker 
1232*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(target, busy);
1233*d83cc019SAndroid Build Coastguard Worker }
1234*d83cc019SAndroid Build Coastguard Worker 
1235*d83cc019SAndroid Build Coastguard Worker static void
test_interrupts_sync(int gem_fd)1236*d83cc019SAndroid Build Coastguard Worker test_interrupts_sync(int gem_fd)
1237*d83cc019SAndroid Build Coastguard Worker {
1238*d83cc019SAndroid Build Coastguard Worker 	const unsigned int test_duration_ms = 1000;
1239*d83cc019SAndroid Build Coastguard Worker 	const int target = 30;
1240*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin[target];
1241*d83cc019SAndroid Build Coastguard Worker 	struct pollfd pfd;
1242*d83cc019SAndroid Build Coastguard Worker 	uint64_t idle, busy;
1243*d83cc019SAndroid Build Coastguard Worker 	int fd;
1244*d83cc019SAndroid Build Coastguard Worker 
1245*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
1246*d83cc019SAndroid Build Coastguard Worker 
1247*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_INTERRUPTS);
1248*d83cc019SAndroid Build Coastguard Worker 
1249*d83cc019SAndroid Build Coastguard Worker 	/* Queue spinning batches. */
1250*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < target; i++)
1251*d83cc019SAndroid Build Coastguard Worker 		spin[i] = __igt_spin_new(gem_fd,
1252*d83cc019SAndroid Build Coastguard Worker 					 .flags = IGT_SPIN_FENCE_OUT);
1253*d83cc019SAndroid Build Coastguard Worker 
1254*d83cc019SAndroid Build Coastguard Worker 	/* Wait for idle state. */
1255*d83cc019SAndroid Build Coastguard Worker 	idle = pmu_read_single(fd);
1256*d83cc019SAndroid Build Coastguard Worker 	do {
1257*d83cc019SAndroid Build Coastguard Worker 		busy = idle;
1258*d83cc019SAndroid Build Coastguard Worker 		usleep(1e3);
1259*d83cc019SAndroid Build Coastguard Worker 		idle = pmu_read_single(fd);
1260*d83cc019SAndroid Build Coastguard Worker 	} while (idle != busy);
1261*d83cc019SAndroid Build Coastguard Worker 
1262*d83cc019SAndroid Build Coastguard Worker 	/* Process the batch queue. */
1263*d83cc019SAndroid Build Coastguard Worker 	pfd.events = POLLIN;
1264*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < target; i++) {
1265*d83cc019SAndroid Build Coastguard Worker 		const unsigned int timeout_ms = test_duration_ms / target;
1266*d83cc019SAndroid Build Coastguard Worker 
1267*d83cc019SAndroid Build Coastguard Worker 		pfd.fd = spin[i]->out_fence;
1268*d83cc019SAndroid Build Coastguard Worker 		igt_spin_set_timeout(spin[i], timeout_ms * 1e6);
1269*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(poll(&pfd, 1, 2 * timeout_ms), 1);
1270*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(gem_fd, spin[i]);
1271*d83cc019SAndroid Build Coastguard Worker 	}
1272*d83cc019SAndroid Build Coastguard Worker 
1273*d83cc019SAndroid Build Coastguard Worker 	/* Check at least as many interrupts has been generated. */
1274*d83cc019SAndroid Build Coastguard Worker 	busy = pmu_read_single(fd) - idle;
1275*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1276*d83cc019SAndroid Build Coastguard Worker 
1277*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(target, busy);
1278*d83cc019SAndroid Build Coastguard Worker }
1279*d83cc019SAndroid Build Coastguard Worker 
1280*d83cc019SAndroid Build Coastguard Worker static void
test_frequency(int gem_fd)1281*d83cc019SAndroid Build Coastguard Worker test_frequency(int gem_fd)
1282*d83cc019SAndroid Build Coastguard Worker {
1283*d83cc019SAndroid Build Coastguard Worker 	uint32_t min_freq, max_freq, boost_freq;
1284*d83cc019SAndroid Build Coastguard Worker 	uint64_t val[2], start[2], slept;
1285*d83cc019SAndroid Build Coastguard Worker 	double min[2], max[2];
1286*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *spin;
1287*d83cc019SAndroid Build Coastguard Worker 	int fd, sysfs;
1288*d83cc019SAndroid Build Coastguard Worker 
1289*d83cc019SAndroid Build Coastguard Worker 	sysfs = igt_sysfs_open(gem_fd);
1290*d83cc019SAndroid Build Coastguard Worker 	igt_require(sysfs >= 0);
1291*d83cc019SAndroid Build Coastguard Worker 
1292*d83cc019SAndroid Build Coastguard Worker 	min_freq = igt_sysfs_get_u32(sysfs, "gt_RPn_freq_mhz");
1293*d83cc019SAndroid Build Coastguard Worker 	max_freq = igt_sysfs_get_u32(sysfs, "gt_RP0_freq_mhz");
1294*d83cc019SAndroid Build Coastguard Worker 	boost_freq = igt_sysfs_get_u32(sysfs, "gt_boost_freq_mhz");
1295*d83cc019SAndroid Build Coastguard Worker 	igt_info("Frequency: min=%u, max=%u, boost=%u MHz\n",
1296*d83cc019SAndroid Build Coastguard Worker 		 min_freq, max_freq, boost_freq);
1297*d83cc019SAndroid Build Coastguard Worker 	igt_require(min_freq > 0 && max_freq > 0 && boost_freq > 0);
1298*d83cc019SAndroid Build Coastguard Worker 	igt_require(max_freq > min_freq);
1299*d83cc019SAndroid Build Coastguard Worker 	igt_require(boost_freq > min_freq);
1300*d83cc019SAndroid Build Coastguard Worker 
1301*d83cc019SAndroid Build Coastguard Worker 	fd = open_group(I915_PMU_REQUESTED_FREQUENCY, -1);
1302*d83cc019SAndroid Build Coastguard Worker 	open_group(I915_PMU_ACTUAL_FREQUENCY, fd);
1303*d83cc019SAndroid Build Coastguard Worker 
1304*d83cc019SAndroid Build Coastguard Worker 	/*
1305*d83cc019SAndroid Build Coastguard Worker 	 * Set GPU to min frequency and read PMU counters.
1306*d83cc019SAndroid Build Coastguard Worker 	 */
1307*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_set_u32(sysfs, "gt_min_freq_mhz", min_freq));
1308*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_get_u32(sysfs, "gt_min_freq_mhz") == min_freq);
1309*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_set_u32(sysfs, "gt_max_freq_mhz", min_freq));
1310*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_get_u32(sysfs, "gt_max_freq_mhz") == min_freq);
1311*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_set_u32(sysfs, "gt_boost_freq_mhz", min_freq));
1312*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_get_u32(sysfs, "gt_boost_freq_mhz") == min_freq);
1313*d83cc019SAndroid Build Coastguard Worker 
1314*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd); /* Idle to be sure the change takes effect */
1315*d83cc019SAndroid Build Coastguard Worker 	spin = spin_sync_flags(gem_fd, 0, I915_EXEC_DEFAULT);
1316*d83cc019SAndroid Build Coastguard Worker 
1317*d83cc019SAndroid Build Coastguard Worker 	slept = pmu_read_multi(fd, 2, start);
1318*d83cc019SAndroid Build Coastguard Worker 	measured_usleep(batch_duration_ns / 1000);
1319*d83cc019SAndroid Build Coastguard Worker 	slept = pmu_read_multi(fd, 2, val) - slept;
1320*d83cc019SAndroid Build Coastguard Worker 
1321*d83cc019SAndroid Build Coastguard Worker 	min[0] = 1e9*(val[0] - start[0]) / slept;
1322*d83cc019SAndroid Build Coastguard Worker 	min[1] = 1e9*(val[1] - start[1]) / slept;
1323*d83cc019SAndroid Build Coastguard Worker 
1324*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin);
1325*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd); /* Don't leak busy bo into the next phase */
1326*d83cc019SAndroid Build Coastguard Worker 
1327*d83cc019SAndroid Build Coastguard Worker 	usleep(1e6);
1328*d83cc019SAndroid Build Coastguard Worker 
1329*d83cc019SAndroid Build Coastguard Worker 	/*
1330*d83cc019SAndroid Build Coastguard Worker 	 * Set GPU to max frequency and read PMU counters.
1331*d83cc019SAndroid Build Coastguard Worker 	 */
1332*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_set_u32(sysfs, "gt_max_freq_mhz", max_freq));
1333*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_get_u32(sysfs, "gt_max_freq_mhz") == max_freq);
1334*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_set_u32(sysfs, "gt_boost_freq_mhz", boost_freq));
1335*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_get_u32(sysfs, "gt_boost_freq_mhz") == boost_freq);
1336*d83cc019SAndroid Build Coastguard Worker 
1337*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_set_u32(sysfs, "gt_min_freq_mhz", max_freq));
1338*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_sysfs_get_u32(sysfs, "gt_min_freq_mhz") == max_freq);
1339*d83cc019SAndroid Build Coastguard Worker 
1340*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
1341*d83cc019SAndroid Build Coastguard Worker 	spin = spin_sync_flags(gem_fd, 0, I915_EXEC_DEFAULT);
1342*d83cc019SAndroid Build Coastguard Worker 
1343*d83cc019SAndroid Build Coastguard Worker 	slept = pmu_read_multi(fd, 2, start);
1344*d83cc019SAndroid Build Coastguard Worker 	measured_usleep(batch_duration_ns / 1000);
1345*d83cc019SAndroid Build Coastguard Worker 	slept = pmu_read_multi(fd, 2, val) - slept;
1346*d83cc019SAndroid Build Coastguard Worker 
1347*d83cc019SAndroid Build Coastguard Worker 	max[0] = 1e9*(val[0] - start[0]) / slept;
1348*d83cc019SAndroid Build Coastguard Worker 	max[1] = 1e9*(val[1] - start[1]) / slept;
1349*d83cc019SAndroid Build Coastguard Worker 
1350*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(gem_fd, spin);
1351*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
1352*d83cc019SAndroid Build Coastguard Worker 
1353*d83cc019SAndroid Build Coastguard Worker 	/*
1354*d83cc019SAndroid Build Coastguard Worker 	 * Restore min/max.
1355*d83cc019SAndroid Build Coastguard Worker 	 */
1356*d83cc019SAndroid Build Coastguard Worker 	igt_sysfs_set_u32(sysfs, "gt_min_freq_mhz", min_freq);
1357*d83cc019SAndroid Build Coastguard Worker 	if (igt_sysfs_get_u32(sysfs, "gt_min_freq_mhz") != min_freq)
1358*d83cc019SAndroid Build Coastguard Worker 		igt_warn("Unable to restore min frequency to saved value [%u MHz], now %u MHz\n",
1359*d83cc019SAndroid Build Coastguard Worker 			 min_freq, igt_sysfs_get_u32(sysfs, "gt_min_freq_mhz"));
1360*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1361*d83cc019SAndroid Build Coastguard Worker 
1362*d83cc019SAndroid Build Coastguard Worker 	igt_info("Min frequency: requested %.1f, actual %.1f\n",
1363*d83cc019SAndroid Build Coastguard Worker 		 min[0], min[1]);
1364*d83cc019SAndroid Build Coastguard Worker 	igt_info("Max frequency: requested %.1f, actual %.1f\n",
1365*d83cc019SAndroid Build Coastguard Worker 		 max[0], max[1]);
1366*d83cc019SAndroid Build Coastguard Worker 
1367*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(min[0], min_freq, tolerance);
1368*d83cc019SAndroid Build Coastguard Worker 	/*
1369*d83cc019SAndroid Build Coastguard Worker 	 * On thermally throttled devices we cannot be sure maximum frequency
1370*d83cc019SAndroid Build Coastguard Worker 	 * can be reached so use larger tolerance downards.
1371*d83cc019SAndroid Build Coastguard Worker 	 */
1372*d83cc019SAndroid Build Coastguard Worker 	__assert_within_epsilon(max[0], max_freq, tolerance, 0.15f);
1373*d83cc019SAndroid Build Coastguard Worker }
1374*d83cc019SAndroid Build Coastguard Worker 
wait_for_rc6(int fd)1375*d83cc019SAndroid Build Coastguard Worker static bool wait_for_rc6(int fd)
1376*d83cc019SAndroid Build Coastguard Worker {
1377*d83cc019SAndroid Build Coastguard Worker 	struct timespec tv = {};
1378*d83cc019SAndroid Build Coastguard Worker 	uint64_t start, now;
1379*d83cc019SAndroid Build Coastguard Worker 
1380*d83cc019SAndroid Build Coastguard Worker 	/* First wait for roughly an RC6 Evaluation Interval */
1381*d83cc019SAndroid Build Coastguard Worker 	usleep(160 * 1000);
1382*d83cc019SAndroid Build Coastguard Worker 
1383*d83cc019SAndroid Build Coastguard Worker 	/* Then poll for RC6 to start ticking */
1384*d83cc019SAndroid Build Coastguard Worker 	now = pmu_read_single(fd);
1385*d83cc019SAndroid Build Coastguard Worker 	do {
1386*d83cc019SAndroid Build Coastguard Worker 		start = now;
1387*d83cc019SAndroid Build Coastguard Worker 		usleep(5000);
1388*d83cc019SAndroid Build Coastguard Worker 		now = pmu_read_single(fd);
1389*d83cc019SAndroid Build Coastguard Worker 		if (now - start > 1e6)
1390*d83cc019SAndroid Build Coastguard Worker 			return true;
1391*d83cc019SAndroid Build Coastguard Worker 	} while (!igt_seconds_elapsed(&tv));
1392*d83cc019SAndroid Build Coastguard Worker 
1393*d83cc019SAndroid Build Coastguard Worker 	return false;
1394*d83cc019SAndroid Build Coastguard Worker }
1395*d83cc019SAndroid Build Coastguard Worker 
1396*d83cc019SAndroid Build Coastguard Worker static void
test_rc6(int gem_fd,unsigned int flags)1397*d83cc019SAndroid Build Coastguard Worker test_rc6(int gem_fd, unsigned int flags)
1398*d83cc019SAndroid Build Coastguard Worker {
1399*d83cc019SAndroid Build Coastguard Worker 	int64_t duration_ns = 2e9;
1400*d83cc019SAndroid Build Coastguard Worker 	uint64_t idle, busy, prev, ts[2];
1401*d83cc019SAndroid Build Coastguard Worker 	unsigned long slept;
1402*d83cc019SAndroid Build Coastguard Worker 	int fd, fw;
1403*d83cc019SAndroid Build Coastguard Worker 
1404*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
1405*d83cc019SAndroid Build Coastguard Worker 
1406*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_RC6_RESIDENCY);
1407*d83cc019SAndroid Build Coastguard Worker 
1408*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_RUNTIME_PM) {
1409*d83cc019SAndroid Build Coastguard Worker 		drmModeRes *res;
1410*d83cc019SAndroid Build Coastguard Worker 
1411*d83cc019SAndroid Build Coastguard Worker 		res = drmModeGetResources(gem_fd);
1412*d83cc019SAndroid Build Coastguard Worker 		igt_require(res);
1413*d83cc019SAndroid Build Coastguard Worker 
1414*d83cc019SAndroid Build Coastguard Worker 		/* force all connectors off */
1415*d83cc019SAndroid Build Coastguard Worker 		kmstest_set_vt_graphics_mode();
1416*d83cc019SAndroid Build Coastguard Worker 		kmstest_unset_all_crtcs(gem_fd, res);
1417*d83cc019SAndroid Build Coastguard Worker 		drmModeFreeResources(res);
1418*d83cc019SAndroid Build Coastguard Worker 
1419*d83cc019SAndroid Build Coastguard Worker 		igt_require(igt_setup_runtime_pm());
1420*d83cc019SAndroid Build Coastguard Worker 		igt_require(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_SUSPENDED));
1421*d83cc019SAndroid Build Coastguard Worker 
1422*d83cc019SAndroid Build Coastguard Worker 		/*
1423*d83cc019SAndroid Build Coastguard Worker 		 * Sleep for a bit to see if once woken up estimated RC6 hasn't
1424*d83cc019SAndroid Build Coastguard Worker 		 * drifted to far in advance of real RC6.
1425*d83cc019SAndroid Build Coastguard Worker 		 */
1426*d83cc019SAndroid Build Coastguard Worker 		if (flags & FLAG_LONG) {
1427*d83cc019SAndroid Build Coastguard Worker 			pmu_read_single(fd);
1428*d83cc019SAndroid Build Coastguard Worker 			sleep(5);
1429*d83cc019SAndroid Build Coastguard Worker 			pmu_read_single(fd);
1430*d83cc019SAndroid Build Coastguard Worker 		}
1431*d83cc019SAndroid Build Coastguard Worker 	}
1432*d83cc019SAndroid Build Coastguard Worker 
1433*d83cc019SAndroid Build Coastguard Worker 	igt_require(wait_for_rc6(fd));
1434*d83cc019SAndroid Build Coastguard Worker 
1435*d83cc019SAndroid Build Coastguard Worker 	/* While idle check full RC6. */
1436*d83cc019SAndroid Build Coastguard Worker 	prev = __pmu_read_single(fd, &ts[0]);
1437*d83cc019SAndroid Build Coastguard Worker 	slept = measured_usleep(duration_ns / 1000);
1438*d83cc019SAndroid Build Coastguard Worker 	idle = __pmu_read_single(fd, &ts[1]);
1439*d83cc019SAndroid Build Coastguard Worker 	igt_debug("slept=%lu perf=%"PRIu64"\n", slept, ts[1] - ts[0]);
1440*d83cc019SAndroid Build Coastguard Worker 
1441*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(idle - prev, ts[1] - ts[0], tolerance);
1442*d83cc019SAndroid Build Coastguard Worker 
1443*d83cc019SAndroid Build Coastguard Worker 	/* Wake up device and check no RC6. */
1444*d83cc019SAndroid Build Coastguard Worker 	fw = igt_open_forcewake_handle(gem_fd);
1445*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fw >= 0);
1446*d83cc019SAndroid Build Coastguard Worker 	usleep(1e3); /* wait for the rc6 cycle counter to stop ticking */
1447*d83cc019SAndroid Build Coastguard Worker 
1448*d83cc019SAndroid Build Coastguard Worker 	prev = pmu_read_single(fd);
1449*d83cc019SAndroid Build Coastguard Worker 	usleep(duration_ns / 1000);
1450*d83cc019SAndroid Build Coastguard Worker 	busy = pmu_read_single(fd);
1451*d83cc019SAndroid Build Coastguard Worker 
1452*d83cc019SAndroid Build Coastguard Worker 	close(fw);
1453*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1454*d83cc019SAndroid Build Coastguard Worker 
1455*d83cc019SAndroid Build Coastguard Worker 	if (flags & TEST_RUNTIME_PM)
1456*d83cc019SAndroid Build Coastguard Worker 		igt_restore_runtime_pm();
1457*d83cc019SAndroid Build Coastguard Worker 
1458*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon(busy - prev, 0.0, tolerance);
1459*d83cc019SAndroid Build Coastguard Worker }
1460*d83cc019SAndroid Build Coastguard Worker 
1461*d83cc019SAndroid Build Coastguard Worker static void
test_enable_race(int gem_fd,const struct intel_execution_engine2 * e)1462*d83cc019SAndroid Build Coastguard Worker test_enable_race(int gem_fd, const struct intel_execution_engine2 *e)
1463*d83cc019SAndroid Build Coastguard Worker {
1464*d83cc019SAndroid Build Coastguard Worker 	uint64_t config = I915_PMU_ENGINE_BUSY(e->class, e->instance);
1465*d83cc019SAndroid Build Coastguard Worker 	struct igt_helper_process engine_load = { };
1466*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbend = MI_BATCH_BUFFER_END;
1467*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = { };
1468*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 eb = { };
1469*d83cc019SAndroid Build Coastguard Worker 	int fd;
1470*d83cc019SAndroid Build Coastguard Worker 
1471*d83cc019SAndroid Build Coastguard Worker 	igt_require(gem_has_execlists(gem_fd));
1472*d83cc019SAndroid Build Coastguard Worker 	igt_require(gem_context_has_engine(gem_fd, 0, e->flags));
1473*d83cc019SAndroid Build Coastguard Worker 
1474*d83cc019SAndroid Build Coastguard Worker 	obj.handle = gem_create(gem_fd, 4096);
1475*d83cc019SAndroid Build Coastguard Worker 	gem_write(gem_fd, obj.handle, 0, &bbend, sizeof(bbend));
1476*d83cc019SAndroid Build Coastguard Worker 
1477*d83cc019SAndroid Build Coastguard Worker 	eb.buffer_count = 1;
1478*d83cc019SAndroid Build Coastguard Worker 	eb.buffers_ptr = to_user_pointer(&obj);
1479*d83cc019SAndroid Build Coastguard Worker 	eb.flags = e->flags;
1480*d83cc019SAndroid Build Coastguard Worker 
1481*d83cc019SAndroid Build Coastguard Worker 	/*
1482*d83cc019SAndroid Build Coastguard Worker 	 * This test is probabilistic so run in a few times to increase the
1483*d83cc019SAndroid Build Coastguard Worker 	 * chance of hitting the race.
1484*d83cc019SAndroid Build Coastguard Worker 	 */
1485*d83cc019SAndroid Build Coastguard Worker 	igt_until_timeout(10) {
1486*d83cc019SAndroid Build Coastguard Worker 		/*
1487*d83cc019SAndroid Build Coastguard Worker 		 * Defeat the busy stats delayed disable, we need to guarantee
1488*d83cc019SAndroid Build Coastguard Worker 		 * we are the first PMU user.
1489*d83cc019SAndroid Build Coastguard Worker 		 */
1490*d83cc019SAndroid Build Coastguard Worker 		gem_quiescent_gpu(gem_fd);
1491*d83cc019SAndroid Build Coastguard Worker 		sleep(2);
1492*d83cc019SAndroid Build Coastguard Worker 
1493*d83cc019SAndroid Build Coastguard Worker 		/* Apply interrupt-heavy load on the engine. */
1494*d83cc019SAndroid Build Coastguard Worker 		igt_fork_helper(&engine_load) {
1495*d83cc019SAndroid Build Coastguard Worker 			for (;;)
1496*d83cc019SAndroid Build Coastguard Worker 				gem_execbuf(gem_fd, &eb);
1497*d83cc019SAndroid Build Coastguard Worker 		}
1498*d83cc019SAndroid Build Coastguard Worker 
1499*d83cc019SAndroid Build Coastguard Worker 		/* Wait a bit to allow engine load to start. */
1500*d83cc019SAndroid Build Coastguard Worker 		usleep(500e3);
1501*d83cc019SAndroid Build Coastguard Worker 
1502*d83cc019SAndroid Build Coastguard Worker 		/* Enable the PMU. */
1503*d83cc019SAndroid Build Coastguard Worker 		fd = open_pmu(config);
1504*d83cc019SAndroid Build Coastguard Worker 
1505*d83cc019SAndroid Build Coastguard Worker 		/* Stop load and close the PMU. */
1506*d83cc019SAndroid Build Coastguard Worker 		igt_stop_helper(&engine_load);
1507*d83cc019SAndroid Build Coastguard Worker 		close(fd);
1508*d83cc019SAndroid Build Coastguard Worker 	}
1509*d83cc019SAndroid Build Coastguard Worker 
1510*d83cc019SAndroid Build Coastguard Worker 	/* Cleanup. */
1511*d83cc019SAndroid Build Coastguard Worker 	gem_close(gem_fd, obj.handle);
1512*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(gem_fd);
1513*d83cc019SAndroid Build Coastguard Worker }
1514*d83cc019SAndroid Build Coastguard Worker 
1515*d83cc019SAndroid Build Coastguard Worker #define __assert_within(x, ref, tol_up, tol_down) \
1516*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f((double)(x) <= ((double)(ref) + (tol_up)) && \
1517*d83cc019SAndroid Build Coastguard Worker 		     (double)(x) >= ((double)(ref) - (tol_down)), \
1518*d83cc019SAndroid Build Coastguard Worker 		     "%f not within +%f/-%f of %f! ('%s' vs '%s')\n", \
1519*d83cc019SAndroid Build Coastguard Worker 		     (double)(x), (double)(tol_up), (double)(tol_down), \
1520*d83cc019SAndroid Build Coastguard Worker 		     (double)(ref), #x, #ref)
1521*d83cc019SAndroid Build Coastguard Worker 
1522*d83cc019SAndroid Build Coastguard Worker #define assert_within(x, ref, tolerance) \
1523*d83cc019SAndroid Build Coastguard Worker 	__assert_within(x, ref, tolerance, tolerance)
1524*d83cc019SAndroid Build Coastguard Worker 
1525*d83cc019SAndroid Build Coastguard Worker static void
accuracy(int gem_fd,const struct intel_execution_engine2 * e,unsigned long target_busy_pct,unsigned long target_iters)1526*d83cc019SAndroid Build Coastguard Worker accuracy(int gem_fd, const struct intel_execution_engine2 *e,
1527*d83cc019SAndroid Build Coastguard Worker 	 unsigned long target_busy_pct,
1528*d83cc019SAndroid Build Coastguard Worker 	 unsigned long target_iters)
1529*d83cc019SAndroid Build Coastguard Worker {
1530*d83cc019SAndroid Build Coastguard Worker 	const unsigned long min_test_us = 1e6;
1531*d83cc019SAndroid Build Coastguard Worker 	unsigned long pwm_calibration_us;
1532*d83cc019SAndroid Build Coastguard Worker 	unsigned long test_us;
1533*d83cc019SAndroid Build Coastguard Worker 	unsigned long cycle_us, busy_us, idle_us;
1534*d83cc019SAndroid Build Coastguard Worker 	double busy_r, expected;
1535*d83cc019SAndroid Build Coastguard Worker 	uint64_t val[2];
1536*d83cc019SAndroid Build Coastguard Worker 	uint64_t ts[2];
1537*d83cc019SAndroid Build Coastguard Worker 	int link[2];
1538*d83cc019SAndroid Build Coastguard Worker 	int fd;
1539*d83cc019SAndroid Build Coastguard Worker 
1540*d83cc019SAndroid Build Coastguard Worker 	/* Sampling platforms cannot reach the high accuracy criteria. */
1541*d83cc019SAndroid Build Coastguard Worker 	igt_require(gem_has_execlists(gem_fd));
1542*d83cc019SAndroid Build Coastguard Worker 
1543*d83cc019SAndroid Build Coastguard Worker 	/* Aim for approximately 100 iterations for calibration */
1544*d83cc019SAndroid Build Coastguard Worker 	cycle_us = min_test_us / target_iters;
1545*d83cc019SAndroid Build Coastguard Worker 	busy_us = cycle_us * target_busy_pct / 100;
1546*d83cc019SAndroid Build Coastguard Worker 	idle_us = cycle_us - busy_us;
1547*d83cc019SAndroid Build Coastguard Worker 
1548*d83cc019SAndroid Build Coastguard Worker 	while (idle_us < 2500 || busy_us < 2500) {
1549*d83cc019SAndroid Build Coastguard Worker 		busy_us *= 2;
1550*d83cc019SAndroid Build Coastguard Worker 		idle_us *= 2;
1551*d83cc019SAndroid Build Coastguard Worker 	}
1552*d83cc019SAndroid Build Coastguard Worker 	cycle_us = busy_us + idle_us;
1553*d83cc019SAndroid Build Coastguard Worker 	pwm_calibration_us = target_iters * cycle_us / 2;
1554*d83cc019SAndroid Build Coastguard Worker 	test_us = target_iters * cycle_us;
1555*d83cc019SAndroid Build Coastguard Worker 
1556*d83cc019SAndroid Build Coastguard Worker 	igt_info("calibration=%lums, test=%lums, cycle=%lums; ratio=%.2f%% (%luus/%luus)\n",
1557*d83cc019SAndroid Build Coastguard Worker 		 pwm_calibration_us / 1000, test_us / 1000, cycle_us / 1000,
1558*d83cc019SAndroid Build Coastguard Worker 		 (double)busy_us / cycle_us * 100.0,
1559*d83cc019SAndroid Build Coastguard Worker 		 busy_us, idle_us);
1560*d83cc019SAndroid Build Coastguard Worker 
1561*d83cc019SAndroid Build Coastguard Worker 	assert_within_epsilon((double)busy_us / cycle_us,
1562*d83cc019SAndroid Build Coastguard Worker 			      (double)target_busy_pct / 100.0,
1563*d83cc019SAndroid Build Coastguard Worker 			      tolerance);
1564*d83cc019SAndroid Build Coastguard Worker 
1565*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pipe(link) == 0);
1566*d83cc019SAndroid Build Coastguard Worker 
1567*d83cc019SAndroid Build Coastguard Worker 	/* Emit PWM pattern on the engine from a child. */
1568*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1569*d83cc019SAndroid Build Coastguard Worker 		const unsigned long timeout[] = {
1570*d83cc019SAndroid Build Coastguard Worker 			pwm_calibration_us * 1000, test_us * 1000
1571*d83cc019SAndroid Build Coastguard Worker 		};
1572*d83cc019SAndroid Build Coastguard Worker 		uint64_t total_busy_ns = 0, total_ns = 0;
1573*d83cc019SAndroid Build Coastguard Worker 		igt_spin_t *spin;
1574*d83cc019SAndroid Build Coastguard Worker 
1575*d83cc019SAndroid Build Coastguard Worker 		/* Allocate our spin batch and idle it. */
1576*d83cc019SAndroid Build Coastguard Worker 		spin = igt_spin_new(gem_fd, .engine = e->flags);
1577*d83cc019SAndroid Build Coastguard Worker 		igt_spin_end(spin);
1578*d83cc019SAndroid Build Coastguard Worker 		gem_sync(gem_fd, spin->handle);
1579*d83cc019SAndroid Build Coastguard Worker 
1580*d83cc019SAndroid Build Coastguard Worker 		/* 1st pass is calibration, second pass is the test. */
1581*d83cc019SAndroid Build Coastguard Worker 		for (int pass = 0; pass < ARRAY_SIZE(timeout); pass++) {
1582*d83cc019SAndroid Build Coastguard Worker 			unsigned int target_idle_us = idle_us;
1583*d83cc019SAndroid Build Coastguard Worker 			struct timespec start = { };
1584*d83cc019SAndroid Build Coastguard Worker 			uint64_t busy_ns = 0;
1585*d83cc019SAndroid Build Coastguard Worker 			unsigned long pass_ns = 0;
1586*d83cc019SAndroid Build Coastguard Worker 			double avg = 0.0, var = 0.0;
1587*d83cc019SAndroid Build Coastguard Worker 			unsigned int n = 0;
1588*d83cc019SAndroid Build Coastguard Worker 
1589*d83cc019SAndroid Build Coastguard Worker 			igt_nsec_elapsed(&start);
1590*d83cc019SAndroid Build Coastguard Worker 
1591*d83cc019SAndroid Build Coastguard Worker 			do {
1592*d83cc019SAndroid Build Coastguard Worker 				unsigned long loop_ns, loop_busy;
1593*d83cc019SAndroid Build Coastguard Worker 				struct timespec _ts = { };
1594*d83cc019SAndroid Build Coastguard Worker 				double err, tmp;
1595*d83cc019SAndroid Build Coastguard Worker 				uint64_t now;
1596*d83cc019SAndroid Build Coastguard Worker 
1597*d83cc019SAndroid Build Coastguard Worker 				/* PWM idle sleep. */
1598*d83cc019SAndroid Build Coastguard Worker 				_ts.tv_nsec = target_idle_us * 1000;
1599*d83cc019SAndroid Build Coastguard Worker 				nanosleep(&_ts, NULL);
1600*d83cc019SAndroid Build Coastguard Worker 
1601*d83cc019SAndroid Build Coastguard Worker 				/* Restart the spinbatch. */
1602*d83cc019SAndroid Build Coastguard Worker 				igt_spin_reset(spin);
1603*d83cc019SAndroid Build Coastguard Worker 				__submit_spin(gem_fd, spin, e, 0);
1604*d83cc019SAndroid Build Coastguard Worker 
1605*d83cc019SAndroid Build Coastguard Worker 				/* PWM busy sleep. */
1606*d83cc019SAndroid Build Coastguard Worker 				loop_busy = igt_nsec_elapsed(&start);
1607*d83cc019SAndroid Build Coastguard Worker 				_ts.tv_nsec = busy_us * 1000;
1608*d83cc019SAndroid Build Coastguard Worker 				nanosleep(&_ts, NULL);
1609*d83cc019SAndroid Build Coastguard Worker 				igt_spin_end(spin);
1610*d83cc019SAndroid Build Coastguard Worker 
1611*d83cc019SAndroid Build Coastguard Worker 				/* Time accounting. */
1612*d83cc019SAndroid Build Coastguard Worker 				now = igt_nsec_elapsed(&start);
1613*d83cc019SAndroid Build Coastguard Worker 				loop_busy = now - loop_busy;
1614*d83cc019SAndroid Build Coastguard Worker 				loop_ns = now - pass_ns;
1615*d83cc019SAndroid Build Coastguard Worker 				pass_ns = now;
1616*d83cc019SAndroid Build Coastguard Worker 
1617*d83cc019SAndroid Build Coastguard Worker 				busy_ns += loop_busy;
1618*d83cc019SAndroid Build Coastguard Worker 				total_busy_ns += loop_busy;
1619*d83cc019SAndroid Build Coastguard Worker 				total_ns += loop_ns;
1620*d83cc019SAndroid Build Coastguard Worker 
1621*d83cc019SAndroid Build Coastguard Worker 				/* Re-calibrate. */
1622*d83cc019SAndroid Build Coastguard Worker 				err = (double)total_busy_ns / total_ns -
1623*d83cc019SAndroid Build Coastguard Worker 				      (double)target_busy_pct / 100.0;
1624*d83cc019SAndroid Build Coastguard Worker 				target_idle_us = (double)target_idle_us *
1625*d83cc019SAndroid Build Coastguard Worker 						 (1.0 + err);
1626*d83cc019SAndroid Build Coastguard Worker 
1627*d83cc019SAndroid Build Coastguard Worker 				/* Running average and variance for debug. */
1628*d83cc019SAndroid Build Coastguard Worker 				err = 100.0 * total_busy_ns / total_ns;
1629*d83cc019SAndroid Build Coastguard Worker 				tmp = avg;
1630*d83cc019SAndroid Build Coastguard Worker 				avg += (err - avg) / ++n;
1631*d83cc019SAndroid Build Coastguard Worker 				var += (err - avg) * (err - tmp);
1632*d83cc019SAndroid Build Coastguard Worker 			} while (pass_ns < timeout[pass]);
1633*d83cc019SAndroid Build Coastguard Worker 
1634*d83cc019SAndroid Build Coastguard Worker 			pass_ns = igt_nsec_elapsed(&start);
1635*d83cc019SAndroid Build Coastguard Worker 			expected = (double)busy_ns / pass_ns;
1636*d83cc019SAndroid Build Coastguard Worker 
1637*d83cc019SAndroid Build Coastguard Worker 			igt_info("%u: %d cycles, busy %"PRIu64"us, idle %"PRIu64"us -> %.2f%% (target: %lu%%; average=%.2f±%.3f%%)\n",
1638*d83cc019SAndroid Build Coastguard Worker 				 pass, n,
1639*d83cc019SAndroid Build Coastguard Worker 				 busy_ns / 1000, (pass_ns - busy_ns) / 1000,
1640*d83cc019SAndroid Build Coastguard Worker 				 100 * expected, target_busy_pct,
1641*d83cc019SAndroid Build Coastguard Worker 				 avg, sqrt(var / n));
1642*d83cc019SAndroid Build Coastguard Worker 
1643*d83cc019SAndroid Build Coastguard Worker 			write(link[1], &expected, sizeof(expected));
1644*d83cc019SAndroid Build Coastguard Worker 		}
1645*d83cc019SAndroid Build Coastguard Worker 
1646*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(gem_fd, spin);
1647*d83cc019SAndroid Build Coastguard Worker 	}
1648*d83cc019SAndroid Build Coastguard Worker 
1649*d83cc019SAndroid Build Coastguard Worker 	fd = open_pmu(I915_PMU_ENGINE_BUSY(e->class, e->instance));
1650*d83cc019SAndroid Build Coastguard Worker 
1651*d83cc019SAndroid Build Coastguard Worker 	/* Let the child run. */
1652*d83cc019SAndroid Build Coastguard Worker 	read(link[0], &expected, sizeof(expected));
1653*d83cc019SAndroid Build Coastguard Worker 	assert_within(100.0 * expected, target_busy_pct, 5);
1654*d83cc019SAndroid Build Coastguard Worker 
1655*d83cc019SAndroid Build Coastguard Worker 	/* Collect engine busyness for an interesting part of child runtime. */
1656*d83cc019SAndroid Build Coastguard Worker 	val[0] = __pmu_read_single(fd, &ts[0]);
1657*d83cc019SAndroid Build Coastguard Worker 	read(link[0], &expected, sizeof(expected));
1658*d83cc019SAndroid Build Coastguard Worker 	val[1] = __pmu_read_single(fd, &ts[1]);
1659*d83cc019SAndroid Build Coastguard Worker 	close(fd);
1660*d83cc019SAndroid Build Coastguard Worker 
1661*d83cc019SAndroid Build Coastguard Worker 	close(link[1]);
1662*d83cc019SAndroid Build Coastguard Worker 	close(link[0]);
1663*d83cc019SAndroid Build Coastguard Worker 
1664*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1665*d83cc019SAndroid Build Coastguard Worker 
1666*d83cc019SAndroid Build Coastguard Worker 	busy_r = (double)(val[1] - val[0]) / (ts[1] - ts[0]);
1667*d83cc019SAndroid Build Coastguard Worker 
1668*d83cc019SAndroid Build Coastguard Worker 	igt_info("error=%.2f%% (%.2f%% vs %.2f%%)\n",
1669*d83cc019SAndroid Build Coastguard Worker 		 (busy_r - expected) * 100, 100 * busy_r, 100 * expected);
1670*d83cc019SAndroid Build Coastguard Worker 
1671*d83cc019SAndroid Build Coastguard Worker 	assert_within(100.0 * busy_r, 100.0 * expected, 2);
1672*d83cc019SAndroid Build Coastguard Worker }
1673*d83cc019SAndroid Build Coastguard Worker 
1674*d83cc019SAndroid Build Coastguard Worker igt_main
1675*d83cc019SAndroid Build Coastguard Worker {
1676*d83cc019SAndroid Build Coastguard Worker 	const unsigned int num_other_metrics =
1677*d83cc019SAndroid Build Coastguard Worker 				I915_PMU_LAST - __I915_PMU_OTHER(0) + 1;
1678*d83cc019SAndroid Build Coastguard Worker 	unsigned int num_engines = 0;
1679*d83cc019SAndroid Build Coastguard Worker 	int fd = -1;
1680*d83cc019SAndroid Build Coastguard Worker 	struct intel_execution_engine2 *e;
1681*d83cc019SAndroid Build Coastguard Worker 	unsigned int i;
1682*d83cc019SAndroid Build Coastguard Worker 
1683*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
1684*d83cc019SAndroid Build Coastguard Worker 		fd = drm_open_driver_master(DRIVER_INTEL);
1685*d83cc019SAndroid Build Coastguard Worker 
1686*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(fd);
1687*d83cc019SAndroid Build Coastguard Worker 		igt_require(i915_type_id() > 0);
1688*d83cc019SAndroid Build Coastguard Worker 
1689*d83cc019SAndroid Build Coastguard Worker 		__for_each_physical_engine(fd, e)
1690*d83cc019SAndroid Build Coastguard Worker 			num_engines++;
1691*d83cc019SAndroid Build Coastguard Worker 	}
1692*d83cc019SAndroid Build Coastguard Worker 
1693*d83cc019SAndroid Build Coastguard Worker 	/**
1694*d83cc019SAndroid Build Coastguard Worker 	 * Test invalid access via perf API is rejected.
1695*d83cc019SAndroid Build Coastguard Worker 	 */
1696*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-init")
1697*d83cc019SAndroid Build Coastguard Worker 		invalid_init();
1698*d83cc019SAndroid Build Coastguard Worker 
__for_each_physical_engine(fd,e)1699*d83cc019SAndroid Build Coastguard Worker 	__for_each_physical_engine(fd, e) {
1700*d83cc019SAndroid Build Coastguard Worker 		const unsigned int pct[] = { 2, 50, 98 };
1701*d83cc019SAndroid Build Coastguard Worker 
1702*d83cc019SAndroid Build Coastguard Worker 		/**
1703*d83cc019SAndroid Build Coastguard Worker 		 * Test that a single engine metric can be initialized or it
1704*d83cc019SAndroid Build Coastguard Worker 		 * is correctly rejected.
1705*d83cc019SAndroid Build Coastguard Worker 		 */
1706*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("init-busy-%s", e->name)
1707*d83cc019SAndroid Build Coastguard Worker 			init(fd, e, I915_SAMPLE_BUSY);
1708*d83cc019SAndroid Build Coastguard Worker 
1709*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("init-wait-%s", e->name)
1710*d83cc019SAndroid Build Coastguard Worker 			init(fd, e, I915_SAMPLE_WAIT);
1711*d83cc019SAndroid Build Coastguard Worker 
1712*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("init-sema-%s", e->name)
1713*d83cc019SAndroid Build Coastguard Worker 			init(fd, e, I915_SAMPLE_SEMA);
1714*d83cc019SAndroid Build Coastguard Worker 
1715*d83cc019SAndroid Build Coastguard Worker 		/**
1716*d83cc019SAndroid Build Coastguard Worker 		 * Test that engines show no load when idle.
1717*d83cc019SAndroid Build Coastguard Worker 		 */
1718*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("idle-%s", e->name)
1719*d83cc019SAndroid Build Coastguard Worker 			single(fd, e, 0);
1720*d83cc019SAndroid Build Coastguard Worker 
1721*d83cc019SAndroid Build Coastguard Worker 		/**
1722*d83cc019SAndroid Build Coastguard Worker 		 * Test that a single engine reports load correctly.
1723*d83cc019SAndroid Build Coastguard Worker 		 */
1724*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-%s", e->name)
1725*d83cc019SAndroid Build Coastguard Worker 			single(fd, e, TEST_BUSY);
1726*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-idle-%s", e->name)
1727*d83cc019SAndroid Build Coastguard Worker 			single(fd, e, TEST_BUSY | TEST_TRAILING_IDLE);
1728*d83cc019SAndroid Build Coastguard Worker 
1729*d83cc019SAndroid Build Coastguard Worker 		/**
1730*d83cc019SAndroid Build Coastguard Worker 		 * Test that when one engine is loaded other report no
1731*d83cc019SAndroid Build Coastguard Worker 		 * load.
1732*d83cc019SAndroid Build Coastguard Worker 		 */
1733*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-check-all-%s", e->name)
1734*d83cc019SAndroid Build Coastguard Worker 			busy_check_all(fd, e, num_engines, TEST_BUSY);
1735*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-idle-check-all-%s", e->name)
1736*d83cc019SAndroid Build Coastguard Worker 			busy_check_all(fd, e, num_engines,
1737*d83cc019SAndroid Build Coastguard Worker 				       TEST_BUSY | TEST_TRAILING_IDLE);
1738*d83cc019SAndroid Build Coastguard Worker 
1739*d83cc019SAndroid Build Coastguard Worker 		/**
1740*d83cc019SAndroid Build Coastguard Worker 		 * Test that when all except one engine are loaded all
1741*d83cc019SAndroid Build Coastguard Worker 		 * loads are correctly reported.
1742*d83cc019SAndroid Build Coastguard Worker 		 */
1743*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("most-busy-check-all-%s", e->name)
1744*d83cc019SAndroid Build Coastguard Worker 			most_busy_check_all(fd, e, num_engines,
1745*d83cc019SAndroid Build Coastguard Worker 					    TEST_BUSY);
1746*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("most-busy-idle-check-all-%s", e->name)
1747*d83cc019SAndroid Build Coastguard Worker 			most_busy_check_all(fd, e, num_engines,
1748*d83cc019SAndroid Build Coastguard Worker 					    TEST_BUSY |
1749*d83cc019SAndroid Build Coastguard Worker 					    TEST_TRAILING_IDLE);
1750*d83cc019SAndroid Build Coastguard Worker 
1751*d83cc019SAndroid Build Coastguard Worker 		/**
1752*d83cc019SAndroid Build Coastguard Worker 		 * Test that semphore counters report no activity on
1753*d83cc019SAndroid Build Coastguard Worker 		 * idle or busy engines.
1754*d83cc019SAndroid Build Coastguard Worker 		 */
1755*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("idle-no-semaphores-%s", e->name)
1756*d83cc019SAndroid Build Coastguard Worker 			no_sema(fd, e, 0);
1757*d83cc019SAndroid Build Coastguard Worker 
1758*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-no-semaphores-%s", e->name)
1759*d83cc019SAndroid Build Coastguard Worker 			no_sema(fd, e, TEST_BUSY);
1760*d83cc019SAndroid Build Coastguard Worker 
1761*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-idle-no-semaphores-%s", e->name)
1762*d83cc019SAndroid Build Coastguard Worker 			no_sema(fd, e, TEST_BUSY | TEST_TRAILING_IDLE);
1763*d83cc019SAndroid Build Coastguard Worker 
1764*d83cc019SAndroid Build Coastguard Worker 		/**
1765*d83cc019SAndroid Build Coastguard Worker 		 * Test that semaphore waits are correctly reported.
1766*d83cc019SAndroid Build Coastguard Worker 		 */
1767*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("semaphore-wait-%s", e->name)
1768*d83cc019SAndroid Build Coastguard Worker 			sema_wait(fd, e, TEST_BUSY);
1769*d83cc019SAndroid Build Coastguard Worker 
1770*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("semaphore-wait-idle-%s", e->name)
1771*d83cc019SAndroid Build Coastguard Worker 			sema_wait(fd, e,
1772*d83cc019SAndroid Build Coastguard Worker 				  TEST_BUSY | TEST_TRAILING_IDLE);
1773*d83cc019SAndroid Build Coastguard Worker 
1774*d83cc019SAndroid Build Coastguard Worker 		/**
1775*d83cc019SAndroid Build Coastguard Worker 		 * Check that two perf clients do not influence each
1776*d83cc019SAndroid Build Coastguard Worker 		 * others observations.
1777*d83cc019SAndroid Build Coastguard Worker 		 */
1778*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("multi-client-%s", e->name)
1779*d83cc019SAndroid Build Coastguard Worker 			multi_client(fd, e);
1780*d83cc019SAndroid Build Coastguard Worker 
1781*d83cc019SAndroid Build Coastguard Worker 		/**
1782*d83cc019SAndroid Build Coastguard Worker 		 * Check that reported usage is correct when PMU is
1783*d83cc019SAndroid Build Coastguard Worker 		 * enabled after the batch is running.
1784*d83cc019SAndroid Build Coastguard Worker 		 */
1785*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-start-%s", e->name)
1786*d83cc019SAndroid Build Coastguard Worker 			busy_start(fd, e);
1787*d83cc019SAndroid Build Coastguard Worker 
1788*d83cc019SAndroid Build Coastguard Worker 		/**
1789*d83cc019SAndroid Build Coastguard Worker 		 * Check that reported usage is correct when PMU is
1790*d83cc019SAndroid Build Coastguard Worker 		 * enabled after two batches are running.
1791*d83cc019SAndroid Build Coastguard Worker 		 */
1792*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-double-start-%s", e->name) {
1793*d83cc019SAndroid Build Coastguard Worker 			gem_require_contexts(fd);
1794*d83cc019SAndroid Build Coastguard Worker 			busy_double_start(fd, e);
1795*d83cc019SAndroid Build Coastguard Worker 		}
1796*d83cc019SAndroid Build Coastguard Worker 
1797*d83cc019SAndroid Build Coastguard Worker 		/**
1798*d83cc019SAndroid Build Coastguard Worker 		 * Check that the PMU can be safely enabled in face of
1799*d83cc019SAndroid Build Coastguard Worker 		 * interrupt-heavy engine load.
1800*d83cc019SAndroid Build Coastguard Worker 		 */
1801*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("enable-race-%s", e->name)
1802*d83cc019SAndroid Build Coastguard Worker 			test_enable_race(fd, e);
1803*d83cc019SAndroid Build Coastguard Worker 
1804*d83cc019SAndroid Build Coastguard Worker 		/**
1805*d83cc019SAndroid Build Coastguard Worker 		 * Check engine busyness accuracy is as expected.
1806*d83cc019SAndroid Build Coastguard Worker 		 */
1807*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < ARRAY_SIZE(pct); i++) {
1808*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("busy-accuracy-%u-%s",
1809*d83cc019SAndroid Build Coastguard Worker 				      pct[i], e->name)
1810*d83cc019SAndroid Build Coastguard Worker 				accuracy(fd, e, pct[i], 10);
1811*d83cc019SAndroid Build Coastguard Worker 		}
1812*d83cc019SAndroid Build Coastguard Worker 
1813*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("busy-hang-%s", e->name) {
1814*d83cc019SAndroid Build Coastguard Worker 			igt_hang_t hang = igt_allow_hang(fd, 0, 0);
1815*d83cc019SAndroid Build Coastguard Worker 
1816*d83cc019SAndroid Build Coastguard Worker 			single(fd, e, TEST_BUSY | FLAG_HANG);
1817*d83cc019SAndroid Build Coastguard Worker 
1818*d83cc019SAndroid Build Coastguard Worker 			igt_disallow_hang(fd, hang);
1819*d83cc019SAndroid Build Coastguard Worker 		}
1820*d83cc019SAndroid Build Coastguard Worker 
1821*d83cc019SAndroid Build Coastguard Worker 		/**
1822*d83cc019SAndroid Build Coastguard Worker 		 * Test that event waits are correctly reported.
1823*d83cc019SAndroid Build Coastguard Worker 		 */
1824*d83cc019SAndroid Build Coastguard Worker 		if (e->class == I915_ENGINE_CLASS_RENDER)
1825*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("event-wait-%s", e->name)
1826*d83cc019SAndroid Build Coastguard Worker 				event_wait(fd, e);
1827*d83cc019SAndroid Build Coastguard Worker 	}
1828*d83cc019SAndroid Build Coastguard Worker 
1829*d83cc019SAndroid Build Coastguard Worker 	/**
1830*d83cc019SAndroid Build Coastguard Worker 	 * Test that when all engines are loaded all loads are
1831*d83cc019SAndroid Build Coastguard Worker 	 * correctly reported.
1832*d83cc019SAndroid Build Coastguard Worker 	 */
1833*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("all-busy-check-all")
1834*d83cc019SAndroid Build Coastguard Worker 		all_busy_check_all(fd, num_engines, TEST_BUSY);
1835*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("all-busy-idle-check-all")
1836*d83cc019SAndroid Build Coastguard Worker 		all_busy_check_all(fd, num_engines,
1837*d83cc019SAndroid Build Coastguard Worker 				   TEST_BUSY | TEST_TRAILING_IDLE);
1838*d83cc019SAndroid Build Coastguard Worker 
1839*d83cc019SAndroid Build Coastguard Worker 	/**
1840*d83cc019SAndroid Build Coastguard Worker 	 * Test that non-engine counters can be initialized and read. Apart
1841*d83cc019SAndroid Build Coastguard Worker 	 * from the invalid metric which should fail.
1842*d83cc019SAndroid Build Coastguard Worker 	 */
1843*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < num_other_metrics + 1; i++) {
1844*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("other-init-%u", i)
1845*d83cc019SAndroid Build Coastguard Worker 			init_other(i, i < num_other_metrics);
1846*d83cc019SAndroid Build Coastguard Worker 
1847*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("other-read-%u", i)
1848*d83cc019SAndroid Build Coastguard Worker 			read_other(i, i < num_other_metrics);
1849*d83cc019SAndroid Build Coastguard Worker 	}
1850*d83cc019SAndroid Build Coastguard Worker 
1851*d83cc019SAndroid Build Coastguard Worker 	/**
1852*d83cc019SAndroid Build Coastguard Worker 	 * Test counters are not affected by CPU offline/online events.
1853*d83cc019SAndroid Build Coastguard Worker 	 */
1854*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("cpu-hotplug")
1855*d83cc019SAndroid Build Coastguard Worker 		cpu_hotplug(fd);
1856*d83cc019SAndroid Build Coastguard Worker 
1857*d83cc019SAndroid Build Coastguard Worker 	/**
1858*d83cc019SAndroid Build Coastguard Worker 	 * Test GPU frequency.
1859*d83cc019SAndroid Build Coastguard Worker 	 */
1860*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("frequency")
1861*d83cc019SAndroid Build Coastguard Worker 		test_frequency(fd);
1862*d83cc019SAndroid Build Coastguard Worker 
1863*d83cc019SAndroid Build Coastguard Worker 	/**
1864*d83cc019SAndroid Build Coastguard Worker 	 * Test interrupt count reporting.
1865*d83cc019SAndroid Build Coastguard Worker 	 */
1866*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("interrupts")
1867*d83cc019SAndroid Build Coastguard Worker 		test_interrupts(fd);
1868*d83cc019SAndroid Build Coastguard Worker 
1869*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("interrupts-sync")
1870*d83cc019SAndroid Build Coastguard Worker 		test_interrupts_sync(fd);
1871*d83cc019SAndroid Build Coastguard Worker 
1872*d83cc019SAndroid Build Coastguard Worker 	/**
1873*d83cc019SAndroid Build Coastguard Worker 	 * Test RC6 residency reporting.
1874*d83cc019SAndroid Build Coastguard Worker 	 */
1875*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("rc6")
1876*d83cc019SAndroid Build Coastguard Worker 		test_rc6(fd, 0);
1877*d83cc019SAndroid Build Coastguard Worker 
1878*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("rc6-runtime-pm")
1879*d83cc019SAndroid Build Coastguard Worker 		test_rc6(fd, TEST_RUNTIME_PM);
1880*d83cc019SAndroid Build Coastguard Worker 
1881*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("rc6-runtime-pm-long")
1882*d83cc019SAndroid Build Coastguard Worker 		test_rc6(fd, TEST_RUNTIME_PM | FLAG_LONG);
1883*d83cc019SAndroid Build Coastguard Worker 
1884*d83cc019SAndroid Build Coastguard Worker 	/**
1885*d83cc019SAndroid Build Coastguard Worker 	 * Check render nodes are counted.
1886*d83cc019SAndroid Build Coastguard Worker 	 */
1887*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group {
1888*d83cc019SAndroid Build Coastguard Worker 		int render_fd = -1;
1889*d83cc019SAndroid Build Coastguard Worker 
1890*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
1891*d83cc019SAndroid Build Coastguard Worker 			render_fd = drm_open_driver_render(DRIVER_INTEL);
1892*d83cc019SAndroid Build Coastguard Worker 			igt_require_gem(render_fd);
1893*d83cc019SAndroid Build Coastguard Worker 
1894*d83cc019SAndroid Build Coastguard Worker 			gem_quiescent_gpu(fd);
1895*d83cc019SAndroid Build Coastguard Worker 		}
1896*d83cc019SAndroid Build Coastguard Worker 
__for_each_physical_engine(render_fd,e)1897*d83cc019SAndroid Build Coastguard Worker 		__for_each_physical_engine(render_fd, e) {
1898*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("render-node-busy-%s", e->name)
1899*d83cc019SAndroid Build Coastguard Worker 				single(render_fd, e, TEST_BUSY);
1900*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("render-node-busy-idle-%s",
1901*d83cc019SAndroid Build Coastguard Worker 				      e->name)
1902*d83cc019SAndroid Build Coastguard Worker 				single(render_fd, e,
1903*d83cc019SAndroid Build Coastguard Worker 				       TEST_BUSY | TEST_TRAILING_IDLE);
1904*d83cc019SAndroid Build Coastguard Worker 		}
1905*d83cc019SAndroid Build Coastguard Worker 
1906*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
1907*d83cc019SAndroid Build Coastguard Worker 			close(render_fd);
1908*d83cc019SAndroid Build Coastguard Worker 		}
1909*d83cc019SAndroid Build Coastguard Worker 	}
1910*d83cc019SAndroid Build Coastguard Worker }
1911