blob: e1be9199423711bf554f2acaa3566cc1636e8e11 [file] [log] [blame]
Chris Wilson5615ab22016-03-11 10:48:47 +00001/*
2 * Copyright © 2009 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25/** @file gem_exec_whisper.c
26 *
27 * Pass around a value to write into a scratch buffer between lots of batches
28 */
29
30#include "igt.h"
31#include "igt_gt.h"
Chris Wilsonc6e26e42016-07-22 12:58:54 +010032#include "igt_sysfs.h"
Chris Wilson5615ab22016-03-11 10:48:47 +000033
34#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
35#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
36
37#define LOCAL_I915_EXEC_BSD_SHIFT (13)
38#define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
39
40#define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
41
Chris Wilson8f6ed9e2016-03-12 11:20:03 +000042#define VERIFY 0
43
Chris Wilson5615ab22016-03-11 10:48:47 +000044static void write_seqno(unsigned offset)
45{
46 uint32_t seqno = UINT32_MAX - offset;
47 FILE *file;
48
49 file = igt_debugfs_fopen("i915_next_seqno", "w");
50 igt_assert(file);
51
52 igt_assert(fprintf(file, "0x%x", seqno) > 0);
53 fclose(file);
54
55 igt_debug("next seqno set to: 0x%x\n", seqno);
56}
57
58static void check_bo(int fd, uint32_t handle)
59{
60 uint32_t *map;
61 int i;
62
63 igt_debug("Verifying result\n");
64 map = gem_mmap__cpu(fd, handle, 0, 4096, PROT_READ);
65 gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
66 for (i = 0; i < 1024; i++)
67 igt_assert_eq(map[i], i);
68 munmap(map, 4096);
69}
70
Chris Wilson8f6ed9e2016-03-12 11:20:03 +000071static void verify_reloc(int fd, uint32_t handle,
72 const struct drm_i915_gem_relocation_entry *reloc)
73{
74 if (VERIFY) {
75 uint64_t target = 0;
76 if (intel_gen(intel_get_drm_devid(fd)) >= 8)
77 gem_read(fd, handle, reloc->offset, &target, 8);
78 else
79 gem_read(fd, handle, reloc->offset, &target, 4);
80 igt_assert_eq_u64(target,
81 reloc->presumed_offset + reloc->delta);
82 }
83}
84
Chris Wilson5615ab22016-03-11 10:48:47 +000085static int __gem_context_create(int fd, uint32_t *ctx_id)
86{
87 struct drm_i915_gem_context_create arg;
88 int ret = 0;
89
90 memset(&arg, 0, sizeof(arg));
91 if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &arg))
92 ret = -errno;
93
94 *ctx_id = arg.ctx_id;
95 return ret;
96}
97
Chris Wilson3b22b892016-03-21 11:00:52 +000098static bool can_mi_store_dword(int gen, unsigned engine)
99{
100 return !(gen == 6 && (engine & ~(3<<13)) == I915_EXEC_BSD);
101}
102
Chris Wilson5615ab22016-03-11 10:48:47 +0000103static bool ignore_engine(int gen, unsigned engine)
104{
Chris Wilson5df2de72016-03-15 09:52:57 +0000105 if (engine == 0)
106 return true;
107
Chris Wilson3b22b892016-03-21 11:00:52 +0000108 if (!can_mi_store_dword(gen, engine))
Chris Wilson5df2de72016-03-15 09:52:57 +0000109 return true;
110
111 return false;
Chris Wilson5615ab22016-03-11 10:48:47 +0000112}
113
114#define CONTEXTS 0x1
Chris Wilson9eacbd22016-03-11 14:31:56 +0000115#define FDS 0x2
Chris Wilson83cfed82016-03-19 14:21:34 +0000116#define INTERRUPTIBLE 0x4
Chris Wilson7b34c512016-06-04 16:12:28 +0100117#define CHAIN 0x8
Chris Wilson587753b2016-09-12 16:06:48 +0100118#define FORKED 0x10
Chris Wilson1a76d882016-10-01 16:50:51 +0100119#define HANG 0x20
120
121struct hang {
122 struct drm_i915_gem_exec_object2 obj;
123 struct drm_i915_gem_relocation_entry reloc;
124 struct drm_i915_gem_execbuffer2 execbuf;
125 int fd;
126};
127
128static void init_hang(struct hang *h)
129{
130 uint32_t *batch;
131 int i, gen;
132
133 h->fd = drm_open_driver(DRIVER_INTEL);
134 igt_allow_hang(h->fd, 0, 0);
135
136 gen = intel_gen(intel_get_drm_devid(h->fd));
137
138 memset(&h->execbuf, 0, sizeof(h->execbuf));
139 h->execbuf.buffers_ptr = (uintptr_t)&h->obj;
140 h->execbuf.buffer_count = 1;
141
142 memset(&h->obj, 0, sizeof(h->obj));
143 h->obj.handle = gem_create(h->fd, 4096);
144
145 h->obj.relocs_ptr = (uintptr_t)&h->reloc;
146 h->obj.relocation_count = 1;
147 memset(&h->reloc, 0, sizeof(h->reloc));
148
149 batch = gem_mmap__cpu(h->fd, h->obj.handle, 0, 4096, PROT_WRITE);
150 gem_set_domain(h->fd, h->obj.handle,
151 I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
152
153 h->reloc.target_handle = h->obj.handle; /* recurse */
154 h->reloc.presumed_offset = 0;
155 h->reloc.offset = 5*sizeof(uint32_t);
156 h->reloc.delta = 0;
157 h->reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
158 h->reloc.write_domain = 0;
159
160 i = 0;
161 batch[i++] = 0xffffffff;
162 batch[i++] = 0xdeadbeef;
163 batch[i++] = 0xc00fee00;
164 batch[i++] = 0x00c00fee;
165 batch[i] = MI_BATCH_BUFFER_START;
166 if (gen >= 8) {
167 batch[i] |= 1 << 8 | 1;
168 batch[++i] = 0;
169 batch[++i] = 0;
170 } else if (gen >= 6) {
171 batch[i] |= 1 << 8;
172 batch[++i] = 0;
173 } else {
174 batch[i] |= 2 << 6;
175 batch[++i] = 0;
176 if (gen < 4) {
177 batch[i] |= 1;
178 h->reloc.delta = 1;
179 }
180 }
181 munmap(batch, 4096);
182}
183
184static void submit_hang(struct hang *h, unsigned *engines, int nengine)
185{
186 while (nengine--) {
187 h->execbuf.flags &= ~ENGINE_MASK;
188 h->execbuf.flags |= *engines++;
189 gem_execbuf(h->fd, &h->execbuf);
190 }
191}
192
193static void fini_hang(struct hang *h)
194{
195 close(h->fd);
196}
Chris Wilson5615ab22016-03-11 10:48:47 +0000197
Chris Wilson2fdf5ac2016-03-14 13:41:15 +0000198static void whisper(int fd, unsigned engine, unsigned flags)
Chris Wilson5615ab22016-03-11 10:48:47 +0000199{
Chris Wilson3e765842016-07-02 11:51:29 +0100200 const uint32_t bbe = MI_BATCH_BUFFER_END;
Chris Wilson5615ab22016-03-11 10:48:47 +0000201 const int gen = intel_gen(intel_get_drm_devid(fd));
202 struct drm_i915_gem_exec_object2 batches[1024];
203 struct drm_i915_gem_relocation_entry inter[1024];
204 struct drm_i915_gem_relocation_entry reloc;
Chris Wilson8f6ed9e2016-03-12 11:20:03 +0000205 struct drm_i915_gem_exec_object2 store, scratch;
206 struct drm_i915_gem_exec_object2 tmp[2];
207 struct drm_i915_gem_execbuffer2 execbuf;
Chris Wilson1a76d882016-10-01 16:50:51 +0100208 struct hang hang;
Chris Wilson9eacbd22016-03-11 14:31:56 +0000209 int fds[64];
Chris Wilson5615ab22016-03-11 10:48:47 +0000210 uint32_t contexts[64];
Chris Wilson5615ab22016-03-11 10:48:47 +0000211 unsigned engines[16];
212 unsigned nengine;
Chris Wilson5615ab22016-03-11 10:48:47 +0000213 uint32_t batch[16];
214 int i, n, pass, loc;
Chris Wilson5dcb0262016-03-26 09:48:16 +0000215 unsigned int relocations = 0;
Chris Wilson488dc3b2016-03-15 09:16:30 +0000216 unsigned int reloc_migrations = 0;
Chris Wilsond5e550f2016-03-21 11:58:21 +0000217 unsigned int reloc_interruptions = 0;
Chris Wilson488dc3b2016-03-15 09:16:30 +0000218 unsigned int eb_migrations = 0;
Chris Wilson5dcb0262016-03-26 09:48:16 +0000219 uint64_t old_offset;
Chris Wilson5615ab22016-03-11 10:48:47 +0000220
221 nengine = 0;
Chris Wilson2fdf5ac2016-03-14 13:41:15 +0000222 if (engine == -1) {
223 for_each_engine(fd, engine) {
224 if (!ignore_engine(gen, engine))
225 engines[nengine++] = engine;
226 }
227 } else {
228 igt_require(gem_has_ring(fd, engine));
Chris Wilsond5e550f2016-03-21 11:58:21 +0000229 igt_require(can_mi_store_dword(gen, engine));
Chris Wilson2fdf5ac2016-03-14 13:41:15 +0000230 engines[nengine++] = engine;
231 }
Chris Wilson5615ab22016-03-11 10:48:47 +0000232 igt_require(nengine);
233
Chris Wilson1a76d882016-10-01 16:50:51 +0100234 if (flags & HANG)
235 init_hang(&hang);
236
Chris Wilson587753b2016-09-12 16:06:48 +0100237 intel_detect_and_clear_missed_interrupts(fd);
238 igt_fork(child, flags & FORKED ? sysconf(_SC_NPROCESSORS_ONLN) : 1) {
239 memset(&scratch, 0, sizeof(scratch));
240 scratch.handle = gem_create(fd, 4096);
241 scratch.flags = EXEC_OBJECT_WRITE;
Chris Wilson8f6ed9e2016-03-12 11:20:03 +0000242
Chris Wilson587753b2016-09-12 16:06:48 +0100243 memset(&store, 0, sizeof(store));
244 store.handle = gem_create(fd, 4096);
245 store.relocs_ptr = (uintptr_t)&reloc;
246 store.relocation_count = 1;
Chris Wilson5615ab22016-03-11 10:48:47 +0000247
Chris Wilson587753b2016-09-12 16:06:48 +0100248 memset(&reloc, 0, sizeof(reloc));
249 reloc.offset = sizeof(uint32_t);
250 if (gen < 8 && gen >= 4)
251 reloc.offset += sizeof(uint32_t);
252 loc = 8;
253 if (gen >= 4)
254 loc += 4;
255 reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
256 reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
Chris Wilson5615ab22016-03-11 10:48:47 +0000257
Chris Wilson587753b2016-09-12 16:06:48 +0100258 {
259 tmp[0] = scratch;
260 tmp[1] = store;
261 gem_write(fd, store.handle, 0, &bbe, sizeof(bbe));
Chris Wilson8f6ed9e2016-03-12 11:20:03 +0000262
Chris Wilson587753b2016-09-12 16:06:48 +0100263 memset(&execbuf, 0, sizeof(execbuf));
264 execbuf.buffers_ptr = (uintptr_t)tmp;
265 execbuf.buffer_count = 2;
266 execbuf.flags = LOCAL_I915_EXEC_HANDLE_LUT;
267 execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
268 if (gen < 6)
269 execbuf.flags |= I915_EXEC_SECURE;
270 igt_require(__gem_execbuf(fd, &execbuf) == 0);
271 scratch = tmp[0];
272 store = tmp[1];
Chris Wilson3e765842016-07-02 11:51:29 +0100273 }
274
Chris Wilson587753b2016-09-12 16:06:48 +0100275 i = 0;
276 batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
277 if (gen >= 8) {
278 batch[++i] = store.offset + loc;
279 batch[++i] = (store.offset + loc) >> 32;
280 } else if (gen >= 4) {
281 batch[++i] = 0;
282 batch[++i] = store.offset + loc;
283 } else {
284 batch[i]--;
285 batch[++i] = store.offset + loc;
286 }
287 batch[++i] = 0xc0ffee;
288 igt_assert(loc == sizeof(uint32_t) * i);
289 batch[++i] = MI_BATCH_BUFFER_END;
Chris Wilson3e765842016-07-02 11:51:29 +0100290
Chris Wilson587753b2016-09-12 16:06:48 +0100291 if (flags & CONTEXTS) {
292 igt_require(__gem_context_create(fd, &contexts[0]) == 0);
293 for (n = 1; n < 64; n++)
294 contexts[n] = gem_context_create(fd);
295 }
296 if (flags & FDS) {
297 igt_require(gen >= 6);
298 for (n = 0; n < 64; n++)
299 fds[n] = drm_open_driver(DRIVER_INTEL);
300 }
Chris Wilson5615ab22016-03-11 10:48:47 +0000301
Chris Wilson587753b2016-09-12 16:06:48 +0100302 memset(batches, 0, sizeof(batches));
303 for (n = 0; n < 1024; n++) {
304 batches[n].handle = gem_create(fd, 4096);
305 gem_write(fd, batches[n].handle, 0, &bbe, sizeof(bbe));
306 }
307 execbuf.buffers_ptr = (uintptr_t)batches;
308 execbuf.buffer_count = 1024;
309 gem_execbuf(fd, &execbuf);
Chris Wilson5615ab22016-03-11 10:48:47 +0000310
Chris Wilson587753b2016-09-12 16:06:48 +0100311 execbuf.buffers_ptr = (uintptr_t)tmp;
312 execbuf.buffer_count = 2;
Chris Wilson5615ab22016-03-11 10:48:47 +0000313
Chris Wilson587753b2016-09-12 16:06:48 +0100314 old_offset = store.offset;
315 for (n = 0; n < 1024; n++) {
Chris Wilson83cfed82016-03-19 14:21:34 +0000316 if (gen >= 8) {
Chris Wilson587753b2016-09-12 16:06:48 +0100317 batch[1] = old_offset + loc;
318 batch[2] = (old_offset + loc) >> 32;
Chris Wilson83cfed82016-03-19 14:21:34 +0000319 } else if (gen >= 4) {
Chris Wilson587753b2016-09-12 16:06:48 +0100320 batch[2] = old_offset + loc;
Chris Wilson83cfed82016-03-19 14:21:34 +0000321 } else {
Chris Wilson587753b2016-09-12 16:06:48 +0100322 batch[1] = old_offset + loc;
Chris Wilson9eacbd22016-03-11 14:31:56 +0000323 }
324
Chris Wilson587753b2016-09-12 16:06:48 +0100325 inter[n] = reloc;
326 inter[n].presumed_offset = old_offset;
327 inter[n].delta = loc;
328 batches[n].relocs_ptr = (uintptr_t)&inter[n];
329 batches[n].relocation_count = 1;
330 gem_write(fd, batches[n].handle, 0, batch, sizeof(batch));
Chris Wilson83cfed82016-03-19 14:21:34 +0000331
Chris Wilson587753b2016-09-12 16:06:48 +0100332 old_offset = batches[n].offset;
333 }
Chris Wilson83cfed82016-03-19 14:21:34 +0000334
Chris Wilson587753b2016-09-12 16:06:48 +0100335 igt_while_interruptible(flags & INTERRUPTIBLE) {
336 for (pass = 0; pass < 1024; pass++) {
337 uint64_t offset;
Chris Wilson83cfed82016-03-19 14:21:34 +0000338
Chris Wilson587753b2016-09-12 16:06:48 +0100339 if (child == 0)
340 write_seqno(pass);
Chris Wilson83cfed82016-03-19 14:21:34 +0000341
Chris Wilson1a76d882016-10-01 16:50:51 +0100342 if (flags & HANG)
343 submit_hang(&hang, engines, nengine);
344
Chris Wilson587753b2016-09-12 16:06:48 +0100345 if (flags & CHAIN) {
Chris Wilson7b34c512016-06-04 16:12:28 +0100346 execbuf.flags &= ~ENGINE_MASK;
347 execbuf.flags |= engines[rand() % nengine];
348 }
Chris Wilson587753b2016-09-12 16:06:48 +0100349
350 reloc.presumed_offset = scratch.offset;
351 reloc.delta = 4*pass;
352 offset = reloc.presumed_offset + reloc.delta;
353
354 i = 0;
355 if (gen >= 8) {
356 batch[++i] = offset;
357 batch[++i] = offset >> 32;
358 } else if (gen >= 4) {
359 batch[++i] = 0;
360 batch[++i] = offset;
361 } else {
362 batch[++i] = offset;
363 }
364 batch[++i] = ~pass;
365 gem_write(fd, store.handle, 0, batch, sizeof(batch));
366
367 tmp[0] = scratch;
368 igt_assert(tmp[0].flags & EXEC_OBJECT_WRITE);
369 tmp[1] = store;
370 verify_reloc(fd, store.handle, &reloc);
371 execbuf.buffers_ptr = (uintptr_t)tmp;
372 gem_execbuf(fd, &execbuf);
373 igt_assert_eq_u64(reloc.presumed_offset, tmp[0].offset);
374 scratch = tmp[0];
375
376 gem_write(fd, batches[1023].handle, loc, &pass, sizeof(pass));
377 for (n = 1024; --n >= 1; ) {
378 int this_fd = fd;
379 uint32_t handle[2];
380
381 execbuf.buffers_ptr = (uintptr_t)&batches[n-1];
382 reloc_migrations += batches[n-1].offset != inter[n].presumed_offset;
383 batches[n-1].offset = inter[n].presumed_offset;
384 old_offset = inter[n].presumed_offset;
385 batches[n-1].relocation_count = 0;
386 batches[n-1].flags |= EXEC_OBJECT_WRITE;
387 verify_reloc(fd, batches[n].handle, &inter[n]);
388
389 if (flags & FDS) {
390 this_fd = fds[rand() % 64];
391 handle[0] = batches[n-1].handle;
392 handle[1] = batches[n].handle;
393 batches[n-1].handle =
394 gem_open(this_fd,
395 gem_flink(fd, handle[0]));
396 batches[n].handle =
397 gem_open(this_fd,
398 gem_flink(fd, handle[1]));
399 }
400
401 if (!(flags & CHAIN)) {
402 execbuf.flags &= ~ENGINE_MASK;
403 execbuf.flags |= engines[rand() % nengine];
404 }
405 if (flags & CONTEXTS)
406 execbuf.rsvd1 = contexts[rand() % 64];
407 gem_execbuf(this_fd, &execbuf);
408 if (inter[n].presumed_offset == -1) {
409 reloc_interruptions++;
410 inter[n].presumed_offset = batches[n-1].offset;
411 }
412 igt_assert_eq_u64(inter[n].presumed_offset, batches[n-1].offset);
413 relocations += inter[n].presumed_offset != old_offset;
414
415 batches[n-1].relocation_count = 1;
416 batches[n-1].flags &= ~EXEC_OBJECT_WRITE;
417
418 if (this_fd != fd) {
419 gem_close(this_fd, batches[n-1].handle);
420 batches[n-1].handle = handle[0];
421
422 gem_close(this_fd, batches[n].handle);
423 batches[n].handle = handle[1];
424 }
425 }
426 execbuf.flags &= ~ENGINE_MASK;
427 execbuf.rsvd1 = 0;
428 execbuf.buffers_ptr = (uintptr_t)&tmp;
429
430 tmp[0] = tmp[1];
431 tmp[0].relocation_count = 0;
432 tmp[0].flags = EXEC_OBJECT_WRITE;
433 reloc_migrations += tmp[0].offset != inter[0].presumed_offset;
434 tmp[0].offset = inter[0].presumed_offset;
435 old_offset = tmp[0].offset;
436 tmp[1] = batches[0];
437 verify_reloc(fd, batches[0].handle, &inter[0]);
438 gem_execbuf(fd, &execbuf);
439 if (inter[0].presumed_offset == -1) {
Chris Wilson5dcb0262016-03-26 09:48:16 +0000440 reloc_interruptions++;
Chris Wilson587753b2016-09-12 16:06:48 +0100441 inter[0].presumed_offset = tmp[0].offset;
Chris Wilson5dcb0262016-03-26 09:48:16 +0000442 }
Chris Wilson587753b2016-09-12 16:06:48 +0100443 igt_assert_eq_u64(inter[0].presumed_offset, tmp[0].offset);
444 relocations += inter[0].presumed_offset != old_offset;
445 batches[0] = tmp[1];
Chris Wilson83cfed82016-03-19 14:21:34 +0000446
Chris Wilson587753b2016-09-12 16:06:48 +0100447 tmp[1] = tmp[0];
448 tmp[0] = scratch;
449 igt_assert(tmp[0].flags & EXEC_OBJECT_WRITE);
450 igt_assert_eq_u64(reloc.presumed_offset, tmp[0].offset);
451 igt_assert(tmp[1].relocs_ptr == (uintptr_t)&reloc);
452 tmp[1].relocation_count = 1;
453 tmp[1].flags &= ~EXEC_OBJECT_WRITE;
454 verify_reloc(fd, store.handle, &reloc);
455 gem_execbuf(fd, &execbuf);
456 eb_migrations += tmp[0].offset != scratch.offset;
457 eb_migrations += tmp[1].offset != store.offset;
458 igt_assert_eq_u64(reloc.presumed_offset, tmp[0].offset);
459 store = tmp[1];
460 scratch = tmp[0];
Chris Wilson83cfed82016-03-19 14:21:34 +0000461 }
Chris Wilson62916782016-03-11 14:16:13 +0000462 }
Chris Wilson587753b2016-09-12 16:06:48 +0100463 igt_info("Number of migrations for execbuf: %d\n", eb_migrations);
464 igt_info("Number of migrations for reloc: %d, interrupted %d, patched %d\n", reloc_migrations, reloc_interruptions, relocations);
Chris Wilson5615ab22016-03-11 10:48:47 +0000465
Chris Wilson587753b2016-09-12 16:06:48 +0100466 check_bo(fd, scratch.handle);
467 gem_close(fd, scratch.handle);
468 gem_close(fd, store.handle);
469
470 if (flags & FDS) {
471 for (n = 0; n < 64; n++)
472 close(fds[n]);
473 }
474 if (flags & CONTEXTS) {
475 for (n = 0; n < 64; n++)
476 gem_context_destroy(fd, contexts[n]);
477 }
478 for (n = 0; n < 1024; n++)
479 gem_close(fd, batches[n].handle);
480 }
481
482 igt_waitchildren();
Chris Wilson1a76d882016-10-01 16:50:51 +0100483
484 if (flags & HANG)
485 fini_hang(&hang);
486 else
487 igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
Chris Wilson5615ab22016-03-11 10:48:47 +0000488}
489
Chris Wilsonc6e26e42016-07-22 12:58:54 +0100490static void print_welcome(int fd)
491{
492 bool active;
Chris Wilsonc6e26e42016-07-22 12:58:54 +0100493 int dir;
494
495 dir = igt_sysfs_open_parameters(fd);
496 if (dir < 0)
497 return;
498
Chris Wilsonb64d10c2016-07-22 17:53:51 +0100499 active = igt_sysfs_get_boolean(dir, "enable_guc_submission");
Chris Wilsonc6e26e42016-07-22 12:58:54 +0100500 if (active) {
501 igt_info("Using GuC submission\n");
502 goto out;
503 }
504
Chris Wilsonb64d10c2016-07-22 17:53:51 +0100505 active = igt_sysfs_get_boolean(dir, "enable_execlists");
Chris Wilsonc6e26e42016-07-22 12:58:54 +0100506 if (active) {
507 igt_info("Using Execlists submission\n");
508 goto out;
509 }
510
Chris Wilsonb64d10c2016-07-22 17:53:51 +0100511 active = igt_sysfs_get_boolean(dir, "semaphores");
Chris Wilsonf565b6c2016-09-08 20:59:55 +0100512 igt_info("Using Legacy submission%s\n",
Chris Wilsonc6e26e42016-07-22 12:58:54 +0100513 active ? ", with semaphores" : "");
514
515out:
516 close(dir);
517}
518
Chris Wilson5615ab22016-03-11 10:48:47 +0000519igt_main
520{
Chris Wilson83cfed82016-03-19 14:21:34 +0000521 const struct mode {
522 const char *name;
523 unsigned flags;
524 } modes[] = {
Chris Wilson2b4c35e2016-05-20 11:20:49 +0100525 { "normal", 0 },
Chris Wilson1a722fa2016-03-26 10:54:43 +0000526 { "interruptible", INTERRUPTIBLE },
Chris Wilson587753b2016-09-12 16:06:48 +0100527 { "forked", FORKED },
Chris Wilson7b34c512016-06-04 16:12:28 +0100528 { "chain", CHAIN },
Chris Wilson587753b2016-09-12 16:06:48 +0100529 { "chain-forked", CHAIN | FORKED },
530 { "chain-interruptible", CHAIN | INTERRUPTIBLE },
Chris Wilson83cfed82016-03-19 14:21:34 +0000531 { "contexts", CONTEXTS },
532 { "contexts-interruptible", CONTEXTS | INTERRUPTIBLE},
Chris Wilson587753b2016-09-12 16:06:48 +0100533 { "contexts-forked", CONTEXTS | FORKED},
Chris Wilson7b34c512016-06-04 16:12:28 +0100534 { "contexts-chain", CONTEXTS | CHAIN },
Chris Wilson83cfed82016-03-19 14:21:34 +0000535 { "fds", FDS },
536 { "fds-interruptible", FDS | INTERRUPTIBLE},
Chris Wilson587753b2016-09-12 16:06:48 +0100537 { "fds-forked", FDS | FORKED},
Chris Wilson7b34c512016-06-04 16:12:28 +0100538 { "fds-chain", FDS | CHAIN},
Chris Wilson83cfed82016-03-19 14:21:34 +0000539 { NULL }
540 };
Chris Wilson5615ab22016-03-11 10:48:47 +0000541 int fd;
542
Daniel Vetterbe21fc02016-06-17 16:04:09 +0200543 igt_fixture {
Chris Wilson5615ab22016-03-11 10:48:47 +0000544 fd = drm_open_driver_master(DRIVER_INTEL);
Chris Wilsonc6e26e42016-07-22 12:58:54 +0100545 print_welcome(fd);
Chris Wilson5615ab22016-03-11 10:48:47 +0000546
Daniel Vetterbe21fc02016-06-17 16:04:09 +0200547 igt_fork_hang_detector(fd);
548 }
Chris Wilson756f3e02016-03-22 11:33:41 +0000549
Chris Wilson83cfed82016-03-19 14:21:34 +0000550 for (const struct mode *m = modes; m->name; m++)
Chris Wilson2b4c35e2016-05-20 11:20:49 +0100551 igt_subtest_f("%s", m->name)
Chris Wilson83cfed82016-03-19 14:21:34 +0000552 whisper(fd, -1, m->flags);
Chris Wilson2fdf5ac2016-03-14 13:41:15 +0000553
554 for (const struct intel_execution_engine *e = intel_execution_engines;
555 e->name; e++) {
Chris Wilson7b34c512016-06-04 16:12:28 +0100556 for (const struct mode *m = modes; m->name; m++) {
557 if (m->flags & CHAIN)
558 continue;
559
Chris Wilson2b4c35e2016-05-20 11:20:49 +0100560 igt_subtest_f("%s-%s", e->name, m->name)
Chris Wilson83cfed82016-03-19 14:21:34 +0000561 whisper(fd, e->exec_id | e->flags, m->flags);
Chris Wilson7b34c512016-06-04 16:12:28 +0100562 }
Chris Wilson2fdf5ac2016-03-14 13:41:15 +0000563 }
Chris Wilson9eacbd22016-03-11 14:31:56 +0000564
Daniel Vetterbe21fc02016-06-17 16:04:09 +0200565 igt_fixture {
566 igt_stop_hang_detector();
Chris Wilson1a76d882016-10-01 16:50:51 +0100567 }
568
569 igt_subtest_group {
570 for (const struct mode *m = modes; m->name; m++) {
571 if (m->flags & INTERRUPTIBLE)
572 continue;
573 igt_subtest_f("hang-%s", m->name)
574 whisper(fd, -1, m->flags | HANG);
575 }
576 }
577
578 igt_fixture {
Chris Wilson5615ab22016-03-11 10:48:47 +0000579 close(fd);
Daniel Vetterbe21fc02016-06-17 16:04:09 +0200580 }
Chris Wilson5615ab22016-03-11 10:48:47 +0000581}