blob: c98a7553b7fe8641db6b42abc65e9b0b83cb56f2 [file] [log] [blame]
Chris Wilson16bafdf2014-09-04 09:26:24 +01001/*
2 * Copyright © 2014 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
Chris Wilson310eaeb2017-06-05 11:55:57 +010024#include <limits.h>
Chris Wilson16bafdf2014-09-04 09:26:24 +010025#include <string.h>
Arkadiusz Hileracfed732017-06-07 12:14:04 +020026#include <strings.h>
Daniel Vetter3cd45de2015-02-10 17:46:43 +010027#include <signal.h>
Chris Wilson16bafdf2014-09-04 09:26:24 +010028#include <errno.h>
Daniel Vetter3cd45de2015-02-10 17:46:43 +010029#include <sys/types.h>
30#include <sys/stat.h>
Chris Wilsonc83299d2015-06-15 14:51:54 +010031#include <sys/ioctl.h>
Daniel Vetter3cd45de2015-02-10 17:46:43 +010032#include <fcntl.h>
Chris Wilson16bafdf2014-09-04 09:26:24 +010033
Daniel Vetter3cd45de2015-02-10 17:46:43 +010034#include "drmtest.h"
Chris Wilsona2eb6372015-12-11 21:24:21 +000035#include "igt_aux.h"
Chris Wilson16bafdf2014-09-04 09:26:24 +010036#include "igt_core.h"
37#include "igt_gt.h"
Chris Wilsone4424812016-10-13 11:04:40 +010038#include "igt_sysfs.h"
Chris Wilson16bafdf2014-09-04 09:26:24 +010039#include "igt_debugfs.h"
40#include "ioctl_wrappers.h"
41#include "intel_reg.h"
Daniel Vetterc66b2422015-02-06 10:49:20 +010042#include "intel_chipset.h"
Antonio Argenziano140a67c2018-07-10 16:45:26 -070043#include "igt_dummyload.h"
Chris Wilson16bafdf2014-09-04 09:26:24 +010044
Daniel Vetter3cd45de2015-02-10 17:46:43 +010045/**
46 * SECTION:igt_gt
47 * @short_description: GT support library
Damien Lespiau6ebd8c22015-06-26 14:28:41 +010048 * @title: GT
Thomas Woodf0381d12015-09-07 09:26:01 +010049 * @include: igt.h
Daniel Vetter3cd45de2015-02-10 17:46:43 +010050 *
51 * This library provides various auxiliary helper functions to handle general
52 * interactions with the GT like forcewake handling, injecting hangs or stopping
53 * engines.
54 */
55
Chris Wilsonc83299d2015-06-15 14:51:54 +010056static bool has_gpu_reset(int fd)
57{
Chris Wilsona2eb6372015-12-11 21:24:21 +000058 static int once = -1;
59 if (once < 0) {
60 struct drm_i915_getparam gp;
61 int val = 0;
Chris Wilsonc83299d2015-06-15 14:51:54 +010062
Chris Wilsona2eb6372015-12-11 21:24:21 +000063 memset(&gp, 0, sizeof(gp));
64 gp.param = 35; /* HAS_GPU_RESET */
65 gp.value = &val;
Chris Wilsonc83299d2015-06-15 14:51:54 +010066
Chris Wilsona2eb6372015-12-11 21:24:21 +000067 if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
68 once = intel_gen(intel_get_drm_devid(fd)) >= 5;
69 else
70 once = val > 0;
71 }
72 return once;
Chris Wilsonc83299d2015-06-15 14:51:54 +010073}
Daniel Vetter3cd45de2015-02-10 17:46:43 +010074
Chris Wilsone4424812016-10-13 11:04:40 +010075static void eat_error_state(int dev)
Chris Wilson0a1fc452016-09-13 11:13:14 +010076{
Chris Wilsone4424812016-10-13 11:04:40 +010077 int dir;
Chris Wilson0a1fc452016-09-13 11:13:14 +010078
Chris Wilsone4424812016-10-13 11:04:40 +010079 dir = igt_sysfs_open(dev, NULL);
80 if (dir < 0)
81 return;
82
83 /* Any write to the error state clears it */
84 igt_sysfs_set(dir, "error", "");
85 close(dir);
Chris Wilson0a1fc452016-09-13 11:13:14 +010086}
87
Daniel Vetter3cd45de2015-02-10 17:46:43 +010088/**
89 * igt_require_hang_ring:
90 * @fd: open i915 drm file descriptor
91 * @ring: execbuf ring flag
92 *
93 * Convenience helper to check whether advanced hang injection is supported by
94 * the kernel. Uses igt_skip to automatically skip the test/subtest if this
95 * isn't the case.
Chris Wilsona2eb6372015-12-11 21:24:21 +000096 *
97 * Note that we can't simply just call this from igt_hang_ring since some
98 * tests want to exercise gpu wedging behavior. For which we intentionally
99 * disable gpu reset support, but still want to inject a hang, see for example
100 * tests/gem_eio.c Instead, we expect that the first invocation of
101 * igt_require_hand_ring be from a vanilla context and use the has_gpu_reset()
102 * determined then for all later instances. This allows us the convenience
103 * of double checking when injecting hangs, whilst pushing the complexity
104 * to the tests that are deliberating trying to break the box.
105 *
106 * This function is also controlled by the environment variables:
107 *
108 * IGT_HANG (boolean) - if false, skip all tests that try to inject a hang.
109 * Default: true
110 *
111 * IGT_HANG_WITHOUT_RESET (boolean) - if true, allow the hang even if the
112 * kernel does not support GPU recovery. The machine will be wedged afterwards
113 * (and so require a reboot between testing), but it does allow limited testing
114 * to be done under hang injection.
115 * Default: false
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100116 */
Daniel Vetterc66b2422015-02-06 10:49:20 +0100117void igt_require_hang_ring(int fd, int ring)
Chris Wilson16bafdf2014-09-04 09:26:24 +0100118{
Chris Wilsona2eb6372015-12-11 21:24:21 +0000119 if (!igt_check_boolean_env_var("IGT_HANG", true))
120 igt_skip("hang injection disabled by user");
121
122 gem_require_ring(fd, ring);
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200123 gem_context_require_bannable(fd);
Chris Wilsona2eb6372015-12-11 21:24:21 +0000124 if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
125 igt_require(has_gpu_reset(fd));
Chris Wilson16bafdf2014-09-04 09:26:24 +0100126}
127
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200128static unsigned context_get_ban(int fd, unsigned ctx)
129{
Chris Wilson4ead0252018-03-07 09:39:06 +0000130 struct drm_i915_gem_context_param param = {
131 .ctx_id = ctx,
132 .param = I915_CONTEXT_PARAM_BANNABLE,
133 };
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200134
135 if (__gem_context_get_param(fd, &param) == -EINVAL) {
136 igt_assert(param.value == 0);
Eric Anholtaa97faa2017-11-10 12:49:14 -0800137 param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200138 gem_context_get_param(fd, &param);
139 }
140
141 return param.value;
142}
143
144static void context_set_ban(int fd, unsigned ctx, unsigned ban)
145{
Chris Wilson4ead0252018-03-07 09:39:06 +0000146 struct drm_i915_gem_context_param param = {
147 .ctx_id = ctx,
148 .param = I915_CONTEXT_PARAM_BANNABLE,
149 .value = ban,
150 };
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200151
152 if(__gem_context_set_param(fd, &param) == -EINVAL) {
153 igt_assert(param.value == ban);
Eric Anholtaa97faa2017-11-10 12:49:14 -0800154 param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200155 gem_context_set_param(fd, &param);
156 }
157}
158
Chris Wilson0a1fc452016-09-13 11:13:14 +0100159igt_hang_t igt_allow_hang(int fd, unsigned ctx, unsigned flags)
160{
Chris Wilson4ead0252018-03-07 09:39:06 +0000161 struct drm_i915_gem_context_param param = {
162 .ctx_id = ctx,
163 };
Chris Wilson0a1fc452016-09-13 11:13:14 +0100164 unsigned ban;
165
Chris Wilsone8905e72018-07-10 12:28:47 +0100166 /*
167 * If the driver is already wedged, we don't expect it to be able
168 * to recover from reset and for it to remain wedged. It's hard to
169 * say even if we do hang/reset making the test suspect.
170 */
171 igt_require_gem(fd);
172
Chris Wilson0a1fc452016-09-13 11:13:14 +0100173 if (!igt_check_boolean_env_var("IGT_HANG", true))
174 igt_skip("hang injection disabled by user");
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200175 gem_context_require_bannable(fd);
Chris Wilson0a1fc452016-09-13 11:13:14 +0100176 if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
177 igt_require(has_gpu_reset(fd));
178
Chris Wilsone0e24a62018-11-28 22:28:11 +0000179 igt_require(igt_sysfs_set_parameter
180 (fd, "reset", "%d", INT_MAX /* any reset method */));
Katarzyna Dec3f773802019-01-23 14:25:26 +0100181
Chris Wilson0a1fc452016-09-13 11:13:14 +0100182 if ((flags & HANG_ALLOW_CAPTURE) == 0) {
Eric Anholtaa97faa2017-11-10 12:49:14 -0800183 param.param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE;
Chris Wilson0a1fc452016-09-13 11:13:14 +0100184 param.value = 1;
185 /* Older kernels may not have NO_ERROR_CAPTURE, in which case
186 * we just eat the error state in post-hang (and hope we eat
187 * the right one).
188 */
189 __gem_context_set_param(fd, &param);
190 }
191
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200192 ban = context_get_ban(fd, ctx);
193 if ((flags & HANG_ALLOW_BAN) == 0)
194 context_set_ban(fd, ctx, 0);
Chris Wilson0a1fc452016-09-13 11:13:14 +0100195
196 return (struct igt_hang){ 0, ctx, ban, flags };
197}
198
199void igt_disallow_hang(int fd, igt_hang_t arg)
200{
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200201 context_set_ban(fd, arg.ctx, arg.ban);
Chris Wilson0a1fc452016-09-13 11:13:14 +0100202
203 if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
Eric Anholtaa97faa2017-11-10 12:49:14 -0800204 struct drm_i915_gem_context_param param = {
205 .ctx_id = arg.ctx,
206 .param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE,
Chris Wilsone2598d42017-10-20 15:16:39 +0100207 .value = 0,
208 };
209 __gem_context_set_param(fd, &param);
210
211 eat_error_state(fd);
Chris Wilson0a1fc452016-09-13 11:13:14 +0100212 }
213}
214
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100215/**
Vinay Belgaumkar7bf3bd72017-10-13 10:22:20 -0700216 * has_ctx_exec:
217 * @fd: open i915 drm file descriptor
218 * @ring: execbuf ring flag
219 * @ctx: Context to be checked
220 *
221 * This helper function checks if non default context submission is allowed
222 * on a ring.
223 *
224 * Returns:
225 * True if allowed
226 *
227 */
228static bool has_ctx_exec(int fd, unsigned ring, uint32_t ctx)
229{
230 struct drm_i915_gem_execbuffer2 execbuf;
231 struct drm_i915_gem_exec_object2 exec;
232
233 /* silly ABI, the kernel thinks everyone who has BSD also has BSD2 */
234 if ((ring & ~(3<<13)) == I915_EXEC_BSD) {
235 if (ring & (3 << 13) && !gem_has_bsd2(fd))
236 return false;
237 }
238
239 memset(&exec, 0, sizeof(exec));
240 memset(&execbuf, 0, sizeof(execbuf));
241 execbuf.buffers_ptr = to_user_pointer(&exec);
242 execbuf.buffer_count = 1;
243 execbuf.flags = ring;
244 execbuf.rsvd1 = ctx;
245 /*
246 * If context submission is not allowed, this will return EINVAL
247 * Otherwise, this will return ENOENT on account of no gem obj
248 * being submitted
249 */
250 return __gem_execbuf(fd, &execbuf) == -ENOENT;
251}
252
253/**
Chris Wilson19642c62015-12-11 13:27:49 +0000254 * igt_hang_ring_ctx:
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100255 * @fd: open i915 drm file descriptor
Chris Wilson19642c62015-12-11 13:27:49 +0000256 * @ctx: the contxt specifier
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100257 * @ring: execbuf ring flag
Chris Wilson19642c62015-12-11 13:27:49 +0000258 * @flags: set of flags to control execution
Vinay Belgaumkar7bf3bd72017-10-13 10:22:20 -0700259 * @offset: The resultant gtt offset of the exec obj
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100260 *
Chris Wilson19642c62015-12-11 13:27:49 +0000261 * This helper function injects a hanging batch associated with @ctx into @ring.
Chris Wilson0a1fc452016-09-13 11:13:14 +0100262 * It returns a #igt_hang_t structure which must be passed to
Chris Wilson19642c62015-12-11 13:27:49 +0000263 * igt_post_hang_ring() for hang post-processing (after the gpu hang
264 * interaction has been tested.
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100265 *
266 * Returns:
267 * Structure with helper internal state for igt_post_hang_ring().
268 */
Antonio Argenziano140a67c2018-07-10 16:45:26 -0700269igt_hang_t igt_hang_ctx(int fd, uint32_t ctx, int ring, unsigned flags)
Chris Wilson16bafdf2014-09-04 09:26:24 +0100270{
Eric Anholtaa97faa2017-11-10 12:49:14 -0800271 struct drm_i915_gem_context_param param;
Antonio Argenziano140a67c2018-07-10 16:45:26 -0700272 igt_spin_t *spin;
Chris Wilson16bafdf2014-09-04 09:26:24 +0100273 unsigned ban;
Chris Wilson16bafdf2014-09-04 09:26:24 +0100274
Chris Wilsona2eb6372015-12-11 21:24:21 +0000275 igt_require_hang_ring(fd, ring);
276
Vinay Belgaumkar7bf3bd72017-10-13 10:22:20 -0700277 /* check if non-default ctx submission is allowed */
278 igt_require(ctx == 0 || has_ctx_exec(fd, ring, ctx));
Chris Wilson19642c62015-12-11 13:27:49 +0000279
Eric Anholtaa97faa2017-11-10 12:49:14 -0800280 param.ctx_id = ctx;
Chris Wilson16bafdf2014-09-04 09:26:24 +0100281 param.size = 0;
Chris Wilson19642c62015-12-11 13:27:49 +0000282
283 if ((flags & HANG_ALLOW_CAPTURE) == 0) {
Eric Anholtaa97faa2017-11-10 12:49:14 -0800284 param.param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE;
Chris Wilson19642c62015-12-11 13:27:49 +0000285 param.value = 1;
286 /* Older kernels may not have NO_ERROR_CAPTURE, in which case
287 * we just eat the error state in post-hang (and hope we eat
288 * the right one).
289 */
290 __gem_context_set_param(fd, &param);
Chris Wilson19642c62015-12-11 13:27:49 +0000291 }
292
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200293 ban = context_get_ban(fd, ctx);
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200294 if ((flags & HANG_ALLOW_BAN) == 0)
295 context_set_ban(fd, ctx, 0);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100296
Antonio Argenziano140a67c2018-07-10 16:45:26 -0700297 spin = __igt_spin_batch_new(fd,
298 .ctx = ctx,
299 .engine = ring,
300 .flags = IGT_SPIN_NO_PREEMPTION);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100301
Antonio Argenziano140a67c2018-07-10 16:45:26 -0700302 return (igt_hang_t){ spin, ctx, ban, flags };
Chris Wilson19642c62015-12-11 13:27:49 +0000303}
304
305/**
306 * igt_hang_ring:
307 * @fd: open i915 drm file descriptor
308 * @ring: execbuf ring flag
309 *
310 * This helper function injects a hanging batch into @ring. It returns a
Chris Wilson0a1fc452016-09-13 11:13:14 +0100311 * #igt_hang_t structure which must be passed to igt_post_hang_ring() for
Chris Wilson19642c62015-12-11 13:27:49 +0000312 * hang post-processing (after the gpu hang interaction has been tested.
313 *
314 * Returns:
315 * Structure with helper internal state for igt_post_hang_ring().
316 */
Chris Wilson0a1fc452016-09-13 11:13:14 +0100317igt_hang_t igt_hang_ring(int fd, int ring)
Chris Wilson19642c62015-12-11 13:27:49 +0000318{
Antonio Argenziano140a67c2018-07-10 16:45:26 -0700319 return igt_hang_ctx(fd, 0, ring, 0);
Chris Wilson19642c62015-12-11 13:27:49 +0000320}
321
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100322/**
Thomas Wood26f40812015-02-20 11:31:01 +0000323 * igt_post_hang_ring:
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100324 * @fd: open i915 drm file descriptor
325 * @arg: hang state from igt_hang_ring()
326 *
327 * This function does the necessary post-processing after a gpu hang injected
328 * with igt_hang_ring().
329 */
Chris Wilson0a1fc452016-09-13 11:13:14 +0100330void igt_post_hang_ring(int fd, igt_hang_t arg)
Chris Wilson16bafdf2014-09-04 09:26:24 +0100331{
Antonio Argenziano140a67c2018-07-10 16:45:26 -0700332 if (!arg.spin)
Chris Wilson16bafdf2014-09-04 09:26:24 +0100333 return;
334
Antonio Argenziano140a67c2018-07-10 16:45:26 -0700335 gem_sync(fd, arg.spin->handle); /* Wait until it hangs */
336 igt_spin_batch_free(fd, arg.spin);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100337
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200338 context_set_ban(fd, arg.ctx, arg.ban);
Chris Wilson19642c62015-12-11 13:27:49 +0000339
340 if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
Eric Anholtaa97faa2017-11-10 12:49:14 -0800341 struct drm_i915_gem_context_param param = {
342 .ctx_id = arg.ctx,
343 .param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE,
Chris Wilsone2598d42017-10-20 15:16:39 +0100344 .value = 0,
345 };
346 __gem_context_set_param(fd, &param);
347
348 eat_error_state(fd);
Chris Wilson19642c62015-12-11 13:27:49 +0000349 }
Chris Wilson16bafdf2014-09-04 09:26:24 +0100350}
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100351
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000352/**
353 * igt_force_gpu_reset:
354 *
355 * forces a gpu reset using the i915_wedged debugfs interface. To be used to
356 * recover from situations where the hangcheck didn't trigger and/or the gpu is
357 * stuck, either because the test manually disabled gpu resets or because the
358 * test hit an hangcheck bug
359 */
Chris Wilson83884e92017-03-21 17:16:03 +0000360void igt_force_gpu_reset(int drm_fd)
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000361{
Chris Wilson58de7852017-03-24 18:11:08 +0000362 int dir, wedged;
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000363
364 igt_debug("Triggering GPU reset\n");
365
Chris Wilson58de7852017-03-24 18:11:08 +0000366 dir = igt_debugfs_dir(drm_fd);
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000367
Chris Wilson58de7852017-03-24 18:11:08 +0000368 igt_sysfs_set(dir, "i915_wedged", "-1");
369 igt_sysfs_scanf(dir, "i915_wedged", "%d", &wedged);
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000370
Chris Wilson58de7852017-03-24 18:11:08 +0000371 close(dir);
Chris Wilson9ba37172018-02-06 22:55:33 +0000372 errno = 0;
Chris Wilson28a2f142017-03-08 12:22:13 +0000373
374 igt_assert(!wedged);
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000375}
376
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100377/* GPU abusers */
378static struct igt_helper_process hang_helper;
379static void __attribute__((noreturn))
380hang_helper_process(pid_t pid, int fd)
381{
382 while (1) {
383 if (kill(pid, 0)) /* Parent has died, so must we. */
384 exit(0);
385
386 igt_post_hang_ring(fd,
387 igt_hang_ring(fd, I915_EXEC_DEFAULT));
388
389 sleep(1);
390 }
391}
392
393/**
394 * igt_fork_hang_helper:
395 *
396 * Fork a child process using #igt_fork_helper to hang the default engine
397 * of the GPU at regular intervals.
398 *
399 * This is useful to exercise slow running code (such as aperture placement)
400 * which needs to be robust against a GPU reset.
401 *
Daniel Vetterd8d1eab2015-12-03 07:45:34 +0100402 * This function automatically skips when test requirements aren't met using
403 * igt_skip().
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100404 */
Daniel Vetterd8d1eab2015-12-03 07:45:34 +0100405void igt_fork_hang_helper(void)
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100406{
407 int fd, gen;
408
Micah Fedkec81d2932015-07-22 21:54:02 +0000409 fd = drm_open_driver(DRIVER_INTEL);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100410
411 gen = intel_gen(intel_get_drm_devid(fd));
Daniel Vetterd8d1eab2015-12-03 07:45:34 +0100412 igt_skip_on(gen < 5);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100413
414 igt_fork_helper(&hang_helper)
415 hang_helper_process(getppid(), fd);
416
417 close(fd);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100418}
419
420/**
421 * igt_stop_hang_helper:
422 *
423 * Stops the child process spawned with igt_fork_hang_helper().
424 *
425 * In tests with subtests this function can be called outside of failure
426 * catching code blocks like #igt_fixture or #igt_subtest.
427 */
428void igt_stop_hang_helper(void)
429{
Daniel Vetterd8d1eab2015-12-03 07:45:34 +0100430 if (hang_helper.running)
431 igt_stop_helper(&hang_helper);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100432}
433
434/**
435 * igt_open_forcewake_handle:
436 *
437 * This functions opens the debugfs forcewake file and so prevents the GT from
438 * suspending. The reference is automatically dropped when the is closed.
439 *
440 * Returns:
441 * The file descriptor of the forcewake handle or -1 if that didn't work out.
442 */
Chris Wilson83884e92017-03-21 17:16:03 +0000443int igt_open_forcewake_handle(int fd)
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100444{
445 if (getenv("IGT_NO_FORCEWAKE"))
446 return -1;
Chris Wilson83884e92017-03-21 17:16:03 +0000447 return igt_debugfs_open(fd, "i915_forcewake_user", O_WRONLY);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100448}
Chris Wilsona6090c72016-01-08 16:32:29 +0000449
Chris Wilson7d089132016-05-01 16:39:14 +0100450#if defined(__x86_64__) || defined(__i386__)
Robert Foss8875bb12016-06-27 06:58:24 -0400451static unsigned int clflush_size;
452
Chris Wilsona6090c72016-01-08 16:32:29 +0000453int igt_setup_clflush(void)
454{
455 FILE *file;
456 char *line = NULL;
457 size_t size = 0;
458 int first_stanza = 1;
459 int has_clflush = 0;
460
461 if (clflush_size)
462 return 1;
463
464 file = fopen("/proc/cpuinfo", "r");
465 if (file == NULL)
466 return 0;
467
468 while (getline(&line, &size, file) != -1) {
469 if (strncmp(line, "processor", 9) == 0) {
470 if (!first_stanza)
471 break;
472 first_stanza = 0;
473 }
474
475 if (strncmp(line, "flags", 5) == 0) {
476 if (strstr(line, "clflush"))
477 has_clflush = 1;
478 }
479
480 if (strncmp(line, "clflush size", 12) == 0) {
481 char *colon = strchr(line, ':');
482 if (colon)
483 clflush_size = atoi(colon + 1);
484 }
485 }
486 free(line);
487 fclose(file);
488
489 return has_clflush && clflush_size;
490}
491
Chris Wilson7d089132016-05-01 16:39:14 +0100492__attribute__((target("sse2")))
Chris Wilsona6090c72016-01-08 16:32:29 +0000493void igt_clflush_range(void *addr, int size)
494{
495 char *p, *end;
496
497 end = (char *)addr + size;
498 p = (char *)((uintptr_t)addr & ~((uintptr_t)clflush_size - 1));
499
Chris Wilson7499b912016-03-03 11:51:18 +0000500 __builtin_ia32_mfence();
Chris Wilsona6090c72016-01-08 16:32:29 +0000501 for (; p < end; p += clflush_size)
Chris Wilson7499b912016-03-03 11:51:18 +0000502 __builtin_ia32_clflush(p);
Chris Wilsonb4817052016-05-01 09:07:29 +0100503 __builtin_ia32_clflush(end - 1); /* magic serialisation for byt+ */
Chris Wilson7499b912016-03-03 11:51:18 +0000504 __builtin_ia32_mfence();
Chris Wilsona6090c72016-01-08 16:32:29 +0000505}
Chris Wilson7d089132016-05-01 16:39:14 +0100506#else
507int igt_setup_clflush(void)
508{
509 /* requires mfence + clflush, both SSE2 instructions */
510 return 0;
511}
512
513void igt_clflush_range(void *addr, int size)
514{
515 fprintf(stderr, "igt_clflush_range() unsupported\n");
516}
517#endif
Chris Wilson5b675f72016-01-22 17:33:40 +0000518
519/**
520 * intel_detect_and_clear_missed_irq:
521 * @fd: open i915 drm file descriptor, used to quiesce the gpu
522 *
523 * This functions idles the GPU and then queries whether there has
524 * been a missed interrupt reported by the driver. Afterwards it
525 * clears the missed interrupt flag, in order to disable the timer
526 * fallback for the next test.
527 */
528unsigned intel_detect_and_clear_missed_interrupts(int fd)
529{
Chris Wilson58de7852017-03-24 18:11:08 +0000530 unsigned missed;
531 int dir;
Chris Wilson5b675f72016-01-22 17:33:40 +0000532
533 gem_quiescent_gpu(fd);
534
Chris Wilson58de7852017-03-24 18:11:08 +0000535 dir = igt_debugfs_dir(fd);
536
537 missed = 0;
Chris Wilsonfa612072018-08-08 11:18:28 +0100538 igt_sysfs_scanf(dir, "i915_ring_missed_irq", "%x", &missed);
Chris Wilson58de7852017-03-24 18:11:08 +0000539 if (missed)
540 igt_sysfs_set(dir, "i915_ring_missed_irq", "0");
541
542 close(dir);
Chris Wilson5b675f72016-01-22 17:33:40 +0000543
Chris Wilsonf22e19b2017-03-23 10:51:28 +0000544 errno = 0;
Chris Wilson5b675f72016-01-22 17:33:40 +0000545 return missed;
546}
Chris Wilson04f52152016-01-27 14:07:27 +0000547
548const struct intel_execution_engine intel_execution_engines[] = {
Chris Wilsonec91c562017-07-06 14:01:56 +0100549 { "default", NULL, 0, 0 },
Chris Wilson82fdfc62017-04-11 20:20:28 +0100550 { "render", "rcs0", I915_EXEC_RENDER, 0 },
551 { "bsd", "vcs0", I915_EXEC_BSD, 0 },
552 { "bsd1", "vcs0", I915_EXEC_BSD, 1<<13 /*I915_EXEC_BSD_RING1*/ },
553 { "bsd2", "vcs1", I915_EXEC_BSD, 2<<13 /*I915_EXEC_BSD_RING2*/ },
554 { "blt", "bcs0", I915_EXEC_BLT, 0 },
555 { "vebox", "vecs0", I915_EXEC_VEBOX, 0 },
Chris Wilson04f52152016-01-27 14:07:27 +0000556 { NULL, 0, 0 }
557};
Chris Wilsonbc787762017-05-18 12:11:59 +0100558
559bool gem_can_store_dword(int fd, unsigned int engine)
560{
561 uint16_t devid = intel_get_drm_devid(fd);
562 const struct intel_device_info *info = intel_get_device_info(devid);
563 const int gen = ffs(info->gen);
564
565 if (gen <= 2) /* requires physical addresses */
566 return false;
567
Chris Wilsondddbc2e2017-09-06 15:34:13 +0100568 if (gen == 3 && (info->is_grantsdale || info->is_alviso))
569 return false; /* only supports physical addresses */
570
Tvrtko Ursulin9d9978a2018-03-22 17:24:15 +0000571 if (gen == 6 && ((engine & 0x3f) == I915_EXEC_BSD))
Chris Wilsonbc787762017-05-18 12:11:59 +0100572 return false; /* kills the machine! */
573
574 if (info->is_broadwater)
575 return false; /* Not sure yet... */
576
577 return true;
578}
Tvrtko Ursulin20d89b42017-09-18 09:06:19 +0100579
580const struct intel_execution_engine2 intel_execution_engines2[] = {
581 { "rcs0", I915_ENGINE_CLASS_RENDER, 0 },
582 { "bcs0", I915_ENGINE_CLASS_COPY, 0 },
583 { "vcs0", I915_ENGINE_CLASS_VIDEO, 0 },
584 { "vcs1", I915_ENGINE_CLASS_VIDEO, 1 },
585 { "vecs0", I915_ENGINE_CLASS_VIDEO_ENHANCE, 0 },
Petri Latvala261ab6b2017-12-05 12:16:30 +0200586 { }
Tvrtko Ursulin20d89b42017-09-18 09:06:19 +0100587};
588
589unsigned int
590gem_class_instance_to_eb_flags(int gem_fd,
591 enum drm_i915_gem_engine_class class,
592 unsigned int instance)
593{
594 if (class != I915_ENGINE_CLASS_VIDEO)
595 igt_assert(instance == 0);
596 else
597 igt_assert(instance >= 0 && instance <= 1);
598
599 switch (class) {
600 case I915_ENGINE_CLASS_RENDER:
601 return I915_EXEC_RENDER;
602 case I915_ENGINE_CLASS_COPY:
603 return I915_EXEC_BLT;
604 case I915_ENGINE_CLASS_VIDEO:
605 if (instance == 0) {
606 if (gem_has_bsd2(gem_fd))
607 return I915_EXEC_BSD | I915_EXEC_BSD_RING1;
608 else
609 return I915_EXEC_BSD;
610
611 } else {
612 return I915_EXEC_BSD | I915_EXEC_BSD_RING2;
613 }
614 case I915_ENGINE_CLASS_VIDEO_ENHANCE:
615 return I915_EXEC_VEBOX;
616 case I915_ENGINE_CLASS_INVALID:
617 default:
618 igt_assert(0);
619 };
620}
621
622bool gem_has_engine(int gem_fd,
623 enum drm_i915_gem_engine_class class,
624 unsigned int instance)
625{
626 return gem_has_ring(gem_fd,
627 gem_class_instance_to_eb_flags(gem_fd, class,
628 instance));
629}
Chris Wilson305ebce2018-02-21 14:13:16 +0000630
631bool gem_ring_is_physical_engine(int fd, unsigned ring)
632{
633 if (ring == I915_EXEC_DEFAULT)
634 return false;
635
636 /* BSD uses an extra flag to chose between aliasing modes */
637 if ((ring & 63) == I915_EXEC_BSD) {
638 bool explicit_bsd = ring & (3 << 13);
639 bool has_bsd2 = gem_has_bsd2(fd);
640 return explicit_bsd ? has_bsd2 : !has_bsd2;
641 }
642
643 return true;
644}
645
646bool gem_ring_has_physical_engine(int fd, unsigned ring)
647{
648 if (!gem_ring_is_physical_engine(fd, ring))
649 return false;
650
651 return gem_has_ring(fd, ring);
652}