blob: 6ac743f1ae43e2331ed60910bcfaaa1625b117d2 [file] [log] [blame]
Mika Kuoppala9b0d3482014-05-19 17:42:21 +03001/*
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 * Authors:
24 * Mika Kuoppala <mika.kuoppala@intel.com>
Mika Kuoppala6fa19342014-05-20 11:25:48 +030025 * Oscar Mateo <oscar.mateo@intel.com>
Mika Kuoppala9b0d3482014-05-19 17:42:21 +030026 *
27 */
28
Thomas Wood804e11f2015-08-17 17:57:43 +010029#include "igt.h"
Mika Kuoppala9b0d3482014-05-19 17:42:21 +030030#include <limits.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34
Brad Volkine34240d2014-11-04 14:00:43 -080035#ifndef I915_PARAM_CMD_PARSER_VERSION
36#define I915_PARAM_CMD_PARSER_VERSION 28
37#endif
38
Chris Wilson405b3472016-02-26 12:47:33 +000039static char read_buffer[1024];
40
Mika Kuoppala9b0d3482014-05-19 17:42:21 +030041static int _read_sysfs(void *dst, int maxlen,
42 const char* path,
43 const char *fname)
44{
45 int fd;
46 char full[PATH_MAX];
47 int r, e;
48
49 igt_assert(snprintf(full, PATH_MAX, "%s/%s", path, fname) < PATH_MAX);
50
51 fd = open(full, O_RDONLY);
52 if (fd == -1)
53 return -errno;
54
55 r = read(fd, dst, maxlen);
56 e = errno;
57 close(fd);
58
59 if (r < 0)
60 return -e;
61
62 return r;
63}
64
65static int read_sysfs(void *dst, int maxlen, const char *fname)
66{
67 char path[PATH_MAX];
68
69 igt_assert(snprintf(path, PATH_MAX, "/sys/class/drm/card%d",
70 drm_get_card()) < PATH_MAX);
71
72 return _read_sysfs(dst, maxlen, path, fname);
73}
74
75static void test_sysfs_error_exists(void)
76{
Chris Wilson405b3472016-02-26 12:47:33 +000077 igt_assert_lt(0, read_sysfs(read_buffer, sizeof(read_buffer), "error"));
Mika Kuoppala9b0d3482014-05-19 17:42:21 +030078}
79
80static void test_debugfs_error_state_exists(void)
81{
82 int fd;
83
Matt Roper07be8fe2015-03-05 15:01:00 -080084 igt_assert_lte(0,
85 (fd = igt_debugfs_open("i915_error_state", O_RDONLY)));
Mika Kuoppala9b0d3482014-05-19 17:42:21 +030086
87 close (fd);
88}
89
90static void test_debugfs_ring_stop_exists(void)
91{
92 int fd;
93
Matt Roper07be8fe2015-03-05 15:01:00 -080094 igt_assert_lte(0, (fd = igt_debugfs_open("i915_ring_stop", O_RDONLY)));
Mika Kuoppala9b0d3482014-05-19 17:42:21 +030095
96 close(fd);
97}
98
99static void read_dfs(const char *fname, char *d, int maxlen)
100{
101 int fd;
102 int l;
103
Matt Roper07be8fe2015-03-05 15:01:00 -0800104 igt_assert_lte(0, (fd = igt_debugfs_open(fname, O_RDONLY)));
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300105
Matt Roper07be8fe2015-03-05 15:01:00 -0800106 igt_assert_lt(0, (l = read(fd, d, maxlen - 1)));
107 igt_assert_lt(l, maxlen);
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300108 d[l] = 0;
109 close(fd);
110
111 igt_debug("dfs entry %s read '%s'\n", fname, d);
112}
113
Chris Wilson405b3472016-02-26 12:47:33 +0000114static int compare_dfs_entry(const char *fname, const char *s)
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300115{
Chris Wilson405b3472016-02-26 12:47:33 +0000116 const int l = min(strlen(s), sizeof(read_buffer));
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300117
Chris Wilson405b3472016-02-26 12:47:33 +0000118 read_dfs(fname, read_buffer, l + 1);
119 return strncmp(read_buffer, s, l);
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300120}
121
122static void assert_dfs_entry(const char *fname, const char *s)
123{
Chris Wilson405b3472016-02-26 12:47:33 +0000124 igt_fail_on_f(compare_dfs_entry(fname, s) != 0,
125 "contents of %s: '%s' (expected '%s')\n",
126 fname, read_buffer, s);
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300127}
128
129static void assert_dfs_entry_not(const char *fname, const char *s)
130{
Chris Wilson405b3472016-02-26 12:47:33 +0000131 igt_fail_on_f(compare_dfs_entry(fname, s) == 0,
132 "contents of %s: '%s' (expected not '%s'\n",
133 fname, read_buffer, s);
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300134}
135
136static void assert_error_state_clear(void)
137{
138 assert_dfs_entry("i915_error_state", "no error state collected");
139}
140
141static void assert_error_state_collected(void)
142{
143 assert_dfs_entry_not("i915_error_state", "no error state collected");
144}
145
Chris Wilson07530572015-12-11 13:27:49 +0000146const uint32_t *batch;
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300147
Chris Wilson07530572015-12-11 13:27:49 +0000148static uint64_t submit_hang(int fd, unsigned ring_id)
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300149{
Chris Wilson07530572015-12-11 13:27:49 +0000150 uint64_t offset;
151 igt_hang_ring_t hang;
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300152
Chris Wilson07530572015-12-11 13:27:49 +0000153 hang = igt_hang_ctx(fd, 0, ring_id, HANG_ALLOW_CAPTURE, &offset);
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300154
Chris Wilson07530572015-12-11 13:27:49 +0000155 batch = gem_mmap__cpu(fd, hang.handle, 0, 4096, PROT_READ);
156 gem_set_domain(fd, hang.handle, I915_GEM_DOMAIN_CPU, 0);
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300157
Chris Wilson07530572015-12-11 13:27:49 +0000158 igt_post_hang_ring(fd, hang);
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300159
Chris Wilson07530572015-12-11 13:27:49 +0000160 return offset;
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300161}
162
163static void clear_error_state(void)
164{
165 int fd;
166 const char *b = "1";
167
Matt Roper07be8fe2015-03-05 15:01:00 -0800168 igt_assert_lte(0,
169 (fd = igt_debugfs_open("i915_error_state", O_WRONLY)));
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300170 igt_assert(write(fd, b, 1) == 1);
171 close(fd);
172}
173
174static void test_error_state_basic(void)
175{
176 int fd;
177
Daniel Vetter6cf72722015-12-03 07:45:36 +0100178 fd = drm_open_driver(DRIVER_INTEL);
179
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300180 clear_error_state();
181 assert_error_state_clear();
182
Chris Wilson07530572015-12-11 13:27:49 +0000183 submit_hang(fd, I915_EXEC_RENDER);
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300184 close(fd);
185
186 assert_error_state_collected();
187 clear_error_state();
188 assert_error_state_clear();
189}
190
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300191static void check_error_state(const int gen,
Brad Volkine34240d2014-11-04 14:00:43 -0800192 const bool uses_cmd_parser,
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300193 const char *expected_ring_name,
194 uint64_t expected_offset)
195{
196 FILE *file;
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300197 char *line = NULL;
198 size_t line_size = 0;
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300199
Chris Wilson01e467a2016-01-01 11:29:51 +0000200 file = igt_debugfs_fopen("i915_error_state", "r");
201 igt_require(file);
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300202
203 while (getline(&line, &line_size, file) > 0) {
Chris Wilson01e467a2016-01-01 11:29:51 +0000204 char *dashes;
Mika Kuoppalac37b2352015-08-18 17:44:38 +0300205 uint32_t gtt_offset_upper, gtt_offset_lower;
Chris Wilson01e467a2016-01-01 11:29:51 +0000206 int matched;
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300207
208 dashes = strstr(line, "---");
209 if (!dashes)
210 continue;
211
Chris Wilson01e467a2016-01-01 11:29:51 +0000212 matched = sscanf(dashes, "--- gtt_offset = 0x%08x %08x\n",
Mika Kuoppalac37b2352015-08-18 17:44:38 +0300213 &gtt_offset_upper, &gtt_offset_lower);
Chris Wilson01e467a2016-01-01 11:29:51 +0000214 if (matched) {
215 char expected_line[64];
216 uint64_t gtt_offset;
217 int i;
Mika Kuoppalac37b2352015-08-18 17:44:38 +0300218
Chris Wilson01e467a2016-01-01 11:29:51 +0000219 strncpy(expected_line, line, dashes - line);
220 expected_line[dashes - line - 1] = '\0';
221 igt_assert(strstr(expected_line, expected_ring_name));
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300222
Chris Wilson01e467a2016-01-01 11:29:51 +0000223 gtt_offset = gtt_offset_upper;
224 if (matched == 2) {
225 gtt_offset <<= 32;
226 gtt_offset |= gtt_offset_lower;
227 }
Brad Volkine34240d2014-11-04 14:00:43 -0800228 if (!uses_cmd_parser)
Chris Wilson01e467a2016-01-01 11:29:51 +0000229 igt_assert_eq_u64(gtt_offset, expected_offset);
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300230
Chris Wilson07530572015-12-11 13:27:49 +0000231 for (i = 0; i < 1024; i++) {
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300232 igt_assert(getline(&line, &line_size, file) > 0);
Chris Wilson01e467a2016-01-01 11:29:51 +0000233 snprintf(expected_line, sizeof(expected_line),
234 "%08x : %08x",
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300235 4*i, batch[i]);
236 igt_assert(strstr(line, expected_line));
237 }
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300238 break;
Chris Wilson01e467a2016-01-01 11:29:51 +0000239 }
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300240 }
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300241
242 free(line);
Chris Wilson01e467a2016-01-01 11:29:51 +0000243 fclose(file);
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300244}
245
Brad Volkine34240d2014-11-04 14:00:43 -0800246static bool uses_cmd_parser(int fd, int gen)
247{
248 int parser_version = 0;
249 drm_i915_getparam_t gp;
250 int rc;
251
252 gp.param = I915_PARAM_CMD_PARSER_VERSION;
253 gp.value = &parser_version;
254 rc = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
255 if (rc || parser_version == 0)
256 return false;
257
Michał Winiarski52b5d502016-01-25 19:35:01 +0100258 if (!gem_uses_ppgtt(fd))
Brad Volkine34240d2014-11-04 14:00:43 -0800259 return false;
260
261 if (gen != 7)
262 return false;
263
264 return true;
265}
266
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300267static void test_error_state_capture(unsigned ring_id,
268 const char *ring_name)
269{
270 int fd, gen;
271 uint64_t offset;
Brad Volkine34240d2014-11-04 14:00:43 -0800272 bool cmd_parser;
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300273
Daniel Vetter6cf72722015-12-03 07:45:36 +0100274 fd = drm_open_driver(DRIVER_INTEL);
275
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300276 clear_error_state();
277
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300278 gen = intel_gen(intel_get_drm_devid(fd));
Brad Volkine34240d2014-11-04 14:00:43 -0800279 cmd_parser = uses_cmd_parser(fd, gen);
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300280
Chris Wilson07530572015-12-11 13:27:49 +0000281 offset = submit_hang(fd, ring_id);
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300282 close(fd);
283
Brad Volkine34240d2014-11-04 14:00:43 -0800284 check_error_state(gen, cmd_parser, ring_name, offset);
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300285}
286
Daniele Ceraolo Spurio95ca7642016-03-01 11:01:33 +0000287
288/* This test covers the case where we end up in an uninitialised area of the
289 * ppgtt and keep executing through it. This is particularly relevant if 48b
290 * ppgtt is enabled because the ppgtt is massively bigger compared to the 32b
291 * case and it takes a lot more time to wrap, so the acthd can potentially keep
292 * increasing for a long time
293 */
294#define NSEC_PER_SEC 1000000000L
295static void hangcheck_unterminated(void)
296{
297 int fd;
298 /* timeout needs to be greater than ~5*hangcheck */
299 int64_t timeout_ns = 100 * NSEC_PER_SEC; /* 100 seconds */
300 struct drm_i915_gem_execbuffer2 execbuf;
301 struct drm_i915_gem_exec_object2 gem_exec;
302 uint32_t handle;
303
304 fd = drm_open_driver(DRIVER_INTEL);
305 igt_require(gem_uses_full_ppgtt(fd));
306 igt_require_hang_ring(fd, 0);
307
308 handle = gem_create(fd, 4096);
309
310 memset(&gem_exec, 0, sizeof(gem_exec));
311 gem_exec.handle = handle;
312
313 memset(&execbuf, 0, sizeof(execbuf));
314 execbuf.buffers_ptr = (uintptr_t)&gem_exec;
315 execbuf.buffer_count = 1;
316
317 gem_execbuf(fd, &execbuf);
318 if (gem_wait(fd, handle, &timeout_ns) != 0) {
319 /* need to manually trigger an hang to clean before failing */
320 igt_force_gpu_reset();
321 igt_assert_f(0, "unterminated batch did not trigger an hang!");
322 }
323
324 close(fd);
325}
326
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300327igt_main
328{
Chris Wilson38fe49d2016-02-04 11:17:42 +0000329 const struct intel_execution_engine *e;
330
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300331 igt_skip_on_simulation();
332
333 igt_subtest("error-state-debugfs-entry")
334 test_debugfs_error_state_exists();
335
336 igt_subtest("error-state-sysfs-entry")
337 test_sysfs_error_exists();
338
339 igt_subtest("ring-stop-sysfs-entry")
340 test_debugfs_ring_stop_exists();
341
342 igt_subtest("error-state-basic")
343 test_error_state_basic();
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300344
Chris Wilson38fe49d2016-02-04 11:17:42 +0000345 for (e = intel_execution_engines; e->name; e++) {
346 if (e->exec_id == 0)
347 continue;
348
349 igt_subtest_f("error-state-capture-%s", e->name)
350 test_error_state_capture(e->exec_id | e->flags,
351 e->full_name);
Mika Kuoppala6fa19342014-05-20 11:25:48 +0300352 }
Daniele Ceraolo Spurio95ca7642016-03-01 11:01:33 +0000353
354 igt_subtest("hangcheck-unterminated")
355 hangcheck_unterminated();
Mika Kuoppala9b0d3482014-05-19 17:42:21 +0300356}