blob: 64a2dfd62da7956cc7f3eebf70ad1689d98b353a [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"
Chris Wilson16bafdf2014-09-04 09:26:24 +010043
Daniel Vetter3cd45de2015-02-10 17:46:43 +010044/**
45 * SECTION:igt_gt
46 * @short_description: GT support library
Damien Lespiau6ebd8c22015-06-26 14:28:41 +010047 * @title: GT
Thomas Woodf0381d12015-09-07 09:26:01 +010048 * @include: igt.h
Daniel Vetter3cd45de2015-02-10 17:46:43 +010049 *
50 * This library provides various auxiliary helper functions to handle general
51 * interactions with the GT like forcewake handling, injecting hangs or stopping
52 * engines.
53 */
54
Chris Wilsonc83299d2015-06-15 14:51:54 +010055static bool has_gpu_reset(int fd)
56{
Chris Wilsona2eb6372015-12-11 21:24:21 +000057 static int once = -1;
58 if (once < 0) {
59 struct drm_i915_getparam gp;
60 int val = 0;
Chris Wilsonc83299d2015-06-15 14:51:54 +010061
Chris Wilsona2eb6372015-12-11 21:24:21 +000062 memset(&gp, 0, sizeof(gp));
63 gp.param = 35; /* HAS_GPU_RESET */
64 gp.value = &val;
Chris Wilsonc83299d2015-06-15 14:51:54 +010065
Chris Wilsona2eb6372015-12-11 21:24:21 +000066 if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
67 once = intel_gen(intel_get_drm_devid(fd)) >= 5;
68 else
69 once = val > 0;
70 }
71 return once;
Chris Wilsonc83299d2015-06-15 14:51:54 +010072}
Daniel Vetter3cd45de2015-02-10 17:46:43 +010073
Chris Wilsone4424812016-10-13 11:04:40 +010074static void eat_error_state(int dev)
Chris Wilson0a1fc452016-09-13 11:13:14 +010075{
Chris Wilsone4424812016-10-13 11:04:40 +010076 int dir;
Chris Wilson0a1fc452016-09-13 11:13:14 +010077
Chris Wilsone4424812016-10-13 11:04:40 +010078 dir = igt_sysfs_open(dev, NULL);
79 if (dir < 0)
80 return;
81
82 /* Any write to the error state clears it */
83 igt_sysfs_set(dir, "error", "");
84 close(dir);
Chris Wilson0a1fc452016-09-13 11:13:14 +010085}
86
Daniel Vetter3cd45de2015-02-10 17:46:43 +010087/**
88 * igt_require_hang_ring:
89 * @fd: open i915 drm file descriptor
90 * @ring: execbuf ring flag
91 *
92 * Convenience helper to check whether advanced hang injection is supported by
93 * the kernel. Uses igt_skip to automatically skip the test/subtest if this
94 * isn't the case.
Chris Wilsona2eb6372015-12-11 21:24:21 +000095 *
96 * Note that we can't simply just call this from igt_hang_ring since some
97 * tests want to exercise gpu wedging behavior. For which we intentionally
98 * disable gpu reset support, but still want to inject a hang, see for example
99 * tests/gem_eio.c Instead, we expect that the first invocation of
100 * igt_require_hand_ring be from a vanilla context and use the has_gpu_reset()
101 * determined then for all later instances. This allows us the convenience
102 * of double checking when injecting hangs, whilst pushing the complexity
103 * to the tests that are deliberating trying to break the box.
104 *
105 * This function is also controlled by the environment variables:
106 *
107 * IGT_HANG (boolean) - if false, skip all tests that try to inject a hang.
108 * Default: true
109 *
110 * IGT_HANG_WITHOUT_RESET (boolean) - if true, allow the hang even if the
111 * kernel does not support GPU recovery. The machine will be wedged afterwards
112 * (and so require a reboot between testing), but it does allow limited testing
113 * to be done under hang injection.
114 * Default: false
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100115 */
Daniel Vetterc66b2422015-02-06 10:49:20 +0100116void igt_require_hang_ring(int fd, int ring)
Chris Wilson16bafdf2014-09-04 09:26:24 +0100117{
Chris Wilsona2eb6372015-12-11 21:24:21 +0000118 if (!igt_check_boolean_env_var("IGT_HANG", true))
119 igt_skip("hang injection disabled by user");
120
121 gem_require_ring(fd, ring);
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200122 gem_context_require_bannable(fd);
Chris Wilsona2eb6372015-12-11 21:24:21 +0000123 if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
124 igt_require(has_gpu_reset(fd));
Chris Wilson16bafdf2014-09-04 09:26:24 +0100125}
126
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200127static unsigned context_get_ban(int fd, unsigned ctx)
128{
Eric Anholtaa97faa2017-11-10 12:49:14 -0800129 struct drm_i915_gem_context_param param;
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200130
Eric Anholtaa97faa2017-11-10 12:49:14 -0800131 param.param = I915_CONTEXT_PARAM_BANNABLE;
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200132 param.value = 0;
133 param.size = 0;
134
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{
Eric Anholtaa97faa2017-11-10 12:49:14 -0800146 struct drm_i915_gem_context_param param;
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200147
Chris Wilsoncc8c9602017-02-04 19:29:57 +0000148 memset(&param, 0, sizeof(param));
Eric Anholtaa97faa2017-11-10 12:49:14 -0800149 param.ctx_id = ctx;
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200150 param.value = ban;
151 param.size = 0;
Eric Anholtaa97faa2017-11-10 12:49:14 -0800152 param.param = I915_CONTEXT_PARAM_BANNABLE;
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200153
154 if(__gem_context_set_param(fd, &param) == -EINVAL) {
155 igt_assert(param.value == ban);
Eric Anholtaa97faa2017-11-10 12:49:14 -0800156 param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200157 gem_context_set_param(fd, &param);
158 }
159}
160
Chris Wilson0a1fc452016-09-13 11:13:14 +0100161igt_hang_t igt_allow_hang(int fd, unsigned ctx, unsigned flags)
162{
Eric Anholtaa97faa2017-11-10 12:49:14 -0800163 struct drm_i915_gem_context_param param;
Chris Wilson0a1fc452016-09-13 11:13:14 +0100164 unsigned ban;
165
Chris Wilson310eaeb2017-06-05 11:55:57 +0100166 igt_assert(igt_sysfs_set_parameter
167 (fd, "reset", "%d", INT_MAX /* any reset method */));
168
Chris Wilson0a1fc452016-09-13 11:13:14 +0100169 if (!igt_check_boolean_env_var("IGT_HANG", true))
170 igt_skip("hang injection disabled by user");
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200171 gem_context_require_bannable(fd);
Chris Wilson0a1fc452016-09-13 11:13:14 +0100172 if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
173 igt_require(has_gpu_reset(fd));
174
Eric Anholtaa97faa2017-11-10 12:49:14 -0800175 param.ctx_id = ctx;
Chris Wilson0a1fc452016-09-13 11:13:14 +0100176 param.size = 0;
177
178 if ((flags & HANG_ALLOW_CAPTURE) == 0) {
Eric Anholtaa97faa2017-11-10 12:49:14 -0800179 param.param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE;
Chris Wilson0a1fc452016-09-13 11:13:14 +0100180 param.value = 1;
181 /* Older kernels may not have NO_ERROR_CAPTURE, in which case
182 * we just eat the error state in post-hang (and hope we eat
183 * the right one).
184 */
185 __gem_context_set_param(fd, &param);
186 }
187
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200188 ban = context_get_ban(fd, ctx);
189 if ((flags & HANG_ALLOW_BAN) == 0)
190 context_set_ban(fd, ctx, 0);
Chris Wilson0a1fc452016-09-13 11:13:14 +0100191
192 return (struct igt_hang){ 0, ctx, ban, flags };
193}
194
195void igt_disallow_hang(int fd, igt_hang_t arg)
196{
Chris Wilson0a1fc452016-09-13 11:13:14 +0100197
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200198 context_set_ban(fd, arg.ctx, arg.ban);
Chris Wilson0a1fc452016-09-13 11:13:14 +0100199
200 if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
Eric Anholtaa97faa2017-11-10 12:49:14 -0800201 struct drm_i915_gem_context_param param = {
202 .ctx_id = arg.ctx,
203 .param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE,
Chris Wilsone2598d42017-10-20 15:16:39 +0100204 .value = 0,
205 };
206 __gem_context_set_param(fd, &param);
207
208 eat_error_state(fd);
Chris Wilson0a1fc452016-09-13 11:13:14 +0100209 }
210}
211
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100212/**
Vinay Belgaumkar7bf3bd72017-10-13 10:22:20 -0700213 * has_ctx_exec:
214 * @fd: open i915 drm file descriptor
215 * @ring: execbuf ring flag
216 * @ctx: Context to be checked
217 *
218 * This helper function checks if non default context submission is allowed
219 * on a ring.
220 *
221 * Returns:
222 * True if allowed
223 *
224 */
225static bool has_ctx_exec(int fd, unsigned ring, uint32_t ctx)
226{
227 struct drm_i915_gem_execbuffer2 execbuf;
228 struct drm_i915_gem_exec_object2 exec;
229
230 /* silly ABI, the kernel thinks everyone who has BSD also has BSD2 */
231 if ((ring & ~(3<<13)) == I915_EXEC_BSD) {
232 if (ring & (3 << 13) && !gem_has_bsd2(fd))
233 return false;
234 }
235
236 memset(&exec, 0, sizeof(exec));
237 memset(&execbuf, 0, sizeof(execbuf));
238 execbuf.buffers_ptr = to_user_pointer(&exec);
239 execbuf.buffer_count = 1;
240 execbuf.flags = ring;
241 execbuf.rsvd1 = ctx;
242 /*
243 * If context submission is not allowed, this will return EINVAL
244 * Otherwise, this will return ENOENT on account of no gem obj
245 * being submitted
246 */
247 return __gem_execbuf(fd, &execbuf) == -ENOENT;
248}
249
250/**
Chris Wilson19642c62015-12-11 13:27:49 +0000251 * igt_hang_ring_ctx:
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100252 * @fd: open i915 drm file descriptor
Chris Wilson19642c62015-12-11 13:27:49 +0000253 * @ctx: the contxt specifier
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100254 * @ring: execbuf ring flag
Chris Wilson19642c62015-12-11 13:27:49 +0000255 * @flags: set of flags to control execution
Vinay Belgaumkar7bf3bd72017-10-13 10:22:20 -0700256 * @offset: The resultant gtt offset of the exec obj
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100257 *
Chris Wilson19642c62015-12-11 13:27:49 +0000258 * This helper function injects a hanging batch associated with @ctx into @ring.
Chris Wilson0a1fc452016-09-13 11:13:14 +0100259 * It returns a #igt_hang_t structure which must be passed to
Chris Wilson19642c62015-12-11 13:27:49 +0000260 * igt_post_hang_ring() for hang post-processing (after the gpu hang
261 * interaction has been tested.
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100262 *
263 * Returns:
264 * Structure with helper internal state for igt_post_hang_ring().
265 */
Chris Wilson0a1fc452016-09-13 11:13:14 +0100266igt_hang_t igt_hang_ctx(int fd,
267 uint32_t ctx,
268 int ring,
269 unsigned flags,
270 uint64_t *offset)
Chris Wilson16bafdf2014-09-04 09:26:24 +0100271{
272 struct drm_i915_gem_relocation_entry reloc;
273 struct drm_i915_gem_execbuffer2 execbuf;
274 struct drm_i915_gem_exec_object2 exec;
Eric Anholtaa97faa2017-11-10 12:49:14 -0800275 struct drm_i915_gem_context_param param;
Chris Wilson415398a2016-05-20 22:06:09 +0100276 uint32_t b[16];
Chris Wilson16bafdf2014-09-04 09:26:24 +0100277 unsigned ban;
278 unsigned len;
279
Chris Wilsona2eb6372015-12-11 21:24:21 +0000280 igt_require_hang_ring(fd, ring);
281
Vinay Belgaumkar7bf3bd72017-10-13 10:22:20 -0700282 /* check if non-default ctx submission is allowed */
283 igt_require(ctx == 0 || has_ctx_exec(fd, ring, ctx));
Chris Wilson19642c62015-12-11 13:27:49 +0000284
Eric Anholtaa97faa2017-11-10 12:49:14 -0800285 param.ctx_id = ctx;
Chris Wilson16bafdf2014-09-04 09:26:24 +0100286 param.size = 0;
Chris Wilson19642c62015-12-11 13:27:49 +0000287
288 if ((flags & HANG_ALLOW_CAPTURE) == 0) {
Eric Anholtaa97faa2017-11-10 12:49:14 -0800289 param.param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE;
Chris Wilson19642c62015-12-11 13:27:49 +0000290 param.value = 1;
291 /* Older kernels may not have NO_ERROR_CAPTURE, in which case
292 * we just eat the error state in post-hang (and hope we eat
293 * the right one).
294 */
295 __gem_context_set_param(fd, &param);
Chris Wilson19642c62015-12-11 13:27:49 +0000296 }
297
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200298 ban = context_get_ban(fd, ctx);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100299
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200300 if ((flags & HANG_ALLOW_BAN) == 0)
301 context_set_ban(fd, ctx, 0);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100302
303 memset(&reloc, 0, sizeof(reloc));
304 memset(&exec, 0, sizeof(exec));
305 memset(&execbuf, 0, sizeof(execbuf));
306
307 exec.handle = gem_create(fd, 4096);
308 exec.relocation_count = 1;
Chris Wilson39858a12017-01-02 11:05:21 +0000309 exec.relocs_ptr = to_user_pointer(&reloc);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100310
Chris Wilson19642c62015-12-11 13:27:49 +0000311 memset(b, 0xc5, sizeof(b));
Mika Kuoppalab5ef40e2016-06-08 15:50:50 +0300312
Chris Wilson16bafdf2014-09-04 09:26:24 +0100313 len = 2;
Chris Wilson27ff12f2017-08-07 13:36:36 +0100314 if (intel_gen(intel_get_drm_devid(fd)) >= 8)
Chris Wilson16bafdf2014-09-04 09:26:24 +0100315 len++;
Chris Wilson27ff12f2017-08-07 13:36:36 +0100316 b[0] = MI_BATCH_BUFFER_START | (len - 2);
317 b[len] = MI_BATCH_BUFFER_END;
318 b[len+1] = MI_NOOP;
Chris Wilson16bafdf2014-09-04 09:26:24 +0100319 gem_write(fd, exec.handle, 0, b, sizeof(b));
320
Chris Wilson27ff12f2017-08-07 13:36:36 +0100321 reloc.offset = sizeof(uint32_t);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100322 reloc.target_handle = exec.handle;
323 reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
324
Chris Wilson39858a12017-01-02 11:05:21 +0000325 execbuf.buffers_ptr = to_user_pointer(&exec);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100326 execbuf.buffer_count = 1;
Chris Wilson16bafdf2014-09-04 09:26:24 +0100327 execbuf.flags = ring;
Chris Wilson19642c62015-12-11 13:27:49 +0000328 i915_execbuffer2_set_context_id(execbuf, ctx);
Chris Wilson16bafdf2014-09-04 09:26:24 +0100329 gem_execbuf(fd, &execbuf);
330
Chris Wilson19642c62015-12-11 13:27:49 +0000331 if (offset)
332 *offset = exec.offset;
333
Chris Wilson0a1fc452016-09-13 11:13:14 +0100334 return (igt_hang_t){ exec.handle, ctx, ban, flags };
Chris Wilson19642c62015-12-11 13:27:49 +0000335}
336
337/**
338 * igt_hang_ring:
339 * @fd: open i915 drm file descriptor
340 * @ring: execbuf ring flag
341 *
342 * This helper function injects a hanging batch into @ring. It returns a
Chris Wilson0a1fc452016-09-13 11:13:14 +0100343 * #igt_hang_t structure which must be passed to igt_post_hang_ring() for
Chris Wilson19642c62015-12-11 13:27:49 +0000344 * hang post-processing (after the gpu hang interaction has been tested.
345 *
346 * Returns:
347 * Structure with helper internal state for igt_post_hang_ring().
348 */
Chris Wilson0a1fc452016-09-13 11:13:14 +0100349igt_hang_t igt_hang_ring(int fd, int ring)
Chris Wilson19642c62015-12-11 13:27:49 +0000350{
351 return igt_hang_ctx(fd, 0, ring, 0, NULL);
352}
353
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100354/**
Thomas Wood26f40812015-02-20 11:31:01 +0000355 * igt_post_hang_ring:
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100356 * @fd: open i915 drm file descriptor
357 * @arg: hang state from igt_hang_ring()
358 *
359 * This function does the necessary post-processing after a gpu hang injected
360 * with igt_hang_ring().
361 */
Chris Wilson0a1fc452016-09-13 11:13:14 +0100362void igt_post_hang_ring(int fd, igt_hang_t arg)
Chris Wilson16bafdf2014-09-04 09:26:24 +0100363{
Chris Wilson16bafdf2014-09-04 09:26:24 +0100364 if (arg.handle == 0)
365 return;
366
367 gem_set_domain(fd, arg.handle,
368 I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
369 gem_close(fd, arg.handle);
370
Mika Kuoppala773ac7c2016-11-08 12:31:06 +0200371 context_set_ban(fd, arg.ctx, arg.ban);
Chris Wilson19642c62015-12-11 13:27:49 +0000372
373 if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
Eric Anholtaa97faa2017-11-10 12:49:14 -0800374 struct drm_i915_gem_context_param param = {
375 .ctx_id = arg.ctx,
376 .param = I915_CONTEXT_PARAM_NO_ERROR_CAPTURE,
Chris Wilsone2598d42017-10-20 15:16:39 +0100377 .value = 0,
378 };
379 __gem_context_set_param(fd, &param);
380
381 eat_error_state(fd);
Chris Wilson19642c62015-12-11 13:27:49 +0000382 }
Chris Wilson16bafdf2014-09-04 09:26:24 +0100383}
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100384
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000385/**
386 * igt_force_gpu_reset:
387 *
388 * forces a gpu reset using the i915_wedged debugfs interface. To be used to
389 * recover from situations where the hangcheck didn't trigger and/or the gpu is
390 * stuck, either because the test manually disabled gpu resets or because the
391 * test hit an hangcheck bug
392 */
Chris Wilson83884e92017-03-21 17:16:03 +0000393void igt_force_gpu_reset(int drm_fd)
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000394{
Chris Wilson58de7852017-03-24 18:11:08 +0000395 int dir, wedged;
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000396
397 igt_debug("Triggering GPU reset\n");
398
Chris Wilson58de7852017-03-24 18:11:08 +0000399 dir = igt_debugfs_dir(drm_fd);
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000400
Chris Wilson58de7852017-03-24 18:11:08 +0000401 igt_sysfs_set(dir, "i915_wedged", "-1");
402 igt_sysfs_scanf(dir, "i915_wedged", "%d", &wedged);
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000403
Chris Wilson58de7852017-03-24 18:11:08 +0000404 close(dir);
Chris Wilson28a2f142017-03-08 12:22:13 +0000405
406 igt_assert(!wedged);
Daniele Ceraolo Spurio03c7f842016-03-01 11:01:32 +0000407}
408
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100409/* GPU abusers */
410static struct igt_helper_process hang_helper;
411static void __attribute__((noreturn))
412hang_helper_process(pid_t pid, int fd)
413{
414 while (1) {
415 if (kill(pid, 0)) /* Parent has died, so must we. */
416 exit(0);
417
418 igt_post_hang_ring(fd,
419 igt_hang_ring(fd, I915_EXEC_DEFAULT));
420
421 sleep(1);
422 }
423}
424
425/**
426 * igt_fork_hang_helper:
427 *
428 * Fork a child process using #igt_fork_helper to hang the default engine
429 * of the GPU at regular intervals.
430 *
431 * This is useful to exercise slow running code (such as aperture placement)
432 * which needs to be robust against a GPU reset.
433 *
Daniel Vetterd8d1eab2015-12-03 07:45:34 +0100434 * This function automatically skips when test requirements aren't met using
435 * igt_skip().
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100436 */
Daniel Vetterd8d1eab2015-12-03 07:45:34 +0100437void igt_fork_hang_helper(void)
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100438{
439 int fd, gen;
440
Micah Fedkec81d2932015-07-22 21:54:02 +0000441 fd = drm_open_driver(DRIVER_INTEL);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100442
443 gen = intel_gen(intel_get_drm_devid(fd));
Daniel Vetterd8d1eab2015-12-03 07:45:34 +0100444 igt_skip_on(gen < 5);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100445
446 igt_fork_helper(&hang_helper)
447 hang_helper_process(getppid(), fd);
448
449 close(fd);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100450}
451
452/**
453 * igt_stop_hang_helper:
454 *
455 * Stops the child process spawned with igt_fork_hang_helper().
456 *
457 * In tests with subtests this function can be called outside of failure
458 * catching code blocks like #igt_fixture or #igt_subtest.
459 */
460void igt_stop_hang_helper(void)
461{
Daniel Vetterd8d1eab2015-12-03 07:45:34 +0100462 if (hang_helper.running)
463 igt_stop_helper(&hang_helper);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100464}
465
466/**
467 * igt_open_forcewake_handle:
468 *
469 * This functions opens the debugfs forcewake file and so prevents the GT from
470 * suspending. The reference is automatically dropped when the is closed.
471 *
472 * Returns:
473 * The file descriptor of the forcewake handle or -1 if that didn't work out.
474 */
Chris Wilson83884e92017-03-21 17:16:03 +0000475int igt_open_forcewake_handle(int fd)
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100476{
477 if (getenv("IGT_NO_FORCEWAKE"))
478 return -1;
Chris Wilson83884e92017-03-21 17:16:03 +0000479 return igt_debugfs_open(fd, "i915_forcewake_user", O_WRONLY);
Daniel Vetter3cd45de2015-02-10 17:46:43 +0100480}
Chris Wilsona6090c72016-01-08 16:32:29 +0000481
Chris Wilson7d089132016-05-01 16:39:14 +0100482#if defined(__x86_64__) || defined(__i386__)
Robert Foss8875bb12016-06-27 06:58:24 -0400483static unsigned int clflush_size;
484
Chris Wilsona6090c72016-01-08 16:32:29 +0000485int igt_setup_clflush(void)
486{
487 FILE *file;
488 char *line = NULL;
489 size_t size = 0;
490 int first_stanza = 1;
491 int has_clflush = 0;
492
493 if (clflush_size)
494 return 1;
495
496 file = fopen("/proc/cpuinfo", "r");
497 if (file == NULL)
498 return 0;
499
500 while (getline(&line, &size, file) != -1) {
501 if (strncmp(line, "processor", 9) == 0) {
502 if (!first_stanza)
503 break;
504 first_stanza = 0;
505 }
506
507 if (strncmp(line, "flags", 5) == 0) {
508 if (strstr(line, "clflush"))
509 has_clflush = 1;
510 }
511
512 if (strncmp(line, "clflush size", 12) == 0) {
513 char *colon = strchr(line, ':');
514 if (colon)
515 clflush_size = atoi(colon + 1);
516 }
517 }
518 free(line);
519 fclose(file);
520
521 return has_clflush && clflush_size;
522}
523
Chris Wilson7d089132016-05-01 16:39:14 +0100524__attribute__((target("sse2")))
Chris Wilsona6090c72016-01-08 16:32:29 +0000525void igt_clflush_range(void *addr, int size)
526{
527 char *p, *end;
528
529 end = (char *)addr + size;
530 p = (char *)((uintptr_t)addr & ~((uintptr_t)clflush_size - 1));
531
Chris Wilson7499b912016-03-03 11:51:18 +0000532 __builtin_ia32_mfence();
Chris Wilsona6090c72016-01-08 16:32:29 +0000533 for (; p < end; p += clflush_size)
Chris Wilson7499b912016-03-03 11:51:18 +0000534 __builtin_ia32_clflush(p);
Chris Wilsonb4817052016-05-01 09:07:29 +0100535 __builtin_ia32_clflush(end - 1); /* magic serialisation for byt+ */
Chris Wilson7499b912016-03-03 11:51:18 +0000536 __builtin_ia32_mfence();
Chris Wilsona6090c72016-01-08 16:32:29 +0000537}
Chris Wilson7d089132016-05-01 16:39:14 +0100538#else
539int igt_setup_clflush(void)
540{
541 /* requires mfence + clflush, both SSE2 instructions */
542 return 0;
543}
544
545void igt_clflush_range(void *addr, int size)
546{
547 fprintf(stderr, "igt_clflush_range() unsupported\n");
548}
549#endif
Chris Wilson5b675f72016-01-22 17:33:40 +0000550
551/**
552 * intel_detect_and_clear_missed_irq:
553 * @fd: open i915 drm file descriptor, used to quiesce the gpu
554 *
555 * This functions idles the GPU and then queries whether there has
556 * been a missed interrupt reported by the driver. Afterwards it
557 * clears the missed interrupt flag, in order to disable the timer
558 * fallback for the next test.
559 */
560unsigned intel_detect_and_clear_missed_interrupts(int fd)
561{
Chris Wilson58de7852017-03-24 18:11:08 +0000562 unsigned missed;
563 int dir;
Chris Wilson5b675f72016-01-22 17:33:40 +0000564
565 gem_quiescent_gpu(fd);
566
Chris Wilson58de7852017-03-24 18:11:08 +0000567 dir = igt_debugfs_dir(fd);
568
569 missed = 0;
570 igt_assert(igt_sysfs_scanf(dir, "i915_ring_missed_irq", "%x", &missed) == 1);
571 if (missed)
572 igt_sysfs_set(dir, "i915_ring_missed_irq", "0");
573
574 close(dir);
Chris Wilson5b675f72016-01-22 17:33:40 +0000575
Chris Wilsonf22e19b2017-03-23 10:51:28 +0000576 errno = 0;
Chris Wilson5b675f72016-01-22 17:33:40 +0000577 return missed;
578}
Chris Wilson04f52152016-01-27 14:07:27 +0000579
580const struct intel_execution_engine intel_execution_engines[] = {
Chris Wilsonec91c562017-07-06 14:01:56 +0100581 { "default", NULL, 0, 0 },
Chris Wilson82fdfc62017-04-11 20:20:28 +0100582 { "render", "rcs0", I915_EXEC_RENDER, 0 },
583 { "bsd", "vcs0", I915_EXEC_BSD, 0 },
584 { "bsd1", "vcs0", I915_EXEC_BSD, 1<<13 /*I915_EXEC_BSD_RING1*/ },
585 { "bsd2", "vcs1", I915_EXEC_BSD, 2<<13 /*I915_EXEC_BSD_RING2*/ },
586 { "blt", "bcs0", I915_EXEC_BLT, 0 },
587 { "vebox", "vecs0", I915_EXEC_VEBOX, 0 },
Chris Wilson04f52152016-01-27 14:07:27 +0000588 { NULL, 0, 0 }
589};
Chris Wilsonbc787762017-05-18 12:11:59 +0100590
591bool gem_can_store_dword(int fd, unsigned int engine)
592{
593 uint16_t devid = intel_get_drm_devid(fd);
594 const struct intel_device_info *info = intel_get_device_info(devid);
595 const int gen = ffs(info->gen);
596
597 if (gen <= 2) /* requires physical addresses */
598 return false;
599
Chris Wilsondddbc2e2017-09-06 15:34:13 +0100600 if (gen == 3 && (info->is_grantsdale || info->is_alviso))
601 return false; /* only supports physical addresses */
602
Chris Wilsonbc787762017-05-18 12:11:59 +0100603 if (gen == 6 && (engine & ~(3<<13)) == I915_EXEC_BSD)
604 return false; /* kills the machine! */
605
606 if (info->is_broadwater)
607 return false; /* Not sure yet... */
608
609 return true;
610}