1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2016 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker *
4*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker *
11*d83cc019SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker * Software.
14*d83cc019SAndroid Build Coastguard Worker *
15*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker */
23*d83cc019SAndroid Build Coastguard Worker
24*d83cc019SAndroid Build Coastguard Worker #include <time.h>
25*d83cc019SAndroid Build Coastguard Worker #include <pthread.h>
26*d83cc019SAndroid Build Coastguard Worker
27*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
28*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
29*d83cc019SAndroid Build Coastguard Worker
30*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_NO_RELOC (1<<11)
31*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
32*d83cc019SAndroid Build Coastguard Worker
33*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_SHIFT (13)
34*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
35*d83cc019SAndroid Build Coastguard Worker
36*d83cc019SAndroid Build Coastguard Worker #define MAX_PRIO LOCAL_I915_CONTEXT_MAX_USER_PRIORITY
37*d83cc019SAndroid Build Coastguard Worker #define MIN_PRIO LOCAL_I915_CONTEXT_MIN_USER_PRIORITY
38*d83cc019SAndroid Build Coastguard Worker
39*d83cc019SAndroid Build Coastguard Worker #define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
40*d83cc019SAndroid Build Coastguard Worker
41*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Basic check of ring<->ring write synchronisation.");
42*d83cc019SAndroid Build Coastguard Worker
43*d83cc019SAndroid Build Coastguard Worker /*
44*d83cc019SAndroid Build Coastguard Worker * Testcase: Basic check of sync
45*d83cc019SAndroid Build Coastguard Worker *
46*d83cc019SAndroid Build Coastguard Worker * Extremely efficient at catching missed irqs
47*d83cc019SAndroid Build Coastguard Worker */
48*d83cc019SAndroid Build Coastguard Worker
gettime(void)49*d83cc019SAndroid Build Coastguard Worker static double gettime(void)
50*d83cc019SAndroid Build Coastguard Worker {
51*d83cc019SAndroid Build Coastguard Worker static clockid_t clock = -1;
52*d83cc019SAndroid Build Coastguard Worker struct timespec ts;
53*d83cc019SAndroid Build Coastguard Worker
54*d83cc019SAndroid Build Coastguard Worker /* Stay on the same clock for consistency. */
55*d83cc019SAndroid Build Coastguard Worker if (clock != (clockid_t)-1) {
56*d83cc019SAndroid Build Coastguard Worker if (clock_gettime(clock, &ts))
57*d83cc019SAndroid Build Coastguard Worker goto error;
58*d83cc019SAndroid Build Coastguard Worker goto out;
59*d83cc019SAndroid Build Coastguard Worker }
60*d83cc019SAndroid Build Coastguard Worker
61*d83cc019SAndroid Build Coastguard Worker #ifdef CLOCK_MONOTONIC_RAW
62*d83cc019SAndroid Build Coastguard Worker if (!clock_gettime(clock = CLOCK_MONOTONIC_RAW, &ts))
63*d83cc019SAndroid Build Coastguard Worker goto out;
64*d83cc019SAndroid Build Coastguard Worker #endif
65*d83cc019SAndroid Build Coastguard Worker #ifdef CLOCK_MONOTONIC_COARSE
66*d83cc019SAndroid Build Coastguard Worker if (!clock_gettime(clock = CLOCK_MONOTONIC_COARSE, &ts))
67*d83cc019SAndroid Build Coastguard Worker goto out;
68*d83cc019SAndroid Build Coastguard Worker #endif
69*d83cc019SAndroid Build Coastguard Worker if (!clock_gettime(clock = CLOCK_MONOTONIC, &ts))
70*d83cc019SAndroid Build Coastguard Worker goto out;
71*d83cc019SAndroid Build Coastguard Worker error:
72*d83cc019SAndroid Build Coastguard Worker igt_warn("Could not read monotonic time: %s\n",
73*d83cc019SAndroid Build Coastguard Worker strerror(errno));
74*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
75*d83cc019SAndroid Build Coastguard Worker return 0;
76*d83cc019SAndroid Build Coastguard Worker
77*d83cc019SAndroid Build Coastguard Worker out:
78*d83cc019SAndroid Build Coastguard Worker return ts.tv_sec + 1e-9*ts.tv_nsec;
79*d83cc019SAndroid Build Coastguard Worker }
80*d83cc019SAndroid Build Coastguard Worker
81*d83cc019SAndroid Build Coastguard Worker static void
sync_ring(int fd,unsigned ring,int num_children,int timeout)82*d83cc019SAndroid Build Coastguard Worker sync_ring(int fd, unsigned ring, int num_children, int timeout)
83*d83cc019SAndroid Build Coastguard Worker {
84*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
85*d83cc019SAndroid Build Coastguard Worker const char *names[16];
86*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
87*d83cc019SAndroid Build Coastguard Worker
88*d83cc019SAndroid Build Coastguard Worker if (ring == ALL_ENGINES) {
89*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
90*d83cc019SAndroid Build Coastguard Worker names[num_engines] = e__->name;
91*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
92*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
93*d83cc019SAndroid Build Coastguard Worker break;
94*d83cc019SAndroid Build Coastguard Worker }
95*d83cc019SAndroid Build Coastguard Worker
96*d83cc019SAndroid Build Coastguard Worker num_children *= num_engines;
97*d83cc019SAndroid Build Coastguard Worker } else {
98*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
99*d83cc019SAndroid Build Coastguard Worker names[num_engines] = NULL;
100*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
101*d83cc019SAndroid Build Coastguard Worker }
102*d83cc019SAndroid Build Coastguard Worker
103*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
104*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_children) {
105*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
106*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object;
107*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
108*d83cc019SAndroid Build Coastguard Worker double start, elapsed;
109*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
110*d83cc019SAndroid Build Coastguard Worker
111*d83cc019SAndroid Build Coastguard Worker memset(&object, 0, sizeof(object));
112*d83cc019SAndroid Build Coastguard Worker object.handle = gem_create(fd, 4096);
113*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object.handle, 0, &bbe, sizeof(bbe));
114*d83cc019SAndroid Build Coastguard Worker
115*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
116*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&object);
117*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
118*d83cc019SAndroid Build Coastguard Worker execbuf.flags = engines[child % num_engines];
119*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
120*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
121*d83cc019SAndroid Build Coastguard Worker
122*d83cc019SAndroid Build Coastguard Worker start = gettime();
123*d83cc019SAndroid Build Coastguard Worker cycles = 0;
124*d83cc019SAndroid Build Coastguard Worker do {
125*d83cc019SAndroid Build Coastguard Worker do {
126*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
127*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
128*d83cc019SAndroid Build Coastguard Worker } while (++cycles & 1023);
129*d83cc019SAndroid Build Coastguard Worker } while ((elapsed = gettime() - start) < timeout);
130*d83cc019SAndroid Build Coastguard Worker igt_info("%s%sompleted %ld cycles: %.3f us\n",
131*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
132*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " c" : "C",
133*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6/cycles);
134*d83cc019SAndroid Build Coastguard Worker
135*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object.handle);
136*d83cc019SAndroid Build Coastguard Worker }
137*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(timeout+10, NULL);
138*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
139*d83cc019SAndroid Build Coastguard Worker }
140*d83cc019SAndroid Build Coastguard Worker
141*d83cc019SAndroid Build Coastguard Worker static void
idle_ring(int fd,unsigned ring,int timeout)142*d83cc019SAndroid Build Coastguard Worker idle_ring(int fd, unsigned ring, int timeout)
143*d83cc019SAndroid Build Coastguard Worker {
144*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
145*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object;
146*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
147*d83cc019SAndroid Build Coastguard Worker double start, elapsed;
148*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
149*d83cc019SAndroid Build Coastguard Worker
150*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
151*d83cc019SAndroid Build Coastguard Worker
152*d83cc019SAndroid Build Coastguard Worker memset(&object, 0, sizeof(object));
153*d83cc019SAndroid Build Coastguard Worker object.handle = gem_create(fd, 4096);
154*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object.handle, 0, &bbe, sizeof(bbe));
155*d83cc019SAndroid Build Coastguard Worker
156*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
157*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&object);
158*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
159*d83cc019SAndroid Build Coastguard Worker execbuf.flags = ring;
160*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
161*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
162*d83cc019SAndroid Build Coastguard Worker
163*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
164*d83cc019SAndroid Build Coastguard Worker start = gettime();
165*d83cc019SAndroid Build Coastguard Worker cycles = 0;
166*d83cc019SAndroid Build Coastguard Worker do {
167*d83cc019SAndroid Build Coastguard Worker do {
168*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
169*d83cc019SAndroid Build Coastguard Worker gem_quiescent_gpu(fd);
170*d83cc019SAndroid Build Coastguard Worker } while (++cycles & 1023);
171*d83cc019SAndroid Build Coastguard Worker } while ((elapsed = gettime() - start) < timeout);
172*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
173*d83cc019SAndroid Build Coastguard Worker
174*d83cc019SAndroid Build Coastguard Worker igt_info("Completed %ld cycles: %.3f us\n",
175*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6/cycles);
176*d83cc019SAndroid Build Coastguard Worker
177*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object.handle);
178*d83cc019SAndroid Build Coastguard Worker }
179*d83cc019SAndroid Build Coastguard Worker
180*d83cc019SAndroid Build Coastguard Worker static void
wakeup_ring(int fd,unsigned ring,int timeout,int wlen)181*d83cc019SAndroid Build Coastguard Worker wakeup_ring(int fd, unsigned ring, int timeout, int wlen)
182*d83cc019SAndroid Build Coastguard Worker {
183*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
184*d83cc019SAndroid Build Coastguard Worker const char *names[16];
185*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
186*d83cc019SAndroid Build Coastguard Worker
187*d83cc019SAndroid Build Coastguard Worker if (ring == ALL_ENGINES) {
188*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
189*d83cc019SAndroid Build Coastguard Worker if (!gem_can_store_dword(fd, ring))
190*d83cc019SAndroid Build Coastguard Worker continue;
191*d83cc019SAndroid Build Coastguard Worker
192*d83cc019SAndroid Build Coastguard Worker names[num_engines] = e__->name;
193*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
194*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
195*d83cc019SAndroid Build Coastguard Worker break;
196*d83cc019SAndroid Build Coastguard Worker }
197*d83cc019SAndroid Build Coastguard Worker igt_require(num_engines);
198*d83cc019SAndroid Build Coastguard Worker } else {
199*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
200*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, ring));
201*d83cc019SAndroid Build Coastguard Worker names[num_engines] = NULL;
202*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
203*d83cc019SAndroid Build Coastguard Worker }
204*d83cc019SAndroid Build Coastguard Worker
205*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
206*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_engines) {
207*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
208*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object;
209*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
210*d83cc019SAndroid Build Coastguard Worker double end, this, elapsed, now, baseline;
211*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
212*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin;
213*d83cc019SAndroid Build Coastguard Worker
214*d83cc019SAndroid Build Coastguard Worker memset(&object, 0, sizeof(object));
215*d83cc019SAndroid Build Coastguard Worker object.handle = gem_create(fd, 4096);
216*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object.handle, 0, &bbe, sizeof(bbe));
217*d83cc019SAndroid Build Coastguard Worker
218*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
219*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&object);
220*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
221*d83cc019SAndroid Build Coastguard Worker execbuf.flags = engines[child % num_engines];
222*d83cc019SAndroid Build Coastguard Worker
223*d83cc019SAndroid Build Coastguard Worker spin = __igt_spin_new(fd,
224*d83cc019SAndroid Build Coastguard Worker .engine = execbuf.flags,
225*d83cc019SAndroid Build Coastguard Worker .flags = (IGT_SPIN_POLL_RUN |
226*d83cc019SAndroid Build Coastguard Worker IGT_SPIN_FAST));
227*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_spin_has_poll(spin));
228*d83cc019SAndroid Build Coastguard Worker
229*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
230*d83cc019SAndroid Build Coastguard Worker
231*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin);
232*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
233*d83cc019SAndroid Build Coastguard Worker
234*d83cc019SAndroid Build Coastguard Worker for (int warmup = 0; warmup <= 1; warmup++) {
235*d83cc019SAndroid Build Coastguard Worker end = gettime() + timeout/10.;
236*d83cc019SAndroid Build Coastguard Worker elapsed = 0;
237*d83cc019SAndroid Build Coastguard Worker cycles = 0;
238*d83cc019SAndroid Build Coastguard Worker do {
239*d83cc019SAndroid Build Coastguard Worker igt_spin_reset(spin);
240*d83cc019SAndroid Build Coastguard Worker
241*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &spin->execbuf);
242*d83cc019SAndroid Build Coastguard Worker igt_spin_busywait_until_started(spin);
243*d83cc019SAndroid Build Coastguard Worker
244*d83cc019SAndroid Build Coastguard Worker this = gettime();
245*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin);
246*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, spin->handle);
247*d83cc019SAndroid Build Coastguard Worker now = gettime();
248*d83cc019SAndroid Build Coastguard Worker
249*d83cc019SAndroid Build Coastguard Worker elapsed += now - this;
250*d83cc019SAndroid Build Coastguard Worker cycles++;
251*d83cc019SAndroid Build Coastguard Worker } while (now < end);
252*d83cc019SAndroid Build Coastguard Worker baseline = elapsed / cycles;
253*d83cc019SAndroid Build Coastguard Worker }
254*d83cc019SAndroid Build Coastguard Worker igt_info("%s%saseline %ld cycles: %.3f us\n",
255*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
256*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " b" : "B",
257*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6/cycles);
258*d83cc019SAndroid Build Coastguard Worker
259*d83cc019SAndroid Build Coastguard Worker end = gettime() + timeout;
260*d83cc019SAndroid Build Coastguard Worker elapsed = 0;
261*d83cc019SAndroid Build Coastguard Worker cycles = 0;
262*d83cc019SAndroid Build Coastguard Worker do {
263*d83cc019SAndroid Build Coastguard Worker igt_spin_reset(spin);
264*d83cc019SAndroid Build Coastguard Worker
265*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &spin->execbuf);
266*d83cc019SAndroid Build Coastguard Worker igt_spin_busywait_until_started(spin);
267*d83cc019SAndroid Build Coastguard Worker
268*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < wlen; n++)
269*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
270*d83cc019SAndroid Build Coastguard Worker
271*d83cc019SAndroid Build Coastguard Worker this = gettime();
272*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin);
273*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
274*d83cc019SAndroid Build Coastguard Worker now = gettime();
275*d83cc019SAndroid Build Coastguard Worker
276*d83cc019SAndroid Build Coastguard Worker elapsed += now - this;
277*d83cc019SAndroid Build Coastguard Worker cycles++;
278*d83cc019SAndroid Build Coastguard Worker } while (now < end);
279*d83cc019SAndroid Build Coastguard Worker elapsed -= cycles * baseline;
280*d83cc019SAndroid Build Coastguard Worker
281*d83cc019SAndroid Build Coastguard Worker igt_info("%s%sompleted %ld cycles: %.3f + %.3f us\n",
282*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
283*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " c" : "C",
284*d83cc019SAndroid Build Coastguard Worker cycles, 1e6*baseline, elapsed*1e6/cycles);
285*d83cc019SAndroid Build Coastguard Worker
286*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin);
287*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object.handle);
288*d83cc019SAndroid Build Coastguard Worker }
289*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(2*timeout, NULL);
290*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
291*d83cc019SAndroid Build Coastguard Worker }
292*d83cc019SAndroid Build Coastguard Worker
active_ring(int fd,unsigned ring,int timeout)293*d83cc019SAndroid Build Coastguard Worker static void active_ring(int fd, unsigned ring, int timeout)
294*d83cc019SAndroid Build Coastguard Worker {
295*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
296*d83cc019SAndroid Build Coastguard Worker const char *names[16];
297*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
298*d83cc019SAndroid Build Coastguard Worker
299*d83cc019SAndroid Build Coastguard Worker if (ring == ALL_ENGINES) {
300*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
301*d83cc019SAndroid Build Coastguard Worker if (!gem_can_store_dword(fd, ring))
302*d83cc019SAndroid Build Coastguard Worker continue;
303*d83cc019SAndroid Build Coastguard Worker
304*d83cc019SAndroid Build Coastguard Worker names[num_engines] = e__->name;
305*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
306*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
307*d83cc019SAndroid Build Coastguard Worker break;
308*d83cc019SAndroid Build Coastguard Worker }
309*d83cc019SAndroid Build Coastguard Worker igt_require(num_engines);
310*d83cc019SAndroid Build Coastguard Worker } else {
311*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
312*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, ring));
313*d83cc019SAndroid Build Coastguard Worker names[num_engines] = NULL;
314*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
315*d83cc019SAndroid Build Coastguard Worker }
316*d83cc019SAndroid Build Coastguard Worker
317*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
318*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_engines) {
319*d83cc019SAndroid Build Coastguard Worker double start, end, elapsed;
320*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
321*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin[2];
322*d83cc019SAndroid Build Coastguard Worker
323*d83cc019SAndroid Build Coastguard Worker spin[0] = __igt_spin_new(fd,
324*d83cc019SAndroid Build Coastguard Worker .engine = ring,
325*d83cc019SAndroid Build Coastguard Worker .flags = IGT_SPIN_FAST);
326*d83cc019SAndroid Build Coastguard Worker
327*d83cc019SAndroid Build Coastguard Worker spin[1] = __igt_spin_new(fd,
328*d83cc019SAndroid Build Coastguard Worker .engine = ring,
329*d83cc019SAndroid Build Coastguard Worker .flags = IGT_SPIN_FAST);
330*d83cc019SAndroid Build Coastguard Worker
331*d83cc019SAndroid Build Coastguard Worker start = gettime();
332*d83cc019SAndroid Build Coastguard Worker end = start + timeout;
333*d83cc019SAndroid Build Coastguard Worker cycles = 0;
334*d83cc019SAndroid Build Coastguard Worker do {
335*d83cc019SAndroid Build Coastguard Worker for (int loop = 0; loop < 1024; loop++) {
336*d83cc019SAndroid Build Coastguard Worker igt_spin_t *s = spin[loop & 1];
337*d83cc019SAndroid Build Coastguard Worker
338*d83cc019SAndroid Build Coastguard Worker igt_spin_end(s);
339*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, s->handle);
340*d83cc019SAndroid Build Coastguard Worker
341*d83cc019SAndroid Build Coastguard Worker igt_spin_reset(s);
342*d83cc019SAndroid Build Coastguard Worker
343*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &s->execbuf);
344*d83cc019SAndroid Build Coastguard Worker }
345*d83cc019SAndroid Build Coastguard Worker cycles += 1024;
346*d83cc019SAndroid Build Coastguard Worker } while ((elapsed = gettime()) < end);
347*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin[1]);
348*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin[0]);
349*d83cc019SAndroid Build Coastguard Worker
350*d83cc019SAndroid Build Coastguard Worker igt_info("%s%sompleted %ld cycles: %.3f us\n",
351*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
352*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " c" : "C",
353*d83cc019SAndroid Build Coastguard Worker cycles, (elapsed - start)*1e6/cycles);
354*d83cc019SAndroid Build Coastguard Worker }
355*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(2*timeout, NULL);
356*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
357*d83cc019SAndroid Build Coastguard Worker }
358*d83cc019SAndroid Build Coastguard Worker
359*d83cc019SAndroid Build Coastguard Worker static void
active_wakeup_ring(int fd,unsigned ring,int timeout,int wlen)360*d83cc019SAndroid Build Coastguard Worker active_wakeup_ring(int fd, unsigned ring, int timeout, int wlen)
361*d83cc019SAndroid Build Coastguard Worker {
362*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
363*d83cc019SAndroid Build Coastguard Worker const char *names[16];
364*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
365*d83cc019SAndroid Build Coastguard Worker
366*d83cc019SAndroid Build Coastguard Worker if (ring == ALL_ENGINES) {
367*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
368*d83cc019SAndroid Build Coastguard Worker if (!gem_can_store_dword(fd, ring))
369*d83cc019SAndroid Build Coastguard Worker continue;
370*d83cc019SAndroid Build Coastguard Worker
371*d83cc019SAndroid Build Coastguard Worker names[num_engines] = e__->name;
372*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
373*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
374*d83cc019SAndroid Build Coastguard Worker break;
375*d83cc019SAndroid Build Coastguard Worker }
376*d83cc019SAndroid Build Coastguard Worker igt_require(num_engines);
377*d83cc019SAndroid Build Coastguard Worker } else {
378*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
379*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, ring));
380*d83cc019SAndroid Build Coastguard Worker names[num_engines] = NULL;
381*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
382*d83cc019SAndroid Build Coastguard Worker }
383*d83cc019SAndroid Build Coastguard Worker
384*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
385*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_engines) {
386*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
387*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object;
388*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
389*d83cc019SAndroid Build Coastguard Worker double end, this, elapsed, now, baseline;
390*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
391*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin[2];
392*d83cc019SAndroid Build Coastguard Worker
393*d83cc019SAndroid Build Coastguard Worker memset(&object, 0, sizeof(object));
394*d83cc019SAndroid Build Coastguard Worker object.handle = gem_create(fd, 4096);
395*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object.handle, 0, &bbe, sizeof(bbe));
396*d83cc019SAndroid Build Coastguard Worker
397*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
398*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&object);
399*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
400*d83cc019SAndroid Build Coastguard Worker execbuf.flags = engines[child % num_engines];
401*d83cc019SAndroid Build Coastguard Worker
402*d83cc019SAndroid Build Coastguard Worker spin[0] = __igt_spin_new(fd,
403*d83cc019SAndroid Build Coastguard Worker .engine = execbuf.flags,
404*d83cc019SAndroid Build Coastguard Worker .flags = (IGT_SPIN_POLL_RUN |
405*d83cc019SAndroid Build Coastguard Worker IGT_SPIN_FAST));
406*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_spin_has_poll(spin[0]));
407*d83cc019SAndroid Build Coastguard Worker
408*d83cc019SAndroid Build Coastguard Worker spin[1] = __igt_spin_new(fd,
409*d83cc019SAndroid Build Coastguard Worker .engine = execbuf.flags,
410*d83cc019SAndroid Build Coastguard Worker .flags = (IGT_SPIN_POLL_RUN |
411*d83cc019SAndroid Build Coastguard Worker IGT_SPIN_FAST));
412*d83cc019SAndroid Build Coastguard Worker
413*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
414*d83cc019SAndroid Build Coastguard Worker
415*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin[1]);
416*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin[0]);
417*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
418*d83cc019SAndroid Build Coastguard Worker
419*d83cc019SAndroid Build Coastguard Worker for (int warmup = 0; warmup <= 1; warmup++) {
420*d83cc019SAndroid Build Coastguard Worker igt_spin_reset(spin[0]);
421*d83cc019SAndroid Build Coastguard Worker
422*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &spin[0]->execbuf);
423*d83cc019SAndroid Build Coastguard Worker
424*d83cc019SAndroid Build Coastguard Worker end = gettime() + timeout/10.;
425*d83cc019SAndroid Build Coastguard Worker elapsed = 0;
426*d83cc019SAndroid Build Coastguard Worker cycles = 0;
427*d83cc019SAndroid Build Coastguard Worker do {
428*d83cc019SAndroid Build Coastguard Worker igt_spin_busywait_until_started(spin[0]);
429*d83cc019SAndroid Build Coastguard Worker
430*d83cc019SAndroid Build Coastguard Worker igt_spin_reset(spin[1]);
431*d83cc019SAndroid Build Coastguard Worker
432*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &spin[1]->execbuf);
433*d83cc019SAndroid Build Coastguard Worker
434*d83cc019SAndroid Build Coastguard Worker this = gettime();
435*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin[0]);
436*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, spin[0]->handle);
437*d83cc019SAndroid Build Coastguard Worker now = gettime();
438*d83cc019SAndroid Build Coastguard Worker
439*d83cc019SAndroid Build Coastguard Worker elapsed += now - this;
440*d83cc019SAndroid Build Coastguard Worker cycles++;
441*d83cc019SAndroid Build Coastguard Worker igt_swap(spin[0], spin[1]);
442*d83cc019SAndroid Build Coastguard Worker } while (now < end);
443*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin[0]);
444*d83cc019SAndroid Build Coastguard Worker baseline = elapsed / cycles;
445*d83cc019SAndroid Build Coastguard Worker }
446*d83cc019SAndroid Build Coastguard Worker igt_info("%s%saseline %ld cycles: %.3f us\n",
447*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
448*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " b" : "B",
449*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6/cycles);
450*d83cc019SAndroid Build Coastguard Worker
451*d83cc019SAndroid Build Coastguard Worker igt_spin_reset(spin[0]);
452*d83cc019SAndroid Build Coastguard Worker
453*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &spin[0]->execbuf);
454*d83cc019SAndroid Build Coastguard Worker
455*d83cc019SAndroid Build Coastguard Worker end = gettime() + timeout;
456*d83cc019SAndroid Build Coastguard Worker elapsed = 0;
457*d83cc019SAndroid Build Coastguard Worker cycles = 0;
458*d83cc019SAndroid Build Coastguard Worker do {
459*d83cc019SAndroid Build Coastguard Worker igt_spin_busywait_until_started(spin[0]);
460*d83cc019SAndroid Build Coastguard Worker
461*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < wlen; n++)
462*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
463*d83cc019SAndroid Build Coastguard Worker
464*d83cc019SAndroid Build Coastguard Worker igt_spin_reset(spin[1]);
465*d83cc019SAndroid Build Coastguard Worker
466*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &spin[1]->execbuf);
467*d83cc019SAndroid Build Coastguard Worker
468*d83cc019SAndroid Build Coastguard Worker this = gettime();
469*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin[0]);
470*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
471*d83cc019SAndroid Build Coastguard Worker now = gettime();
472*d83cc019SAndroid Build Coastguard Worker
473*d83cc019SAndroid Build Coastguard Worker elapsed += now - this;
474*d83cc019SAndroid Build Coastguard Worker cycles++;
475*d83cc019SAndroid Build Coastguard Worker igt_swap(spin[0], spin[1]);
476*d83cc019SAndroid Build Coastguard Worker } while (now < end);
477*d83cc019SAndroid Build Coastguard Worker igt_spin_end(spin[0]);
478*d83cc019SAndroid Build Coastguard Worker elapsed -= cycles * baseline;
479*d83cc019SAndroid Build Coastguard Worker
480*d83cc019SAndroid Build Coastguard Worker igt_info("%s%sompleted %ld cycles: %.3f + %.3f us\n",
481*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
482*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " c" : "C",
483*d83cc019SAndroid Build Coastguard Worker cycles, 1e6*baseline, elapsed*1e6/cycles);
484*d83cc019SAndroid Build Coastguard Worker
485*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin[1]);
486*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin[0]);
487*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object.handle);
488*d83cc019SAndroid Build Coastguard Worker }
489*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(2*timeout, NULL);
490*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
491*d83cc019SAndroid Build Coastguard Worker }
492*d83cc019SAndroid Build Coastguard Worker
493*d83cc019SAndroid Build Coastguard Worker static void
store_ring(int fd,unsigned ring,int num_children,int timeout)494*d83cc019SAndroid Build Coastguard Worker store_ring(int fd, unsigned ring, int num_children, int timeout)
495*d83cc019SAndroid Build Coastguard Worker {
496*d83cc019SAndroid Build Coastguard Worker const int gen = intel_gen(intel_get_drm_devid(fd));
497*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
498*d83cc019SAndroid Build Coastguard Worker const char *names[16];
499*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
500*d83cc019SAndroid Build Coastguard Worker
501*d83cc019SAndroid Build Coastguard Worker if (ring == ALL_ENGINES) {
502*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
503*d83cc019SAndroid Build Coastguard Worker if (!gem_can_store_dword(fd, ring))
504*d83cc019SAndroid Build Coastguard Worker continue;
505*d83cc019SAndroid Build Coastguard Worker
506*d83cc019SAndroid Build Coastguard Worker names[num_engines] = e__->name;
507*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
508*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
509*d83cc019SAndroid Build Coastguard Worker break;
510*d83cc019SAndroid Build Coastguard Worker }
511*d83cc019SAndroid Build Coastguard Worker
512*d83cc019SAndroid Build Coastguard Worker num_children *= num_engines;
513*d83cc019SAndroid Build Coastguard Worker } else {
514*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
515*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, ring));
516*d83cc019SAndroid Build Coastguard Worker names[num_engines] = NULL;
517*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
518*d83cc019SAndroid Build Coastguard Worker }
519*d83cc019SAndroid Build Coastguard Worker
520*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
521*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_children) {
522*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
523*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object[2];
524*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc[1024];
525*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
526*d83cc019SAndroid Build Coastguard Worker double start, elapsed;
527*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
528*d83cc019SAndroid Build Coastguard Worker uint32_t *batch, *b;
529*d83cc019SAndroid Build Coastguard Worker
530*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
531*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(object);
532*d83cc019SAndroid Build Coastguard Worker execbuf.flags = engines[child % num_engines];
533*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
534*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
535*d83cc019SAndroid Build Coastguard Worker if (gen < 6)
536*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= I915_EXEC_SECURE;
537*d83cc019SAndroid Build Coastguard Worker
538*d83cc019SAndroid Build Coastguard Worker memset(object, 0, sizeof(object));
539*d83cc019SAndroid Build Coastguard Worker object[0].handle = gem_create(fd, 4096);
540*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object[0].handle, 0, &bbe, sizeof(bbe));
541*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
542*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
543*d83cc019SAndroid Build Coastguard Worker
544*d83cc019SAndroid Build Coastguard Worker object[0].flags |= EXEC_OBJECT_WRITE;
545*d83cc019SAndroid Build Coastguard Worker object[1].handle = gem_create(fd, 20*1024);
546*d83cc019SAndroid Build Coastguard Worker
547*d83cc019SAndroid Build Coastguard Worker object[1].relocs_ptr = to_user_pointer(reloc);
548*d83cc019SAndroid Build Coastguard Worker object[1].relocation_count = 1024;
549*d83cc019SAndroid Build Coastguard Worker
550*d83cc019SAndroid Build Coastguard Worker batch = gem_mmap__cpu(fd, object[1].handle, 0, 20*1024,
551*d83cc019SAndroid Build Coastguard Worker PROT_WRITE | PROT_READ);
552*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, object[1].handle,
553*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
554*d83cc019SAndroid Build Coastguard Worker
555*d83cc019SAndroid Build Coastguard Worker memset(reloc, 0, sizeof(reloc));
556*d83cc019SAndroid Build Coastguard Worker b = batch;
557*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < 1024; i++) {
558*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
559*d83cc019SAndroid Build Coastguard Worker
560*d83cc019SAndroid Build Coastguard Worker reloc[i].presumed_offset = object[0].offset;
561*d83cc019SAndroid Build Coastguard Worker reloc[i].offset = (b - batch + 1) * sizeof(*batch);
562*d83cc019SAndroid Build Coastguard Worker reloc[i].delta = i * sizeof(uint32_t);
563*d83cc019SAndroid Build Coastguard Worker reloc[i].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
564*d83cc019SAndroid Build Coastguard Worker reloc[i].write_domain = I915_GEM_DOMAIN_INSTRUCTION;
565*d83cc019SAndroid Build Coastguard Worker
566*d83cc019SAndroid Build Coastguard Worker offset = object[0].offset + reloc[i].delta;
567*d83cc019SAndroid Build Coastguard Worker *b++ = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
568*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
569*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
570*d83cc019SAndroid Build Coastguard Worker *b++ = offset >> 32;
571*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
572*d83cc019SAndroid Build Coastguard Worker *b++ = 0;
573*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
574*d83cc019SAndroid Build Coastguard Worker reloc[i].offset += sizeof(*batch);
575*d83cc019SAndroid Build Coastguard Worker } else {
576*d83cc019SAndroid Build Coastguard Worker b[-1] -= 1;
577*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
578*d83cc019SAndroid Build Coastguard Worker }
579*d83cc019SAndroid Build Coastguard Worker *b++ = i;
580*d83cc019SAndroid Build Coastguard Worker }
581*d83cc019SAndroid Build Coastguard Worker *b++ = MI_BATCH_BUFFER_END;
582*d83cc019SAndroid Build Coastguard Worker igt_assert((b - batch)*sizeof(uint32_t) < 20*1024);
583*d83cc019SAndroid Build Coastguard Worker munmap(batch, 20*1024);
584*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
585*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
586*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object[1].handle);
587*d83cc019SAndroid Build Coastguard Worker
588*d83cc019SAndroid Build Coastguard Worker start = gettime();
589*d83cc019SAndroid Build Coastguard Worker cycles = 0;
590*d83cc019SAndroid Build Coastguard Worker do {
591*d83cc019SAndroid Build Coastguard Worker do {
592*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
593*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object[1].handle);
594*d83cc019SAndroid Build Coastguard Worker } while (++cycles & 1023);
595*d83cc019SAndroid Build Coastguard Worker } while ((elapsed = gettime() - start) < timeout);
596*d83cc019SAndroid Build Coastguard Worker igt_info("%s%sompleted %ld cycles: %.3f us\n",
597*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
598*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " c" : "C",
599*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6/cycles);
600*d83cc019SAndroid Build Coastguard Worker
601*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object[1].handle);
602*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object[0].handle);
603*d83cc019SAndroid Build Coastguard Worker }
604*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(timeout+10, NULL);
605*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
606*d83cc019SAndroid Build Coastguard Worker }
607*d83cc019SAndroid Build Coastguard Worker
608*d83cc019SAndroid Build Coastguard Worker static void
switch_ring(int fd,unsigned ring,int num_children,int timeout)609*d83cc019SAndroid Build Coastguard Worker switch_ring(int fd, unsigned ring, int num_children, int timeout)
610*d83cc019SAndroid Build Coastguard Worker {
611*d83cc019SAndroid Build Coastguard Worker const int gen = intel_gen(intel_get_drm_devid(fd));
612*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
613*d83cc019SAndroid Build Coastguard Worker const char *names[16];
614*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
615*d83cc019SAndroid Build Coastguard Worker
616*d83cc019SAndroid Build Coastguard Worker gem_require_contexts(fd);
617*d83cc019SAndroid Build Coastguard Worker
618*d83cc019SAndroid Build Coastguard Worker if (ring == ALL_ENGINES) {
619*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
620*d83cc019SAndroid Build Coastguard Worker if (!gem_can_store_dword(fd, ring))
621*d83cc019SAndroid Build Coastguard Worker continue;
622*d83cc019SAndroid Build Coastguard Worker
623*d83cc019SAndroid Build Coastguard Worker names[num_engines] = e__->name;
624*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
625*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
626*d83cc019SAndroid Build Coastguard Worker break;
627*d83cc019SAndroid Build Coastguard Worker }
628*d83cc019SAndroid Build Coastguard Worker
629*d83cc019SAndroid Build Coastguard Worker num_children *= num_engines;
630*d83cc019SAndroid Build Coastguard Worker } else {
631*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
632*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, ring));
633*d83cc019SAndroid Build Coastguard Worker names[num_engines] = NULL;
634*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
635*d83cc019SAndroid Build Coastguard Worker }
636*d83cc019SAndroid Build Coastguard Worker
637*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
638*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_children) {
639*d83cc019SAndroid Build Coastguard Worker struct context {
640*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object[2];
641*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc[1024];
642*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
643*d83cc019SAndroid Build Coastguard Worker } contexts[2];
644*d83cc019SAndroid Build Coastguard Worker double elapsed, baseline;
645*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
646*d83cc019SAndroid Build Coastguard Worker
647*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(contexts); i++) {
648*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
649*d83cc019SAndroid Build Coastguard Worker const uint32_t sz = 32 << 10;
650*d83cc019SAndroid Build Coastguard Worker struct context *c = &contexts[i];
651*d83cc019SAndroid Build Coastguard Worker uint32_t *batch, *b;
652*d83cc019SAndroid Build Coastguard Worker
653*d83cc019SAndroid Build Coastguard Worker memset(&c->execbuf, 0, sizeof(c->execbuf));
654*d83cc019SAndroid Build Coastguard Worker c->execbuf.buffers_ptr = to_user_pointer(c->object);
655*d83cc019SAndroid Build Coastguard Worker c->execbuf.flags = engines[child % num_engines];
656*d83cc019SAndroid Build Coastguard Worker c->execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
657*d83cc019SAndroid Build Coastguard Worker c->execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
658*d83cc019SAndroid Build Coastguard Worker if (gen < 6)
659*d83cc019SAndroid Build Coastguard Worker c->execbuf.flags |= I915_EXEC_SECURE;
660*d83cc019SAndroid Build Coastguard Worker c->execbuf.rsvd1 = gem_context_create(fd);
661*d83cc019SAndroid Build Coastguard Worker
662*d83cc019SAndroid Build Coastguard Worker memset(c->object, 0, sizeof(c->object));
663*d83cc019SAndroid Build Coastguard Worker c->object[0].handle = gem_create(fd, 4096);
664*d83cc019SAndroid Build Coastguard Worker gem_write(fd, c->object[0].handle, 0, &bbe, sizeof(bbe));
665*d83cc019SAndroid Build Coastguard Worker c->execbuf.buffer_count = 1;
666*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &c->execbuf);
667*d83cc019SAndroid Build Coastguard Worker
668*d83cc019SAndroid Build Coastguard Worker c->object[0].flags |= EXEC_OBJECT_WRITE;
669*d83cc019SAndroid Build Coastguard Worker c->object[1].handle = gem_create(fd, sz);
670*d83cc019SAndroid Build Coastguard Worker
671*d83cc019SAndroid Build Coastguard Worker c->object[1].relocs_ptr = to_user_pointer(c->reloc);
672*d83cc019SAndroid Build Coastguard Worker c->object[1].relocation_count = 1024 * i;
673*d83cc019SAndroid Build Coastguard Worker
674*d83cc019SAndroid Build Coastguard Worker batch = gem_mmap__cpu(fd, c->object[1].handle, 0, sz,
675*d83cc019SAndroid Build Coastguard Worker PROT_WRITE | PROT_READ);
676*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, c->object[1].handle,
677*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
678*d83cc019SAndroid Build Coastguard Worker
679*d83cc019SAndroid Build Coastguard Worker memset(c->reloc, 0, sizeof(c->reloc));
680*d83cc019SAndroid Build Coastguard Worker b = batch;
681*d83cc019SAndroid Build Coastguard Worker for (int r = 0; r < c->object[1].relocation_count; r++) {
682*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
683*d83cc019SAndroid Build Coastguard Worker
684*d83cc019SAndroid Build Coastguard Worker c->reloc[r].presumed_offset = c->object[0].offset;
685*d83cc019SAndroid Build Coastguard Worker c->reloc[r].offset = (b - batch + 1) * sizeof(*batch);
686*d83cc019SAndroid Build Coastguard Worker c->reloc[r].delta = r * sizeof(uint32_t);
687*d83cc019SAndroid Build Coastguard Worker c->reloc[r].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
688*d83cc019SAndroid Build Coastguard Worker c->reloc[r].write_domain = I915_GEM_DOMAIN_INSTRUCTION;
689*d83cc019SAndroid Build Coastguard Worker
690*d83cc019SAndroid Build Coastguard Worker offset = c->object[0].offset + c->reloc[r].delta;
691*d83cc019SAndroid Build Coastguard Worker *b++ = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
692*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
693*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
694*d83cc019SAndroid Build Coastguard Worker *b++ = offset >> 32;
695*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
696*d83cc019SAndroid Build Coastguard Worker *b++ = 0;
697*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
698*d83cc019SAndroid Build Coastguard Worker c->reloc[r].offset += sizeof(*batch);
699*d83cc019SAndroid Build Coastguard Worker } else {
700*d83cc019SAndroid Build Coastguard Worker b[-1] -= 1;
701*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
702*d83cc019SAndroid Build Coastguard Worker }
703*d83cc019SAndroid Build Coastguard Worker *b++ = r;
704*d83cc019SAndroid Build Coastguard Worker *b++ = 0x5 << 23;
705*d83cc019SAndroid Build Coastguard Worker }
706*d83cc019SAndroid Build Coastguard Worker *b++ = MI_BATCH_BUFFER_END;
707*d83cc019SAndroid Build Coastguard Worker igt_assert((b - batch)*sizeof(uint32_t) < sz);
708*d83cc019SAndroid Build Coastguard Worker munmap(batch, sz);
709*d83cc019SAndroid Build Coastguard Worker c->execbuf.buffer_count = 2;
710*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &c->execbuf);
711*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, c->object[1].handle);
712*d83cc019SAndroid Build Coastguard Worker }
713*d83cc019SAndroid Build Coastguard Worker
714*d83cc019SAndroid Build Coastguard Worker cycles = 0;
715*d83cc019SAndroid Build Coastguard Worker baseline = 0;
716*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
717*d83cc019SAndroid Build Coastguard Worker do {
718*d83cc019SAndroid Build Coastguard Worker double this;
719*d83cc019SAndroid Build Coastguard Worker
720*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &contexts[1].execbuf);
721*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &contexts[0].execbuf);
722*d83cc019SAndroid Build Coastguard Worker
723*d83cc019SAndroid Build Coastguard Worker this = gettime();
724*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, contexts[1].object[1].handle);
725*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, contexts[0].object[1].handle);
726*d83cc019SAndroid Build Coastguard Worker baseline += gettime() - this;
727*d83cc019SAndroid Build Coastguard Worker } while (++cycles & 1023);
728*d83cc019SAndroid Build Coastguard Worker }
729*d83cc019SAndroid Build Coastguard Worker baseline /= cycles;
730*d83cc019SAndroid Build Coastguard Worker
731*d83cc019SAndroid Build Coastguard Worker cycles = 0;
732*d83cc019SAndroid Build Coastguard Worker elapsed = 0;
733*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
734*d83cc019SAndroid Build Coastguard Worker do {
735*d83cc019SAndroid Build Coastguard Worker double this;
736*d83cc019SAndroid Build Coastguard Worker
737*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &contexts[1].execbuf);
738*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &contexts[0].execbuf);
739*d83cc019SAndroid Build Coastguard Worker
740*d83cc019SAndroid Build Coastguard Worker this = gettime();
741*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, contexts[0].object[1].handle);
742*d83cc019SAndroid Build Coastguard Worker elapsed += gettime() - this;
743*d83cc019SAndroid Build Coastguard Worker
744*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, contexts[1].object[1].handle);
745*d83cc019SAndroid Build Coastguard Worker } while (++cycles & 1023);
746*d83cc019SAndroid Build Coastguard Worker }
747*d83cc019SAndroid Build Coastguard Worker elapsed /= cycles;
748*d83cc019SAndroid Build Coastguard Worker
749*d83cc019SAndroid Build Coastguard Worker igt_info("%s%sompleted %ld cycles: %.3f us, baseline %.3f us\n",
750*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
751*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " c" : "C",
752*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6, baseline*1e6);
753*d83cc019SAndroid Build Coastguard Worker
754*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(contexts); i++) {
755*d83cc019SAndroid Build Coastguard Worker gem_close(fd, contexts[i].object[1].handle);
756*d83cc019SAndroid Build Coastguard Worker gem_close(fd, contexts[i].object[0].handle);
757*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, contexts[i].execbuf.rsvd1);
758*d83cc019SAndroid Build Coastguard Worker }
759*d83cc019SAndroid Build Coastguard Worker }
760*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(timeout+10, NULL);
761*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
762*d83cc019SAndroid Build Coastguard Worker }
763*d83cc019SAndroid Build Coastguard Worker
xchg(void * array,unsigned i,unsigned j)764*d83cc019SAndroid Build Coastguard Worker static void xchg(void *array, unsigned i, unsigned j)
765*d83cc019SAndroid Build Coastguard Worker {
766*d83cc019SAndroid Build Coastguard Worker uint32_t *u32 = array;
767*d83cc019SAndroid Build Coastguard Worker uint32_t tmp = u32[i];
768*d83cc019SAndroid Build Coastguard Worker u32[i] = u32[j];
769*d83cc019SAndroid Build Coastguard Worker u32[j] = tmp;
770*d83cc019SAndroid Build Coastguard Worker }
771*d83cc019SAndroid Build Coastguard Worker
772*d83cc019SAndroid Build Coastguard Worker struct waiter {
773*d83cc019SAndroid Build Coastguard Worker pthread_t thread;
774*d83cc019SAndroid Build Coastguard Worker pthread_mutex_t mutex;
775*d83cc019SAndroid Build Coastguard Worker pthread_cond_t cond;
776*d83cc019SAndroid Build Coastguard Worker
777*d83cc019SAndroid Build Coastguard Worker int ready;
778*d83cc019SAndroid Build Coastguard Worker volatile int *done;
779*d83cc019SAndroid Build Coastguard Worker
780*d83cc019SAndroid Build Coastguard Worker int fd;
781*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object;
782*d83cc019SAndroid Build Coastguard Worker uint32_t handles[64];
783*d83cc019SAndroid Build Coastguard Worker };
784*d83cc019SAndroid Build Coastguard Worker
waiter(void * arg)785*d83cc019SAndroid Build Coastguard Worker static void *waiter(void *arg)
786*d83cc019SAndroid Build Coastguard Worker {
787*d83cc019SAndroid Build Coastguard Worker struct waiter *w = arg;
788*d83cc019SAndroid Build Coastguard Worker
789*d83cc019SAndroid Build Coastguard Worker do {
790*d83cc019SAndroid Build Coastguard Worker pthread_mutex_lock(&w->mutex);
791*d83cc019SAndroid Build Coastguard Worker w->ready = 0;
792*d83cc019SAndroid Build Coastguard Worker pthread_cond_signal(&w->cond);
793*d83cc019SAndroid Build Coastguard Worker while (!w->ready)
794*d83cc019SAndroid Build Coastguard Worker pthread_cond_wait(&w->cond, &w->mutex);
795*d83cc019SAndroid Build Coastguard Worker pthread_mutex_unlock(&w->mutex);
796*d83cc019SAndroid Build Coastguard Worker if (*w->done < 0)
797*d83cc019SAndroid Build Coastguard Worker return NULL;
798*d83cc019SAndroid Build Coastguard Worker
799*d83cc019SAndroid Build Coastguard Worker gem_sync(w->fd, w->object.handle);
800*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < ARRAY_SIZE(w->handles); n++)
801*d83cc019SAndroid Build Coastguard Worker gem_sync(w->fd, w->handles[n]);
802*d83cc019SAndroid Build Coastguard Worker } while (1);
803*d83cc019SAndroid Build Coastguard Worker }
804*d83cc019SAndroid Build Coastguard Worker
805*d83cc019SAndroid Build Coastguard Worker static void
__store_many(int fd,unsigned ring,int timeout,unsigned long * cycles)806*d83cc019SAndroid Build Coastguard Worker __store_many(int fd, unsigned ring, int timeout, unsigned long *cycles)
807*d83cc019SAndroid Build Coastguard Worker {
808*d83cc019SAndroid Build Coastguard Worker const int gen = intel_gen(intel_get_drm_devid(fd));
809*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
810*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object[2];
811*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
812*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc[1024];
813*d83cc019SAndroid Build Coastguard Worker struct waiter threads[64];
814*d83cc019SAndroid Build Coastguard Worker int order[64];
815*d83cc019SAndroid Build Coastguard Worker uint32_t *batch, *b;
816*d83cc019SAndroid Build Coastguard Worker int done;
817*d83cc019SAndroid Build Coastguard Worker
818*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
819*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(object);
820*d83cc019SAndroid Build Coastguard Worker execbuf.flags = ring;
821*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
822*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
823*d83cc019SAndroid Build Coastguard Worker if (gen < 6)
824*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= I915_EXEC_SECURE;
825*d83cc019SAndroid Build Coastguard Worker
826*d83cc019SAndroid Build Coastguard Worker memset(object, 0, sizeof(object));
827*d83cc019SAndroid Build Coastguard Worker object[0].handle = gem_create(fd, 4096);
828*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object[0].handle, 0, &bbe, sizeof(bbe));
829*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
830*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
831*d83cc019SAndroid Build Coastguard Worker object[0].flags |= EXEC_OBJECT_WRITE;
832*d83cc019SAndroid Build Coastguard Worker
833*d83cc019SAndroid Build Coastguard Worker object[1].relocs_ptr = to_user_pointer(reloc);
834*d83cc019SAndroid Build Coastguard Worker object[1].relocation_count = 1024;
835*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
836*d83cc019SAndroid Build Coastguard Worker
837*d83cc019SAndroid Build Coastguard Worker memset(reloc, 0, sizeof(reloc));
838*d83cc019SAndroid Build Coastguard Worker b = batch = malloc(20*1024);
839*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < 1024; i++) {
840*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
841*d83cc019SAndroid Build Coastguard Worker
842*d83cc019SAndroid Build Coastguard Worker reloc[i].presumed_offset = object[0].offset;
843*d83cc019SAndroid Build Coastguard Worker reloc[i].offset = (b - batch + 1) * sizeof(*batch);
844*d83cc019SAndroid Build Coastguard Worker reloc[i].delta = i * sizeof(uint32_t);
845*d83cc019SAndroid Build Coastguard Worker reloc[i].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
846*d83cc019SAndroid Build Coastguard Worker reloc[i].write_domain = I915_GEM_DOMAIN_INSTRUCTION;
847*d83cc019SAndroid Build Coastguard Worker
848*d83cc019SAndroid Build Coastguard Worker offset = object[0].offset + reloc[i].delta;
849*d83cc019SAndroid Build Coastguard Worker *b++ = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
850*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
851*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
852*d83cc019SAndroid Build Coastguard Worker *b++ = offset >> 32;
853*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
854*d83cc019SAndroid Build Coastguard Worker *b++ = 0;
855*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
856*d83cc019SAndroid Build Coastguard Worker reloc[i].offset += sizeof(*batch);
857*d83cc019SAndroid Build Coastguard Worker } else {
858*d83cc019SAndroid Build Coastguard Worker b[-1] -= 1;
859*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
860*d83cc019SAndroid Build Coastguard Worker }
861*d83cc019SAndroid Build Coastguard Worker *b++ = i;
862*d83cc019SAndroid Build Coastguard Worker }
863*d83cc019SAndroid Build Coastguard Worker *b++ = MI_BATCH_BUFFER_END;
864*d83cc019SAndroid Build Coastguard Worker igt_assert((b - batch)*sizeof(uint32_t) < 20*1024);
865*d83cc019SAndroid Build Coastguard Worker
866*d83cc019SAndroid Build Coastguard Worker done = 0;
867*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(threads); i++) {
868*d83cc019SAndroid Build Coastguard Worker threads[i].fd = fd;
869*d83cc019SAndroid Build Coastguard Worker threads[i].object = object[1];
870*d83cc019SAndroid Build Coastguard Worker threads[i].object.handle = gem_create(fd, 20*1024);
871*d83cc019SAndroid Build Coastguard Worker gem_write(fd, threads[i].object.handle, 0, batch, 20*1024);
872*d83cc019SAndroid Build Coastguard Worker
873*d83cc019SAndroid Build Coastguard Worker pthread_cond_init(&threads[i].cond, NULL);
874*d83cc019SAndroid Build Coastguard Worker pthread_mutex_init(&threads[i].mutex, NULL);
875*d83cc019SAndroid Build Coastguard Worker threads[i].done = &done;
876*d83cc019SAndroid Build Coastguard Worker threads[i].ready = 0;
877*d83cc019SAndroid Build Coastguard Worker
878*d83cc019SAndroid Build Coastguard Worker pthread_create(&threads[i].thread, NULL, waiter, &threads[i]);
879*d83cc019SAndroid Build Coastguard Worker order[i] = i;
880*d83cc019SAndroid Build Coastguard Worker }
881*d83cc019SAndroid Build Coastguard Worker free(batch);
882*d83cc019SAndroid Build Coastguard Worker
883*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(threads); i++) {
884*d83cc019SAndroid Build Coastguard Worker for (int j = 0; j < ARRAY_SIZE(threads); j++)
885*d83cc019SAndroid Build Coastguard Worker threads[i].handles[j] = threads[j].object.handle;
886*d83cc019SAndroid Build Coastguard Worker }
887*d83cc019SAndroid Build Coastguard Worker
888*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(timeout) {
889*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(threads); i++) {
890*d83cc019SAndroid Build Coastguard Worker pthread_mutex_lock(&threads[i].mutex);
891*d83cc019SAndroid Build Coastguard Worker while (threads[i].ready)
892*d83cc019SAndroid Build Coastguard Worker pthread_cond_wait(&threads[i].cond,
893*d83cc019SAndroid Build Coastguard Worker &threads[i].mutex);
894*d83cc019SAndroid Build Coastguard Worker pthread_mutex_unlock(&threads[i].mutex);
895*d83cc019SAndroid Build Coastguard Worker igt_permute_array(threads[i].handles,
896*d83cc019SAndroid Build Coastguard Worker ARRAY_SIZE(threads[i].handles),
897*d83cc019SAndroid Build Coastguard Worker xchg);
898*d83cc019SAndroid Build Coastguard Worker }
899*d83cc019SAndroid Build Coastguard Worker
900*d83cc019SAndroid Build Coastguard Worker igt_permute_array(order, ARRAY_SIZE(threads), xchg);
901*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(threads); i++) {
902*d83cc019SAndroid Build Coastguard Worker object[1] = threads[i].object;
903*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
904*d83cc019SAndroid Build Coastguard Worker threads[i].object = object[1];
905*d83cc019SAndroid Build Coastguard Worker }
906*d83cc019SAndroid Build Coastguard Worker ++*cycles;
907*d83cc019SAndroid Build Coastguard Worker
908*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(threads); i++) {
909*d83cc019SAndroid Build Coastguard Worker struct waiter *w = &threads[order[i]];
910*d83cc019SAndroid Build Coastguard Worker
911*d83cc019SAndroid Build Coastguard Worker w->ready = 1;
912*d83cc019SAndroid Build Coastguard Worker pthread_cond_signal(&w->cond);
913*d83cc019SAndroid Build Coastguard Worker }
914*d83cc019SAndroid Build Coastguard Worker }
915*d83cc019SAndroid Build Coastguard Worker
916*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(threads); i++) {
917*d83cc019SAndroid Build Coastguard Worker pthread_mutex_lock(&threads[i].mutex);
918*d83cc019SAndroid Build Coastguard Worker while (threads[i].ready)
919*d83cc019SAndroid Build Coastguard Worker pthread_cond_wait(&threads[i].cond, &threads[i].mutex);
920*d83cc019SAndroid Build Coastguard Worker pthread_mutex_unlock(&threads[i].mutex);
921*d83cc019SAndroid Build Coastguard Worker }
922*d83cc019SAndroid Build Coastguard Worker done = -1;
923*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(threads); i++) {
924*d83cc019SAndroid Build Coastguard Worker threads[i].ready = 1;
925*d83cc019SAndroid Build Coastguard Worker pthread_cond_signal(&threads[i].cond);
926*d83cc019SAndroid Build Coastguard Worker pthread_join(threads[i].thread, NULL);
927*d83cc019SAndroid Build Coastguard Worker gem_close(fd, threads[i].object.handle);
928*d83cc019SAndroid Build Coastguard Worker }
929*d83cc019SAndroid Build Coastguard Worker
930*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object[0].handle);
931*d83cc019SAndroid Build Coastguard Worker }
932*d83cc019SAndroid Build Coastguard Worker
933*d83cc019SAndroid Build Coastguard Worker static void
store_many(int fd,unsigned ring,int timeout)934*d83cc019SAndroid Build Coastguard Worker store_many(int fd, unsigned ring, int timeout)
935*d83cc019SAndroid Build Coastguard Worker {
936*d83cc019SAndroid Build Coastguard Worker unsigned long *shared;
937*d83cc019SAndroid Build Coastguard Worker const char *names[16];
938*d83cc019SAndroid Build Coastguard Worker int n = 0;
939*d83cc019SAndroid Build Coastguard Worker
940*d83cc019SAndroid Build Coastguard Worker shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
941*d83cc019SAndroid Build Coastguard Worker igt_assert(shared != MAP_FAILED);
942*d83cc019SAndroid Build Coastguard Worker
943*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
944*d83cc019SAndroid Build Coastguard Worker
945*d83cc019SAndroid Build Coastguard Worker if (ring == ALL_ENGINES) {
946*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
947*d83cc019SAndroid Build Coastguard Worker if (!gem_can_store_dword(fd, ring))
948*d83cc019SAndroid Build Coastguard Worker continue;
949*d83cc019SAndroid Build Coastguard Worker
950*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 1)
951*d83cc019SAndroid Build Coastguard Worker __store_many(fd,
952*d83cc019SAndroid Build Coastguard Worker ring,
953*d83cc019SAndroid Build Coastguard Worker timeout,
954*d83cc019SAndroid Build Coastguard Worker &shared[n]);
955*d83cc019SAndroid Build Coastguard Worker
956*d83cc019SAndroid Build Coastguard Worker names[n++] = e__->name;
957*d83cc019SAndroid Build Coastguard Worker }
958*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
959*d83cc019SAndroid Build Coastguard Worker } else {
960*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
961*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, ring));
962*d83cc019SAndroid Build Coastguard Worker __store_many(fd, ring, timeout, &shared[n]);
963*d83cc019SAndroid Build Coastguard Worker names[n++] = NULL;
964*d83cc019SAndroid Build Coastguard Worker }
965*d83cc019SAndroid Build Coastguard Worker
966*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < n; i++) {
967*d83cc019SAndroid Build Coastguard Worker igt_info("%s%sompleted %ld cycles\n",
968*d83cc019SAndroid Build Coastguard Worker names[i] ?: "", names[i] ? " c" : "C", shared[i]);
969*d83cc019SAndroid Build Coastguard Worker }
970*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
971*d83cc019SAndroid Build Coastguard Worker munmap(shared, 4096);
972*d83cc019SAndroid Build Coastguard Worker }
973*d83cc019SAndroid Build Coastguard Worker
974*d83cc019SAndroid Build Coastguard Worker static void
sync_all(int fd,int num_children,int timeout)975*d83cc019SAndroid Build Coastguard Worker sync_all(int fd, int num_children, int timeout)
976*d83cc019SAndroid Build Coastguard Worker {
977*d83cc019SAndroid Build Coastguard Worker unsigned engines[16], engine;
978*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
979*d83cc019SAndroid Build Coastguard Worker
980*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, engine) {
981*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = engine;
982*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
983*d83cc019SAndroid Build Coastguard Worker break;
984*d83cc019SAndroid Build Coastguard Worker }
985*d83cc019SAndroid Build Coastguard Worker igt_require(num_engines);
986*d83cc019SAndroid Build Coastguard Worker
987*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
988*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_children) {
989*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
990*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object;
991*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
992*d83cc019SAndroid Build Coastguard Worker double start, elapsed;
993*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
994*d83cc019SAndroid Build Coastguard Worker
995*d83cc019SAndroid Build Coastguard Worker memset(&object, 0, sizeof(object));
996*d83cc019SAndroid Build Coastguard Worker object.handle = gem_create(fd, 4096);
997*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object.handle, 0, &bbe, sizeof(bbe));
998*d83cc019SAndroid Build Coastguard Worker
999*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
1000*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&object);
1001*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
1002*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
1003*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
1004*d83cc019SAndroid Build Coastguard Worker
1005*d83cc019SAndroid Build Coastguard Worker start = gettime();
1006*d83cc019SAndroid Build Coastguard Worker cycles = 0;
1007*d83cc019SAndroid Build Coastguard Worker do {
1008*d83cc019SAndroid Build Coastguard Worker do {
1009*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < num_engines; n++) {
1010*d83cc019SAndroid Build Coastguard Worker execbuf.flags = engines[n];
1011*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
1012*d83cc019SAndroid Build Coastguard Worker }
1013*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
1014*d83cc019SAndroid Build Coastguard Worker } while (++cycles & 1023);
1015*d83cc019SAndroid Build Coastguard Worker } while ((elapsed = gettime() - start) < timeout);
1016*d83cc019SAndroid Build Coastguard Worker igt_info("Completed %ld cycles: %.3f us\n",
1017*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6/cycles);
1018*d83cc019SAndroid Build Coastguard Worker
1019*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object.handle);
1020*d83cc019SAndroid Build Coastguard Worker }
1021*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(timeout+10, NULL);
1022*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
1023*d83cc019SAndroid Build Coastguard Worker }
1024*d83cc019SAndroid Build Coastguard Worker
1025*d83cc019SAndroid Build Coastguard Worker static void
store_all(int fd,int num_children,int timeout)1026*d83cc019SAndroid Build Coastguard Worker store_all(int fd, int num_children, int timeout)
1027*d83cc019SAndroid Build Coastguard Worker {
1028*d83cc019SAndroid Build Coastguard Worker const int gen = intel_gen(intel_get_drm_devid(fd));
1029*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
1030*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
1031*d83cc019SAndroid Build Coastguard Worker unsigned int ring;
1032*d83cc019SAndroid Build Coastguard Worker
1033*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
1034*d83cc019SAndroid Build Coastguard Worker if (!gem_can_store_dword(fd, ring))
1035*d83cc019SAndroid Build Coastguard Worker continue;
1036*d83cc019SAndroid Build Coastguard Worker
1037*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
1038*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
1039*d83cc019SAndroid Build Coastguard Worker break;
1040*d83cc019SAndroid Build Coastguard Worker }
1041*d83cc019SAndroid Build Coastguard Worker igt_require(num_engines);
1042*d83cc019SAndroid Build Coastguard Worker
1043*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
1044*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_children) {
1045*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
1046*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object[2];
1047*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc[1024];
1048*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
1049*d83cc019SAndroid Build Coastguard Worker double start, elapsed;
1050*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
1051*d83cc019SAndroid Build Coastguard Worker uint32_t *batch, *b;
1052*d83cc019SAndroid Build Coastguard Worker
1053*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
1054*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(object);
1055*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
1056*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
1057*d83cc019SAndroid Build Coastguard Worker if (gen < 6)
1058*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= I915_EXEC_SECURE;
1059*d83cc019SAndroid Build Coastguard Worker
1060*d83cc019SAndroid Build Coastguard Worker memset(object, 0, sizeof(object));
1061*d83cc019SAndroid Build Coastguard Worker object[0].handle = gem_create(fd, 4096);
1062*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object[0].handle, 0, &bbe, sizeof(bbe));
1063*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
1064*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
1065*d83cc019SAndroid Build Coastguard Worker
1066*d83cc019SAndroid Build Coastguard Worker object[0].flags |= EXEC_OBJECT_WRITE;
1067*d83cc019SAndroid Build Coastguard Worker object[1].handle = gem_create(fd, 1024*16 + 4096);
1068*d83cc019SAndroid Build Coastguard Worker
1069*d83cc019SAndroid Build Coastguard Worker object[1].relocs_ptr = to_user_pointer(reloc);
1070*d83cc019SAndroid Build Coastguard Worker object[1].relocation_count = 1024;
1071*d83cc019SAndroid Build Coastguard Worker
1072*d83cc019SAndroid Build Coastguard Worker batch = gem_mmap__cpu(fd, object[1].handle, 0, 16*1024 + 4096,
1073*d83cc019SAndroid Build Coastguard Worker PROT_WRITE | PROT_READ);
1074*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, object[1].handle,
1075*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
1076*d83cc019SAndroid Build Coastguard Worker
1077*d83cc019SAndroid Build Coastguard Worker memset(reloc, 0, sizeof(reloc));
1078*d83cc019SAndroid Build Coastguard Worker b = batch;
1079*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < 1024; i++) {
1080*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
1081*d83cc019SAndroid Build Coastguard Worker
1082*d83cc019SAndroid Build Coastguard Worker reloc[i].presumed_offset = object[0].offset;
1083*d83cc019SAndroid Build Coastguard Worker reloc[i].offset = (b - batch + 1) * sizeof(*batch);
1084*d83cc019SAndroid Build Coastguard Worker reloc[i].delta = i * sizeof(uint32_t);
1085*d83cc019SAndroid Build Coastguard Worker reloc[i].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
1086*d83cc019SAndroid Build Coastguard Worker reloc[i].write_domain = I915_GEM_DOMAIN_INSTRUCTION;
1087*d83cc019SAndroid Build Coastguard Worker
1088*d83cc019SAndroid Build Coastguard Worker offset = object[0].offset + reloc[i].delta;
1089*d83cc019SAndroid Build Coastguard Worker *b++ = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
1090*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
1091*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
1092*d83cc019SAndroid Build Coastguard Worker *b++ = offset >> 32;
1093*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
1094*d83cc019SAndroid Build Coastguard Worker *b++ = 0;
1095*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
1096*d83cc019SAndroid Build Coastguard Worker reloc[i].offset += sizeof(*batch);
1097*d83cc019SAndroid Build Coastguard Worker } else {
1098*d83cc019SAndroid Build Coastguard Worker b[-1] -= 1;
1099*d83cc019SAndroid Build Coastguard Worker *b++ = offset;
1100*d83cc019SAndroid Build Coastguard Worker }
1101*d83cc019SAndroid Build Coastguard Worker *b++ = i;
1102*d83cc019SAndroid Build Coastguard Worker }
1103*d83cc019SAndroid Build Coastguard Worker *b++ = MI_BATCH_BUFFER_END;
1104*d83cc019SAndroid Build Coastguard Worker igt_assert((b - batch)*sizeof(uint32_t) < 20*1024);
1105*d83cc019SAndroid Build Coastguard Worker munmap(batch, 16*1024+4096);
1106*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
1107*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
1108*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object[1].handle);
1109*d83cc019SAndroid Build Coastguard Worker
1110*d83cc019SAndroid Build Coastguard Worker start = gettime();
1111*d83cc019SAndroid Build Coastguard Worker cycles = 0;
1112*d83cc019SAndroid Build Coastguard Worker do {
1113*d83cc019SAndroid Build Coastguard Worker do {
1114*d83cc019SAndroid Build Coastguard Worker igt_permute_array(engines, num_engines, xchg);
1115*d83cc019SAndroid Build Coastguard Worker for (int n = 0; n < num_engines; n++) {
1116*d83cc019SAndroid Build Coastguard Worker execbuf.flags &= ~ENGINE_MASK;
1117*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= engines[n];
1118*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
1119*d83cc019SAndroid Build Coastguard Worker }
1120*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object[1].handle);
1121*d83cc019SAndroid Build Coastguard Worker } while (++cycles & 1023);
1122*d83cc019SAndroid Build Coastguard Worker } while ((elapsed = gettime() - start) < timeout);
1123*d83cc019SAndroid Build Coastguard Worker igt_info("Completed %ld cycles: %.3f us\n",
1124*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6/cycles);
1125*d83cc019SAndroid Build Coastguard Worker
1126*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object[1].handle);
1127*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object[0].handle);
1128*d83cc019SAndroid Build Coastguard Worker }
1129*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(timeout+10, NULL);
1130*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
1131*d83cc019SAndroid Build Coastguard Worker }
1132*d83cc019SAndroid Build Coastguard Worker
1133*d83cc019SAndroid Build Coastguard Worker static void
preempt(int fd,unsigned ring,int num_children,int timeout)1134*d83cc019SAndroid Build Coastguard Worker preempt(int fd, unsigned ring, int num_children, int timeout)
1135*d83cc019SAndroid Build Coastguard Worker {
1136*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
1137*d83cc019SAndroid Build Coastguard Worker const char *names[16];
1138*d83cc019SAndroid Build Coastguard Worker int num_engines = 0;
1139*d83cc019SAndroid Build Coastguard Worker uint32_t ctx[2];
1140*d83cc019SAndroid Build Coastguard Worker
1141*d83cc019SAndroid Build Coastguard Worker if (ring == ALL_ENGINES) {
1142*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, ring) {
1143*d83cc019SAndroid Build Coastguard Worker names[num_engines] = e__->name;
1144*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
1145*d83cc019SAndroid Build Coastguard Worker if (num_engines == ARRAY_SIZE(engines))
1146*d83cc019SAndroid Build Coastguard Worker break;
1147*d83cc019SAndroid Build Coastguard Worker }
1148*d83cc019SAndroid Build Coastguard Worker
1149*d83cc019SAndroid Build Coastguard Worker num_children *= num_engines;
1150*d83cc019SAndroid Build Coastguard Worker } else {
1151*d83cc019SAndroid Build Coastguard Worker gem_require_ring(fd, ring);
1152*d83cc019SAndroid Build Coastguard Worker names[num_engines] = NULL;
1153*d83cc019SAndroid Build Coastguard Worker engines[num_engines++] = ring;
1154*d83cc019SAndroid Build Coastguard Worker }
1155*d83cc019SAndroid Build Coastguard Worker
1156*d83cc019SAndroid Build Coastguard Worker ctx[0] = gem_context_create(fd);
1157*d83cc019SAndroid Build Coastguard Worker gem_context_set_priority(fd, ctx[0], MIN_PRIO);
1158*d83cc019SAndroid Build Coastguard Worker
1159*d83cc019SAndroid Build Coastguard Worker ctx[1] = gem_context_create(fd);
1160*d83cc019SAndroid Build Coastguard Worker gem_context_set_priority(fd, ctx[1], MAX_PRIO);
1161*d83cc019SAndroid Build Coastguard Worker
1162*d83cc019SAndroid Build Coastguard Worker intel_detect_and_clear_missed_interrupts(fd);
1163*d83cc019SAndroid Build Coastguard Worker igt_fork(child, num_children) {
1164*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
1165*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 object;
1166*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
1167*d83cc019SAndroid Build Coastguard Worker double start, elapsed;
1168*d83cc019SAndroid Build Coastguard Worker unsigned long cycles;
1169*d83cc019SAndroid Build Coastguard Worker
1170*d83cc019SAndroid Build Coastguard Worker memset(&object, 0, sizeof(object));
1171*d83cc019SAndroid Build Coastguard Worker object.handle = gem_create(fd, 4096);
1172*d83cc019SAndroid Build Coastguard Worker gem_write(fd, object.handle, 0, &bbe, sizeof(bbe));
1173*d83cc019SAndroid Build Coastguard Worker
1174*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
1175*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&object);
1176*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
1177*d83cc019SAndroid Build Coastguard Worker execbuf.flags = engines[child % num_engines];
1178*d83cc019SAndroid Build Coastguard Worker execbuf.rsvd1 = ctx[1];
1179*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
1180*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
1181*d83cc019SAndroid Build Coastguard Worker
1182*d83cc019SAndroid Build Coastguard Worker start = gettime();
1183*d83cc019SAndroid Build Coastguard Worker cycles = 0;
1184*d83cc019SAndroid Build Coastguard Worker do {
1185*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin =
1186*d83cc019SAndroid Build Coastguard Worker __igt_spin_new(fd,
1187*d83cc019SAndroid Build Coastguard Worker .ctx = ctx[0],
1188*d83cc019SAndroid Build Coastguard Worker .engine = execbuf.flags);
1189*d83cc019SAndroid Build Coastguard Worker
1190*d83cc019SAndroid Build Coastguard Worker do {
1191*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
1192*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, object.handle);
1193*d83cc019SAndroid Build Coastguard Worker } while (++cycles & 1023);
1194*d83cc019SAndroid Build Coastguard Worker
1195*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin);
1196*d83cc019SAndroid Build Coastguard Worker } while ((elapsed = gettime() - start) < timeout);
1197*d83cc019SAndroid Build Coastguard Worker igt_info("%s%sompleted %ld cycles: %.3f us\n",
1198*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ?: "",
1199*d83cc019SAndroid Build Coastguard Worker names[child % num_engines] ? " c" : "C",
1200*d83cc019SAndroid Build Coastguard Worker cycles, elapsed*1e6/cycles);
1201*d83cc019SAndroid Build Coastguard Worker
1202*d83cc019SAndroid Build Coastguard Worker gem_close(fd, object.handle);
1203*d83cc019SAndroid Build Coastguard Worker }
1204*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(timeout+10, NULL);
1205*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
1206*d83cc019SAndroid Build Coastguard Worker
1207*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, ctx[1]);
1208*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, ctx[0]);
1209*d83cc019SAndroid Build Coastguard Worker }
1210*d83cc019SAndroid Build Coastguard Worker
1211*d83cc019SAndroid Build Coastguard Worker igt_main
1212*d83cc019SAndroid Build Coastguard Worker {
1213*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine *e;
1214*d83cc019SAndroid Build Coastguard Worker const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
1215*d83cc019SAndroid Build Coastguard Worker int fd = -1;
1216*d83cc019SAndroid Build Coastguard Worker
1217*d83cc019SAndroid Build Coastguard Worker igt_skip_on_simulation();
1218*d83cc019SAndroid Build Coastguard Worker
1219*d83cc019SAndroid Build Coastguard Worker igt_fixture {
1220*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
1221*d83cc019SAndroid Build Coastguard Worker igt_require_gem(fd);
1222*d83cc019SAndroid Build Coastguard Worker gem_submission_print_method(fd);
1223*d83cc019SAndroid Build Coastguard Worker gem_scheduler_print_capability(fd);
1224*d83cc019SAndroid Build Coastguard Worker
1225*d83cc019SAndroid Build Coastguard Worker igt_fork_hang_detector(fd);
1226*d83cc019SAndroid Build Coastguard Worker }
1227*d83cc019SAndroid Build Coastguard Worker
1228*d83cc019SAndroid Build Coastguard Worker for (e = intel_execution_engines; e->name; e++) {
1229*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%s", e->name)
1230*d83cc019SAndroid Build Coastguard Worker sync_ring(fd, e->exec_id | e->flags, 1, 150);
1231*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("idle-%s", e->name)
1232*d83cc019SAndroid Build Coastguard Worker idle_ring(fd, e->exec_id | e->flags, 150);
1233*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("active-%s", e->name)
1234*d83cc019SAndroid Build Coastguard Worker active_ring(fd, e->exec_id | e->flags, 150);
1235*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("wakeup-%s", e->name)
1236*d83cc019SAndroid Build Coastguard Worker wakeup_ring(fd, e->exec_id | e->flags, 150, 1);
1237*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("active-wakeup-%s", e->name)
1238*d83cc019SAndroid Build Coastguard Worker active_wakeup_ring(fd, e->exec_id | e->flags, 150, 1);
1239*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("double-wakeup-%s", e->name)
1240*d83cc019SAndroid Build Coastguard Worker wakeup_ring(fd, e->exec_id | e->flags, 150, 2);
1241*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("store-%s", e->name)
1242*d83cc019SAndroid Build Coastguard Worker store_ring(fd, e->exec_id | e->flags, 1, 150);
1243*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("switch-%s", e->name)
1244*d83cc019SAndroid Build Coastguard Worker switch_ring(fd, e->exec_id | e->flags, 1, 150);
1245*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("forked-switch-%s", e->name)
1246*d83cc019SAndroid Build Coastguard Worker switch_ring(fd, e->exec_id | e->flags, ncpus, 150);
1247*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("many-%s", e->name)
1248*d83cc019SAndroid Build Coastguard Worker store_many(fd, e->exec_id | e->flags, 150);
1249*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("forked-%s", e->name)
1250*d83cc019SAndroid Build Coastguard Worker sync_ring(fd, e->exec_id | e->flags, ncpus, 150);
1251*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("forked-store-%s", e->name)
1252*d83cc019SAndroid Build Coastguard Worker store_ring(fd, e->exec_id | e->flags, ncpus, 150);
1253*d83cc019SAndroid Build Coastguard Worker }
1254*d83cc019SAndroid Build Coastguard Worker
1255*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-each")
1256*d83cc019SAndroid Build Coastguard Worker sync_ring(fd, ALL_ENGINES, 1, 5);
1257*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-store-each")
1258*d83cc019SAndroid Build Coastguard Worker store_ring(fd, ALL_ENGINES, 1, 5);
1259*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-many-each")
1260*d83cc019SAndroid Build Coastguard Worker store_many(fd, ALL_ENGINES, 5);
1261*d83cc019SAndroid Build Coastguard Worker igt_subtest("switch-each")
1262*d83cc019SAndroid Build Coastguard Worker switch_ring(fd, ALL_ENGINES, 1, 150);
1263*d83cc019SAndroid Build Coastguard Worker igt_subtest("forked-switch-each")
1264*d83cc019SAndroid Build Coastguard Worker switch_ring(fd, ALL_ENGINES, ncpus, 150);
1265*d83cc019SAndroid Build Coastguard Worker igt_subtest("forked-each")
1266*d83cc019SAndroid Build Coastguard Worker sync_ring(fd, ALL_ENGINES, ncpus, 150);
1267*d83cc019SAndroid Build Coastguard Worker igt_subtest("forked-store-each")
1268*d83cc019SAndroid Build Coastguard Worker store_ring(fd, ALL_ENGINES, ncpus, 150);
1269*d83cc019SAndroid Build Coastguard Worker igt_subtest("active-each")
1270*d83cc019SAndroid Build Coastguard Worker active_ring(fd, ALL_ENGINES, 150);
1271*d83cc019SAndroid Build Coastguard Worker igt_subtest("wakeup-each")
1272*d83cc019SAndroid Build Coastguard Worker wakeup_ring(fd, ALL_ENGINES, 150, 1);
1273*d83cc019SAndroid Build Coastguard Worker igt_subtest("active-wakeup-each")
1274*d83cc019SAndroid Build Coastguard Worker active_wakeup_ring(fd, ALL_ENGINES, 150, 1);
1275*d83cc019SAndroid Build Coastguard Worker igt_subtest("double-wakeup-each")
1276*d83cc019SAndroid Build Coastguard Worker wakeup_ring(fd, ALL_ENGINES, 150, 2);
1277*d83cc019SAndroid Build Coastguard Worker
1278*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-all")
1279*d83cc019SAndroid Build Coastguard Worker sync_all(fd, 1, 5);
1280*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-store-all")
1281*d83cc019SAndroid Build Coastguard Worker store_all(fd, 1, 5);
1282*d83cc019SAndroid Build Coastguard Worker
1283*d83cc019SAndroid Build Coastguard Worker igt_subtest("all")
1284*d83cc019SAndroid Build Coastguard Worker sync_all(fd, 1, 150);
1285*d83cc019SAndroid Build Coastguard Worker igt_subtest("store-all")
1286*d83cc019SAndroid Build Coastguard Worker store_all(fd, 1, 150);
1287*d83cc019SAndroid Build Coastguard Worker igt_subtest("forked-all")
1288*d83cc019SAndroid Build Coastguard Worker sync_all(fd, ncpus, 150);
1289*d83cc019SAndroid Build Coastguard Worker igt_subtest("forked-store-all")
1290*d83cc019SAndroid Build Coastguard Worker store_all(fd, ncpus, 150);
1291*d83cc019SAndroid Build Coastguard Worker
1292*d83cc019SAndroid Build Coastguard Worker igt_subtest_group {
1293*d83cc019SAndroid Build Coastguard Worker igt_fixture {
1294*d83cc019SAndroid Build Coastguard Worker gem_require_contexts(fd);
1295*d83cc019SAndroid Build Coastguard Worker igt_require(gem_scheduler_has_ctx_priority(fd));
1296*d83cc019SAndroid Build Coastguard Worker igt_require(gem_scheduler_has_preemption(fd));
1297*d83cc019SAndroid Build Coastguard Worker }
1298*d83cc019SAndroid Build Coastguard Worker
1299*d83cc019SAndroid Build Coastguard Worker igt_subtest("preempt-all")
1300*d83cc019SAndroid Build Coastguard Worker preempt(fd, ALL_ENGINES, 1, 20);
1301*d83cc019SAndroid Build Coastguard Worker
1302*d83cc019SAndroid Build Coastguard Worker for (e = intel_execution_engines; e->name; e++) {
1303*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("preempt-%s", e->name)
1304*d83cc019SAndroid Build Coastguard Worker preempt(fd, e->exec_id | e->flags, ncpus, 150);
1305*d83cc019SAndroid Build Coastguard Worker }
1306*d83cc019SAndroid Build Coastguard Worker }
1307*d83cc019SAndroid Build Coastguard Worker
1308*d83cc019SAndroid Build Coastguard Worker igt_fixture {
1309*d83cc019SAndroid Build Coastguard Worker igt_stop_hang_detector();
1310*d83cc019SAndroid Build Coastguard Worker close(fd);
1311*d83cc019SAndroid Build Coastguard Worker }
1312*d83cc019SAndroid Build Coastguard Worker }
1313