1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2014 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 * Authors:
24*d83cc019SAndroid Build Coastguard Worker * Mika Kuoppala <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker * Oscar Mateo <[email protected]>
26*d83cc019SAndroid Build Coastguard Worker *
27*d83cc019SAndroid Build Coastguard Worker */
28*d83cc019SAndroid Build Coastguard Worker
29*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
30*d83cc019SAndroid Build Coastguard Worker #include <limits.h>
31*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
32*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
33*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
34*d83cc019SAndroid Build Coastguard Worker
35*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
36*d83cc019SAndroid Build Coastguard Worker #include "igt_debugfs.h"
37*d83cc019SAndroid Build Coastguard Worker
38*d83cc019SAndroid Build Coastguard Worker #ifndef I915_PARAM_CMD_PARSER_VERSION
39*d83cc019SAndroid Build Coastguard Worker #define I915_PARAM_CMD_PARSER_VERSION 28
40*d83cc019SAndroid Build Coastguard Worker #endif
41*d83cc019SAndroid Build Coastguard Worker
42*d83cc019SAndroid Build Coastguard Worker static int device = -1;
43*d83cc019SAndroid Build Coastguard Worker static int sysfs = -1;
44*d83cc019SAndroid Build Coastguard Worker
has_error_state(int dir)45*d83cc019SAndroid Build Coastguard Worker static bool has_error_state(int dir)
46*d83cc019SAndroid Build Coastguard Worker {
47*d83cc019SAndroid Build Coastguard Worker bool result;
48*d83cc019SAndroid Build Coastguard Worker int fd;
49*d83cc019SAndroid Build Coastguard Worker
50*d83cc019SAndroid Build Coastguard Worker fd = openat(dir, "error", O_RDONLY);
51*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
52*d83cc019SAndroid Build Coastguard Worker return false;
53*d83cc019SAndroid Build Coastguard Worker
54*d83cc019SAndroid Build Coastguard Worker if (read(fd, &result, sizeof(result)) < 0)
55*d83cc019SAndroid Build Coastguard Worker result = false;
56*d83cc019SAndroid Build Coastguard Worker else
57*d83cc019SAndroid Build Coastguard Worker result = true;
58*d83cc019SAndroid Build Coastguard Worker
59*d83cc019SAndroid Build Coastguard Worker close(fd);
60*d83cc019SAndroid Build Coastguard Worker return result;
61*d83cc019SAndroid Build Coastguard Worker }
62*d83cc019SAndroid Build Coastguard Worker
assert_entry(const char * s,bool expect)63*d83cc019SAndroid Build Coastguard Worker static void assert_entry(const char *s, bool expect)
64*d83cc019SAndroid Build Coastguard Worker {
65*d83cc019SAndroid Build Coastguard Worker char *error;
66*d83cc019SAndroid Build Coastguard Worker
67*d83cc019SAndroid Build Coastguard Worker error = igt_sysfs_get(sysfs, "error");
68*d83cc019SAndroid Build Coastguard Worker igt_assert(error);
69*d83cc019SAndroid Build Coastguard Worker
70*d83cc019SAndroid Build Coastguard Worker igt_assert_f(!!strcasecmp(error, s) != expect,
71*d83cc019SAndroid Build Coastguard Worker "contents of error: '%s' (expected %s '%s')\n",
72*d83cc019SAndroid Build Coastguard Worker error, expect ? "": "not", s);
73*d83cc019SAndroid Build Coastguard Worker
74*d83cc019SAndroid Build Coastguard Worker free(error);
75*d83cc019SAndroid Build Coastguard Worker }
76*d83cc019SAndroid Build Coastguard Worker
assert_error_state_clear(void)77*d83cc019SAndroid Build Coastguard Worker static void assert_error_state_clear(void)
78*d83cc019SAndroid Build Coastguard Worker {
79*d83cc019SAndroid Build Coastguard Worker assert_entry("no error state collected", true);
80*d83cc019SAndroid Build Coastguard Worker }
81*d83cc019SAndroid Build Coastguard Worker
assert_error_state_collected(void)82*d83cc019SAndroid Build Coastguard Worker static void assert_error_state_collected(void)
83*d83cc019SAndroid Build Coastguard Worker {
84*d83cc019SAndroid Build Coastguard Worker assert_entry("no error state collected", false);
85*d83cc019SAndroid Build Coastguard Worker }
86*d83cc019SAndroid Build Coastguard Worker
clear_error_state(void)87*d83cc019SAndroid Build Coastguard Worker static void clear_error_state(void)
88*d83cc019SAndroid Build Coastguard Worker {
89*d83cc019SAndroid Build Coastguard Worker igt_sysfs_write(sysfs, "error", "", 1);
90*d83cc019SAndroid Build Coastguard Worker }
91*d83cc019SAndroid Build Coastguard Worker
test_error_state_basic(void)92*d83cc019SAndroid Build Coastguard Worker static void test_error_state_basic(void)
93*d83cc019SAndroid Build Coastguard Worker {
94*d83cc019SAndroid Build Coastguard Worker int fd;
95*d83cc019SAndroid Build Coastguard Worker
96*d83cc019SAndroid Build Coastguard Worker clear_error_state();
97*d83cc019SAndroid Build Coastguard Worker assert_error_state_clear();
98*d83cc019SAndroid Build Coastguard Worker
99*d83cc019SAndroid Build Coastguard Worker /* Manually trigger a hang by request a reset */
100*d83cc019SAndroid Build Coastguard Worker fd = igt_debugfs_open(device, "i915_wedged", O_WRONLY);
101*d83cc019SAndroid Build Coastguard Worker igt_ignore_warn(write(fd, "1\n", 2));
102*d83cc019SAndroid Build Coastguard Worker close(fd);
103*d83cc019SAndroid Build Coastguard Worker
104*d83cc019SAndroid Build Coastguard Worker assert_error_state_collected();
105*d83cc019SAndroid Build Coastguard Worker
106*d83cc019SAndroid Build Coastguard Worker clear_error_state();
107*d83cc019SAndroid Build Coastguard Worker assert_error_state_clear();
108*d83cc019SAndroid Build Coastguard Worker }
109*d83cc019SAndroid Build Coastguard Worker
open_error(void)110*d83cc019SAndroid Build Coastguard Worker static FILE *open_error(void)
111*d83cc019SAndroid Build Coastguard Worker {
112*d83cc019SAndroid Build Coastguard Worker int fd;
113*d83cc019SAndroid Build Coastguard Worker
114*d83cc019SAndroid Build Coastguard Worker fd = openat(sysfs, "error", O_RDONLY);
115*d83cc019SAndroid Build Coastguard Worker if (fd < 0)
116*d83cc019SAndroid Build Coastguard Worker return NULL;
117*d83cc019SAndroid Build Coastguard Worker
118*d83cc019SAndroid Build Coastguard Worker return fdopen(fd, "r");
119*d83cc019SAndroid Build Coastguard Worker }
120*d83cc019SAndroid Build Coastguard Worker
uses_cmd_parser(void)121*d83cc019SAndroid Build Coastguard Worker static bool uses_cmd_parser(void)
122*d83cc019SAndroid Build Coastguard Worker {
123*d83cc019SAndroid Build Coastguard Worker int parser_version = 0;
124*d83cc019SAndroid Build Coastguard Worker drm_i915_getparam_t gp;
125*d83cc019SAndroid Build Coastguard Worker
126*d83cc019SAndroid Build Coastguard Worker gp.param = I915_PARAM_CMD_PARSER_VERSION;
127*d83cc019SAndroid Build Coastguard Worker gp.value = &parser_version;
128*d83cc019SAndroid Build Coastguard Worker drmIoctl(device, DRM_IOCTL_I915_GETPARAM, &gp);
129*d83cc019SAndroid Build Coastguard Worker
130*d83cc019SAndroid Build Coastguard Worker return parser_version > 0;
131*d83cc019SAndroid Build Coastguard Worker }
132*d83cc019SAndroid Build Coastguard Worker
check_error_state(const char * expected_ring_name,uint64_t expected_offset,const uint32_t * batch)133*d83cc019SAndroid Build Coastguard Worker static void check_error_state(const char *expected_ring_name,
134*d83cc019SAndroid Build Coastguard Worker uint64_t expected_offset,
135*d83cc019SAndroid Build Coastguard Worker const uint32_t *batch)
136*d83cc019SAndroid Build Coastguard Worker {
137*d83cc019SAndroid Build Coastguard Worker bool cmd_parser = uses_cmd_parser();
138*d83cc019SAndroid Build Coastguard Worker FILE *file = open_error();
139*d83cc019SAndroid Build Coastguard Worker char *line = NULL;
140*d83cc019SAndroid Build Coastguard Worker size_t line_size = 0;
141*d83cc019SAndroid Build Coastguard Worker bool found = false;
142*d83cc019SAndroid Build Coastguard Worker
143*d83cc019SAndroid Build Coastguard Worker igt_debug("%s(expected ring name=%s, expected offset=%"PRIx64")\n",
144*d83cc019SAndroid Build Coastguard Worker __func__, expected_ring_name, expected_offset);
145*d83cc019SAndroid Build Coastguard Worker igt_debugfs_dump(device, "i915_error_state");
146*d83cc019SAndroid Build Coastguard Worker
147*d83cc019SAndroid Build Coastguard Worker igt_assert(getline(&line, &line_size, file) != -1);
148*d83cc019SAndroid Build Coastguard Worker igt_assert(strcasecmp(line, "No error state collected"));
149*d83cc019SAndroid Build Coastguard Worker
150*d83cc019SAndroid Build Coastguard Worker while (getline(&line, &line_size, file) > 0) {
151*d83cc019SAndroid Build Coastguard Worker char *dashes;
152*d83cc019SAndroid Build Coastguard Worker uint32_t gtt_offset_upper, gtt_offset_lower;
153*d83cc019SAndroid Build Coastguard Worker int matched;
154*d83cc019SAndroid Build Coastguard Worker
155*d83cc019SAndroid Build Coastguard Worker dashes = strstr(line, "---");
156*d83cc019SAndroid Build Coastguard Worker if (!dashes)
157*d83cc019SAndroid Build Coastguard Worker continue;
158*d83cc019SAndroid Build Coastguard Worker
159*d83cc019SAndroid Build Coastguard Worker matched = sscanf(dashes, "--- gtt_offset = 0x%08x %08x\n",
160*d83cc019SAndroid Build Coastguard Worker >t_offset_upper, >t_offset_lower);
161*d83cc019SAndroid Build Coastguard Worker if (matched) {
162*d83cc019SAndroid Build Coastguard Worker char expected_line[128];
163*d83cc019SAndroid Build Coastguard Worker uint64_t gtt_offset;
164*d83cc019SAndroid Build Coastguard Worker int i;
165*d83cc019SAndroid Build Coastguard Worker
166*d83cc019SAndroid Build Coastguard Worker strncpy(expected_line, line, dashes - line);
167*d83cc019SAndroid Build Coastguard Worker expected_line[dashes - line - 1] = '\0';
168*d83cc019SAndroid Build Coastguard Worker igt_assert(strstr(expected_line, expected_ring_name));
169*d83cc019SAndroid Build Coastguard Worker
170*d83cc019SAndroid Build Coastguard Worker gtt_offset = gtt_offset_upper;
171*d83cc019SAndroid Build Coastguard Worker if (matched == 2) {
172*d83cc019SAndroid Build Coastguard Worker gtt_offset <<= 32;
173*d83cc019SAndroid Build Coastguard Worker gtt_offset |= gtt_offset_lower;
174*d83cc019SAndroid Build Coastguard Worker }
175*d83cc019SAndroid Build Coastguard Worker if (!cmd_parser)
176*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(gtt_offset, expected_offset);
177*d83cc019SAndroid Build Coastguard Worker
178*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 1024; i++) {
179*d83cc019SAndroid Build Coastguard Worker igt_assert(getline(&line, &line_size, file) > 0);
180*d83cc019SAndroid Build Coastguard Worker if (line[0] == ':' || line[0] == '~')
181*d83cc019SAndroid Build Coastguard Worker break;
182*d83cc019SAndroid Build Coastguard Worker
183*d83cc019SAndroid Build Coastguard Worker snprintf(expected_line, sizeof(expected_line),
184*d83cc019SAndroid Build Coastguard Worker "%08x : %08x",
185*d83cc019SAndroid Build Coastguard Worker 4*i, batch[i]);
186*d83cc019SAndroid Build Coastguard Worker igt_assert(strstr(line, expected_line));
187*d83cc019SAndroid Build Coastguard Worker }
188*d83cc019SAndroid Build Coastguard Worker
189*d83cc019SAndroid Build Coastguard Worker found = true;
190*d83cc019SAndroid Build Coastguard Worker break;
191*d83cc019SAndroid Build Coastguard Worker }
192*d83cc019SAndroid Build Coastguard Worker }
193*d83cc019SAndroid Build Coastguard Worker
194*d83cc019SAndroid Build Coastguard Worker free(line);
195*d83cc019SAndroid Build Coastguard Worker fclose(file);
196*d83cc019SAndroid Build Coastguard Worker
197*d83cc019SAndroid Build Coastguard Worker clear_error_state();
198*d83cc019SAndroid Build Coastguard Worker
199*d83cc019SAndroid Build Coastguard Worker igt_assert(found);
200*d83cc019SAndroid Build Coastguard Worker }
201*d83cc019SAndroid Build Coastguard Worker
test_error_state_capture(unsigned ring_id,const char * ring_name)202*d83cc019SAndroid Build Coastguard Worker static void test_error_state_capture(unsigned ring_id,
203*d83cc019SAndroid Build Coastguard Worker const char *ring_name)
204*d83cc019SAndroid Build Coastguard Worker {
205*d83cc019SAndroid Build Coastguard Worker uint32_t *batch;
206*d83cc019SAndroid Build Coastguard Worker igt_hang_t hang;
207*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
208*d83cc019SAndroid Build Coastguard Worker
209*d83cc019SAndroid Build Coastguard Worker clear_error_state();
210*d83cc019SAndroid Build Coastguard Worker
211*d83cc019SAndroid Build Coastguard Worker hang = igt_hang_ctx(device, 0, ring_id, HANG_ALLOW_CAPTURE);
212*d83cc019SAndroid Build Coastguard Worker offset = hang.spin->obj[IGT_SPIN_BATCH].offset;
213*d83cc019SAndroid Build Coastguard Worker
214*d83cc019SAndroid Build Coastguard Worker batch = gem_mmap__cpu(device, hang.spin->handle, 0, 4096, PROT_READ);
215*d83cc019SAndroid Build Coastguard Worker gem_set_domain(device, hang.spin->handle, I915_GEM_DOMAIN_CPU, 0);
216*d83cc019SAndroid Build Coastguard Worker
217*d83cc019SAndroid Build Coastguard Worker igt_post_hang_ring(device, hang);
218*d83cc019SAndroid Build Coastguard Worker
219*d83cc019SAndroid Build Coastguard Worker check_error_state(ring_name, offset, batch);
220*d83cc019SAndroid Build Coastguard Worker munmap(batch, 4096);
221*d83cc019SAndroid Build Coastguard Worker }
222*d83cc019SAndroid Build Coastguard Worker
223*d83cc019SAndroid Build Coastguard Worker /* This test covers the case where we end up in an uninitialised area of the
224*d83cc019SAndroid Build Coastguard Worker * ppgtt and keep executing through it. This is particularly relevant if 48b
225*d83cc019SAndroid Build Coastguard Worker * ppgtt is enabled because the ppgtt is massively bigger compared to the 32b
226*d83cc019SAndroid Build Coastguard Worker * case and it takes a lot more time to wrap, so the acthd can potentially keep
227*d83cc019SAndroid Build Coastguard Worker * increasing for a long time
228*d83cc019SAndroid Build Coastguard Worker */
hangcheck_unterminated(void)229*d83cc019SAndroid Build Coastguard Worker static void hangcheck_unterminated(void)
230*d83cc019SAndroid Build Coastguard Worker {
231*d83cc019SAndroid Build Coastguard Worker /* timeout needs to be greater than ~5*hangcheck */
232*d83cc019SAndroid Build Coastguard Worker int64_t timeout_ns = 100ull * NSEC_PER_SEC; /* 100 seconds */
233*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
234*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 gem_exec;
235*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
236*d83cc019SAndroid Build Coastguard Worker
237*d83cc019SAndroid Build Coastguard Worker igt_require(gem_uses_full_ppgtt(device));
238*d83cc019SAndroid Build Coastguard Worker igt_require_hang_ring(device, 0);
239*d83cc019SAndroid Build Coastguard Worker
240*d83cc019SAndroid Build Coastguard Worker handle = gem_create(device, 4096);
241*d83cc019SAndroid Build Coastguard Worker
242*d83cc019SAndroid Build Coastguard Worker memset(&gem_exec, 0, sizeof(gem_exec));
243*d83cc019SAndroid Build Coastguard Worker gem_exec.handle = handle;
244*d83cc019SAndroid Build Coastguard Worker
245*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
246*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = (uintptr_t)&gem_exec;
247*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
248*d83cc019SAndroid Build Coastguard Worker
249*d83cc019SAndroid Build Coastguard Worker gem_execbuf(device, &execbuf);
250*d83cc019SAndroid Build Coastguard Worker if (gem_wait(device, handle, &timeout_ns) != 0) {
251*d83cc019SAndroid Build Coastguard Worker /* need to manually trigger an hang to clean before failing */
252*d83cc019SAndroid Build Coastguard Worker igt_force_gpu_reset(device);
253*d83cc019SAndroid Build Coastguard Worker igt_assert_f(0, "unterminated batch did not trigger an hang!");
254*d83cc019SAndroid Build Coastguard Worker }
255*d83cc019SAndroid Build Coastguard Worker }
256*d83cc019SAndroid Build Coastguard Worker
257*d83cc019SAndroid Build Coastguard Worker igt_main
258*d83cc019SAndroid Build Coastguard Worker {
259*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine2 *e;
260*d83cc019SAndroid Build Coastguard Worker igt_hang_t hang = {};
261*d83cc019SAndroid Build Coastguard Worker
262*d83cc019SAndroid Build Coastguard Worker igt_skip_on_simulation();
263*d83cc019SAndroid Build Coastguard Worker
264*d83cc019SAndroid Build Coastguard Worker igt_fixture {
265*d83cc019SAndroid Build Coastguard Worker device = drm_open_driver(DRIVER_INTEL);
266*d83cc019SAndroid Build Coastguard Worker igt_require_gem(device);
267*d83cc019SAndroid Build Coastguard Worker
268*d83cc019SAndroid Build Coastguard Worker hang = igt_allow_hang(device, 0, HANG_ALLOW_CAPTURE);
269*d83cc019SAndroid Build Coastguard Worker
270*d83cc019SAndroid Build Coastguard Worker sysfs = igt_sysfs_open(device);
271*d83cc019SAndroid Build Coastguard Worker igt_assert(sysfs != -1);
272*d83cc019SAndroid Build Coastguard Worker
273*d83cc019SAndroid Build Coastguard Worker igt_require(has_error_state(sysfs));
274*d83cc019SAndroid Build Coastguard Worker }
275*d83cc019SAndroid Build Coastguard Worker
276*d83cc019SAndroid Build Coastguard Worker igt_subtest("error-state-basic")
277*d83cc019SAndroid Build Coastguard Worker test_error_state_basic();
278*d83cc019SAndroid Build Coastguard Worker
279*d83cc019SAndroid Build Coastguard Worker __for_each_physical_engine(device, e)
280*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("error-state-capture-%s", e->name)
281*d83cc019SAndroid Build Coastguard Worker test_error_state_capture(e->flags, e->name);
282*d83cc019SAndroid Build Coastguard Worker
283*d83cc019SAndroid Build Coastguard Worker igt_subtest("hangcheck-unterminated")
284*d83cc019SAndroid Build Coastguard Worker hangcheck_unterminated();
285*d83cc019SAndroid Build Coastguard Worker
286*d83cc019SAndroid Build Coastguard Worker igt_fixture {
287*d83cc019SAndroid Build Coastguard Worker igt_disallow_hang(device, hang);
288*d83cc019SAndroid Build Coastguard Worker }
289*d83cc019SAndroid Build Coastguard Worker }
290