1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright (c) 2013 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 *
26*d83cc019SAndroid Build Coastguard Worker */
27*d83cc019SAndroid Build Coastguard Worker
28*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
29*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
30*d83cc019SAndroid Build Coastguard Worker #include <limits.h>
31*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
32*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
33*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
34*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
35*d83cc019SAndroid Build Coastguard Worker #include <string.h>
36*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
37*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
38*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
39*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
40*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
41*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
42*d83cc019SAndroid Build Coastguard Worker #include <time.h>
43*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
44*d83cc019SAndroid Build Coastguard Worker
45*d83cc019SAndroid Build Coastguard Worker
46*d83cc019SAndroid Build Coastguard Worker #define RS_NO_ERROR 0
47*d83cc019SAndroid Build Coastguard Worker #define RS_BATCH_ACTIVE (1 << 0)
48*d83cc019SAndroid Build Coastguard Worker #define RS_BATCH_PENDING (1 << 1)
49*d83cc019SAndroid Build Coastguard Worker #define RS_UNKNOWN (1 << 2)
50*d83cc019SAndroid Build Coastguard Worker
51*d83cc019SAndroid Build Coastguard Worker
52*d83cc019SAndroid Build Coastguard Worker static uint32_t devid;
53*d83cc019SAndroid Build Coastguard Worker
54*d83cc019SAndroid Build Coastguard Worker struct local_drm_i915_reset_stats {
55*d83cc019SAndroid Build Coastguard Worker __u32 ctx_id;
56*d83cc019SAndroid Build Coastguard Worker __u32 flags;
57*d83cc019SAndroid Build Coastguard Worker __u32 reset_count;
58*d83cc019SAndroid Build Coastguard Worker __u32 batch_active;
59*d83cc019SAndroid Build Coastguard Worker __u32 batch_pending;
60*d83cc019SAndroid Build Coastguard Worker __u32 pad;
61*d83cc019SAndroid Build Coastguard Worker };
62*d83cc019SAndroid Build Coastguard Worker
63*d83cc019SAndroid Build Coastguard Worker #define MAX_FD 32
64*d83cc019SAndroid Build Coastguard Worker
65*d83cc019SAndroid Build Coastguard Worker #define GET_RESET_STATS_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x32, struct local_drm_i915_reset_stats)
66*d83cc019SAndroid Build Coastguard Worker
67*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_VEBOX (4 << 0)
68*d83cc019SAndroid Build Coastguard Worker
sync_gpu(void)69*d83cc019SAndroid Build Coastguard Worker static void sync_gpu(void)
70*d83cc019SAndroid Build Coastguard Worker {
71*d83cc019SAndroid Build Coastguard Worker int fd = drm_open_driver(DRIVER_INTEL);
72*d83cc019SAndroid Build Coastguard Worker gem_quiescent_gpu(fd);
73*d83cc019SAndroid Build Coastguard Worker close(fd);
74*d83cc019SAndroid Build Coastguard Worker }
75*d83cc019SAndroid Build Coastguard Worker
noop(int fd,uint32_t ctx,const struct intel_execution_engine * e)76*d83cc019SAndroid Build Coastguard Worker static int noop(int fd, uint32_t ctx, const struct intel_execution_engine *e)
77*d83cc019SAndroid Build Coastguard Worker {
78*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
79*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 eb;
80*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 exec;
81*d83cc019SAndroid Build Coastguard Worker int ret;
82*d83cc019SAndroid Build Coastguard Worker
83*d83cc019SAndroid Build Coastguard Worker memset(&exec, 0, sizeof(exec));
84*d83cc019SAndroid Build Coastguard Worker exec.handle = gem_create(fd, 4096);
85*d83cc019SAndroid Build Coastguard Worker igt_assert((int)exec.handle > 0);
86*d83cc019SAndroid Build Coastguard Worker gem_write(fd, exec.handle, 0, &bbe, sizeof(bbe));
87*d83cc019SAndroid Build Coastguard Worker
88*d83cc019SAndroid Build Coastguard Worker memset(&eb, 0, sizeof(eb));
89*d83cc019SAndroid Build Coastguard Worker eb.buffers_ptr = to_user_pointer(&exec);
90*d83cc019SAndroid Build Coastguard Worker eb.buffer_count = 1;
91*d83cc019SAndroid Build Coastguard Worker eb.flags = e->exec_id | e->flags;
92*d83cc019SAndroid Build Coastguard Worker i915_execbuffer2_set_context_id(eb, ctx);
93*d83cc019SAndroid Build Coastguard Worker
94*d83cc019SAndroid Build Coastguard Worker ret = __gem_execbuf(fd, &eb);
95*d83cc019SAndroid Build Coastguard Worker if (ret < 0) {
96*d83cc019SAndroid Build Coastguard Worker gem_close(fd, exec.handle);
97*d83cc019SAndroid Build Coastguard Worker return ret;
98*d83cc019SAndroid Build Coastguard Worker }
99*d83cc019SAndroid Build Coastguard Worker
100*d83cc019SAndroid Build Coastguard Worker return exec.handle;
101*d83cc019SAndroid Build Coastguard Worker }
102*d83cc019SAndroid Build Coastguard Worker
has_engine(int fd,uint32_t ctx,const struct intel_execution_engine * e)103*d83cc019SAndroid Build Coastguard Worker static int has_engine(int fd,
104*d83cc019SAndroid Build Coastguard Worker uint32_t ctx,
105*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine *e)
106*d83cc019SAndroid Build Coastguard Worker {
107*d83cc019SAndroid Build Coastguard Worker int handle = noop(fd, ctx, e);
108*d83cc019SAndroid Build Coastguard Worker if (handle < 0)
109*d83cc019SAndroid Build Coastguard Worker return 0;
110*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
111*d83cc019SAndroid Build Coastguard Worker return 1;
112*d83cc019SAndroid Build Coastguard Worker }
113*d83cc019SAndroid Build Coastguard Worker
check_context(const struct intel_execution_engine * e)114*d83cc019SAndroid Build Coastguard Worker static void check_context(const struct intel_execution_engine *e)
115*d83cc019SAndroid Build Coastguard Worker {
116*d83cc019SAndroid Build Coastguard Worker int fd = drm_open_driver(DRIVER_INTEL);
117*d83cc019SAndroid Build Coastguard Worker
118*d83cc019SAndroid Build Coastguard Worker gem_require_contexts(fd);
119*d83cc019SAndroid Build Coastguard Worker igt_require(has_engine(fd, gem_context_create(fd), e));
120*d83cc019SAndroid Build Coastguard Worker
121*d83cc019SAndroid Build Coastguard Worker close(fd);
122*d83cc019SAndroid Build Coastguard Worker }
123*d83cc019SAndroid Build Coastguard Worker
gem_reset_stats(int fd,int ctx_id,struct local_drm_i915_reset_stats * rs)124*d83cc019SAndroid Build Coastguard Worker static int gem_reset_stats(int fd, int ctx_id,
125*d83cc019SAndroid Build Coastguard Worker struct local_drm_i915_reset_stats *rs)
126*d83cc019SAndroid Build Coastguard Worker {
127*d83cc019SAndroid Build Coastguard Worker memset(rs, 0, sizeof(*rs));
128*d83cc019SAndroid Build Coastguard Worker rs->ctx_id = ctx_id;
129*d83cc019SAndroid Build Coastguard Worker rs->reset_count = -1;
130*d83cc019SAndroid Build Coastguard Worker
131*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(fd, GET_RESET_STATS_IOCTL, rs))
132*d83cc019SAndroid Build Coastguard Worker return -errno;
133*d83cc019SAndroid Build Coastguard Worker
134*d83cc019SAndroid Build Coastguard Worker igt_assert(rs->reset_count != -1);
135*d83cc019SAndroid Build Coastguard Worker return 0;
136*d83cc019SAndroid Build Coastguard Worker }
137*d83cc019SAndroid Build Coastguard Worker
gem_reset_status(int fd,int ctx_id)138*d83cc019SAndroid Build Coastguard Worker static int gem_reset_status(int fd, int ctx_id)
139*d83cc019SAndroid Build Coastguard Worker {
140*d83cc019SAndroid Build Coastguard Worker struct local_drm_i915_reset_stats rs;
141*d83cc019SAndroid Build Coastguard Worker int ret;
142*d83cc019SAndroid Build Coastguard Worker
143*d83cc019SAndroid Build Coastguard Worker ret = gem_reset_stats(fd, ctx_id, &rs);
144*d83cc019SAndroid Build Coastguard Worker if (ret)
145*d83cc019SAndroid Build Coastguard Worker return ret;
146*d83cc019SAndroid Build Coastguard Worker
147*d83cc019SAndroid Build Coastguard Worker if (rs.batch_active)
148*d83cc019SAndroid Build Coastguard Worker return RS_BATCH_ACTIVE;
149*d83cc019SAndroid Build Coastguard Worker if (rs.batch_pending)
150*d83cc019SAndroid Build Coastguard Worker return RS_BATCH_PENDING;
151*d83cc019SAndroid Build Coastguard Worker
152*d83cc019SAndroid Build Coastguard Worker return RS_NO_ERROR;
153*d83cc019SAndroid Build Coastguard Worker }
154*d83cc019SAndroid Build Coastguard Worker
155*d83cc019SAndroid Build Coastguard Worker static struct timespec ts_injected;
156*d83cc019SAndroid Build Coastguard Worker
157*d83cc019SAndroid Build Coastguard Worker #define BAN HANG_ALLOW_BAN
158*d83cc019SAndroid Build Coastguard Worker #define ASYNC 2
inject_hang(int fd,uint32_t ctx,const struct intel_execution_engine * e,unsigned flags)159*d83cc019SAndroid Build Coastguard Worker static void inject_hang(int fd, uint32_t ctx,
160*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine *e,
161*d83cc019SAndroid Build Coastguard Worker unsigned flags)
162*d83cc019SAndroid Build Coastguard Worker {
163*d83cc019SAndroid Build Coastguard Worker igt_hang_t hang;
164*d83cc019SAndroid Build Coastguard Worker
165*d83cc019SAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &ts_injected);
166*d83cc019SAndroid Build Coastguard Worker
167*d83cc019SAndroid Build Coastguard Worker hang = igt_hang_ctx(fd, ctx, e->exec_id | e->flags, flags & BAN);
168*d83cc019SAndroid Build Coastguard Worker if ((flags & ASYNC) == 0)
169*d83cc019SAndroid Build Coastguard Worker igt_post_hang_ring(fd, hang);
170*d83cc019SAndroid Build Coastguard Worker }
171*d83cc019SAndroid Build Coastguard Worker
status_to_string(int x)172*d83cc019SAndroid Build Coastguard Worker static const char *status_to_string(int x)
173*d83cc019SAndroid Build Coastguard Worker {
174*d83cc019SAndroid Build Coastguard Worker const char *strings[] = {
175*d83cc019SAndroid Build Coastguard Worker "No error",
176*d83cc019SAndroid Build Coastguard Worker "Guilty",
177*d83cc019SAndroid Build Coastguard Worker "Pending",
178*d83cc019SAndroid Build Coastguard Worker };
179*d83cc019SAndroid Build Coastguard Worker if (x >= ARRAY_SIZE(strings))
180*d83cc019SAndroid Build Coastguard Worker return "Unknown";
181*d83cc019SAndroid Build Coastguard Worker return strings[x];
182*d83cc019SAndroid Build Coastguard Worker }
183*d83cc019SAndroid Build Coastguard Worker
_assert_reset_status(int idx,int fd,int ctx,int status)184*d83cc019SAndroid Build Coastguard Worker static int _assert_reset_status(int idx, int fd, int ctx, int status)
185*d83cc019SAndroid Build Coastguard Worker {
186*d83cc019SAndroid Build Coastguard Worker int rs;
187*d83cc019SAndroid Build Coastguard Worker
188*d83cc019SAndroid Build Coastguard Worker rs = gem_reset_status(fd, ctx);
189*d83cc019SAndroid Build Coastguard Worker if (rs < 0) {
190*d83cc019SAndroid Build Coastguard Worker igt_info("reset status for %d ctx %d returned %d\n",
191*d83cc019SAndroid Build Coastguard Worker idx, ctx, rs);
192*d83cc019SAndroid Build Coastguard Worker return rs;
193*d83cc019SAndroid Build Coastguard Worker }
194*d83cc019SAndroid Build Coastguard Worker
195*d83cc019SAndroid Build Coastguard Worker if (rs != status) {
196*d83cc019SAndroid Build Coastguard Worker igt_info("%d:%d expected '%s' [%d], found '%s' [%d]\n",
197*d83cc019SAndroid Build Coastguard Worker idx, ctx,
198*d83cc019SAndroid Build Coastguard Worker status_to_string(status), status,
199*d83cc019SAndroid Build Coastguard Worker status_to_string(rs), rs);
200*d83cc019SAndroid Build Coastguard Worker
201*d83cc019SAndroid Build Coastguard Worker return 1;
202*d83cc019SAndroid Build Coastguard Worker }
203*d83cc019SAndroid Build Coastguard Worker
204*d83cc019SAndroid Build Coastguard Worker return 0;
205*d83cc019SAndroid Build Coastguard Worker }
206*d83cc019SAndroid Build Coastguard Worker
207*d83cc019SAndroid Build Coastguard Worker #define assert_reset_status(idx, fd, ctx, status) \
208*d83cc019SAndroid Build Coastguard Worker igt_assert(_assert_reset_status(idx, fd, ctx, status) == 0)
209*d83cc019SAndroid Build Coastguard Worker
test_rs(const struct intel_execution_engine * e,int num_fds,int hang_index,int rs_assumed_no_hang)210*d83cc019SAndroid Build Coastguard Worker static void test_rs(const struct intel_execution_engine *e,
211*d83cc019SAndroid Build Coastguard Worker int num_fds, int hang_index, int rs_assumed_no_hang)
212*d83cc019SAndroid Build Coastguard Worker {
213*d83cc019SAndroid Build Coastguard Worker int fd[MAX_FD];
214*d83cc019SAndroid Build Coastguard Worker int i;
215*d83cc019SAndroid Build Coastguard Worker
216*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(num_fds, MAX_FD);
217*d83cc019SAndroid Build Coastguard Worker igt_assert_lt(hang_index, MAX_FD);
218*d83cc019SAndroid Build Coastguard Worker
219*d83cc019SAndroid Build Coastguard Worker igt_debug("num fds=%d, hang index=%d\n", num_fds, hang_index);
220*d83cc019SAndroid Build Coastguard Worker
221*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
222*d83cc019SAndroid Build Coastguard Worker fd[i] = drm_open_driver(DRIVER_INTEL);
223*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
224*d83cc019SAndroid Build Coastguard Worker }
225*d83cc019SAndroid Build Coastguard Worker
226*d83cc019SAndroid Build Coastguard Worker sync_gpu();
227*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
228*d83cc019SAndroid Build Coastguard Worker if (i == hang_index)
229*d83cc019SAndroid Build Coastguard Worker inject_hang(fd[i], 0, e, ASYNC);
230*d83cc019SAndroid Build Coastguard Worker else
231*d83cc019SAndroid Build Coastguard Worker igt_assert(noop(fd[i], 0, e) > 0);
232*d83cc019SAndroid Build Coastguard Worker }
233*d83cc019SAndroid Build Coastguard Worker sync_gpu();
234*d83cc019SAndroid Build Coastguard Worker
235*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
236*d83cc019SAndroid Build Coastguard Worker if (hang_index < 0) {
237*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, rs_assumed_no_hang);
238*d83cc019SAndroid Build Coastguard Worker continue;
239*d83cc019SAndroid Build Coastguard Worker }
240*d83cc019SAndroid Build Coastguard Worker
241*d83cc019SAndroid Build Coastguard Worker if (i < hang_index)
242*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
243*d83cc019SAndroid Build Coastguard Worker if (i == hang_index)
244*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_BATCH_ACTIVE);
245*d83cc019SAndroid Build Coastguard Worker if (i > hang_index)
246*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
247*d83cc019SAndroid Build Coastguard Worker }
248*d83cc019SAndroid Build Coastguard Worker
249*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_seconds_elapsed(&ts_injected) <= 30);
250*d83cc019SAndroid Build Coastguard Worker
251*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++)
252*d83cc019SAndroid Build Coastguard Worker close(fd[i]);
253*d83cc019SAndroid Build Coastguard Worker }
254*d83cc019SAndroid Build Coastguard Worker
255*d83cc019SAndroid Build Coastguard Worker #define MAX_CTX 100
test_rs_ctx(const struct intel_execution_engine * e,int num_fds,int num_ctx,int hang_index,int hang_context)256*d83cc019SAndroid Build Coastguard Worker static void test_rs_ctx(const struct intel_execution_engine *e,
257*d83cc019SAndroid Build Coastguard Worker int num_fds, int num_ctx, int hang_index,
258*d83cc019SAndroid Build Coastguard Worker int hang_context)
259*d83cc019SAndroid Build Coastguard Worker {
260*d83cc019SAndroid Build Coastguard Worker int i, j;
261*d83cc019SAndroid Build Coastguard Worker int fd[MAX_FD];
262*d83cc019SAndroid Build Coastguard Worker int ctx[MAX_FD][MAX_CTX];
263*d83cc019SAndroid Build Coastguard Worker
264*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(num_fds, MAX_FD);
265*d83cc019SAndroid Build Coastguard Worker igt_assert_lt(hang_index, MAX_FD);
266*d83cc019SAndroid Build Coastguard Worker
267*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(num_ctx, MAX_CTX);
268*d83cc019SAndroid Build Coastguard Worker igt_assert_lt(hang_context, MAX_CTX);
269*d83cc019SAndroid Build Coastguard Worker
270*d83cc019SAndroid Build Coastguard Worker test_rs(e, num_fds, -1, RS_NO_ERROR);
271*d83cc019SAndroid Build Coastguard Worker
272*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
273*d83cc019SAndroid Build Coastguard Worker fd[i] = drm_open_driver(DRIVER_INTEL);
274*d83cc019SAndroid Build Coastguard Worker igt_assert(fd[i]);
275*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
276*d83cc019SAndroid Build Coastguard Worker
277*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < num_ctx; j++) {
278*d83cc019SAndroid Build Coastguard Worker ctx[i][j] = gem_context_create(fd[i]);
279*d83cc019SAndroid Build Coastguard Worker }
280*d83cc019SAndroid Build Coastguard Worker
281*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
282*d83cc019SAndroid Build Coastguard Worker }
283*d83cc019SAndroid Build Coastguard Worker
284*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
285*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
286*d83cc019SAndroid Build Coastguard Worker
287*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < num_ctx; j++)
288*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], ctx[i][j], RS_NO_ERROR);
289*d83cc019SAndroid Build Coastguard Worker
290*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
291*d83cc019SAndroid Build Coastguard Worker }
292*d83cc019SAndroid Build Coastguard Worker
293*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
294*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < num_ctx; j++) {
295*d83cc019SAndroid Build Coastguard Worker if (i == hang_index && j == hang_context)
296*d83cc019SAndroid Build Coastguard Worker inject_hang(fd[i], ctx[i][j], e, ASYNC);
297*d83cc019SAndroid Build Coastguard Worker else
298*d83cc019SAndroid Build Coastguard Worker igt_assert(noop(fd[i], ctx[i][j], e) > 0);
299*d83cc019SAndroid Build Coastguard Worker }
300*d83cc019SAndroid Build Coastguard Worker }
301*d83cc019SAndroid Build Coastguard Worker sync_gpu();
302*d83cc019SAndroid Build Coastguard Worker
303*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_seconds_elapsed(&ts_injected) <= 30);
304*d83cc019SAndroid Build Coastguard Worker
305*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++)
306*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
307*d83cc019SAndroid Build Coastguard Worker
308*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
309*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < num_ctx; j++) {
310*d83cc019SAndroid Build Coastguard Worker if (i < hang_index)
311*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], ctx[i][j], RS_NO_ERROR);
312*d83cc019SAndroid Build Coastguard Worker if (i == hang_index && j < hang_context)
313*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], ctx[i][j], RS_NO_ERROR);
314*d83cc019SAndroid Build Coastguard Worker if (i == hang_index && j == hang_context)
315*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], ctx[i][j],
316*d83cc019SAndroid Build Coastguard Worker RS_BATCH_ACTIVE);
317*d83cc019SAndroid Build Coastguard Worker if (i == hang_index && j > hang_context)
318*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], ctx[i][j],
319*d83cc019SAndroid Build Coastguard Worker RS_NO_ERROR);
320*d83cc019SAndroid Build Coastguard Worker if (i > hang_index)
321*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], ctx[i][j],
322*d83cc019SAndroid Build Coastguard Worker RS_NO_ERROR);
323*d83cc019SAndroid Build Coastguard Worker }
324*d83cc019SAndroid Build Coastguard Worker }
325*d83cc019SAndroid Build Coastguard Worker
326*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < num_fds; i++) {
327*d83cc019SAndroid Build Coastguard Worker assert_reset_status(i, fd[i], 0, RS_NO_ERROR);
328*d83cc019SAndroid Build Coastguard Worker close(fd[i]);
329*d83cc019SAndroid Build Coastguard Worker }
330*d83cc019SAndroid Build Coastguard Worker }
331*d83cc019SAndroid Build Coastguard Worker
test_ban(const struct intel_execution_engine * e)332*d83cc019SAndroid Build Coastguard Worker static void test_ban(const struct intel_execution_engine *e)
333*d83cc019SAndroid Build Coastguard Worker {
334*d83cc019SAndroid Build Coastguard Worker struct local_drm_i915_reset_stats rs_bad, rs_good;
335*d83cc019SAndroid Build Coastguard Worker int fd_bad, fd_good;
336*d83cc019SAndroid Build Coastguard Worker int ban, retry = 10;
337*d83cc019SAndroid Build Coastguard Worker int active_count = 0;
338*d83cc019SAndroid Build Coastguard Worker
339*d83cc019SAndroid Build Coastguard Worker fd_bad = drm_open_driver(DRIVER_INTEL);
340*d83cc019SAndroid Build Coastguard Worker fd_good = drm_open_driver(DRIVER_INTEL);
341*d83cc019SAndroid Build Coastguard Worker
342*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd_bad, fd_bad, 0, RS_NO_ERROR);
343*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd_good, fd_good, 0, RS_NO_ERROR);
344*d83cc019SAndroid Build Coastguard Worker
345*d83cc019SAndroid Build Coastguard Worker noop(fd_bad, 0, e);
346*d83cc019SAndroid Build Coastguard Worker noop(fd_good, 0, e);
347*d83cc019SAndroid Build Coastguard Worker
348*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd_bad, fd_bad, 0, RS_NO_ERROR);
349*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd_good, fd_good, 0, RS_NO_ERROR);
350*d83cc019SAndroid Build Coastguard Worker
351*d83cc019SAndroid Build Coastguard Worker inject_hang(fd_bad, 0, e, BAN | ASYNC);
352*d83cc019SAndroid Build Coastguard Worker active_count++;
353*d83cc019SAndroid Build Coastguard Worker
354*d83cc019SAndroid Build Coastguard Worker noop(fd_good, 0, e);
355*d83cc019SAndroid Build Coastguard Worker noop(fd_good, 0, e);
356*d83cc019SAndroid Build Coastguard Worker
357*d83cc019SAndroid Build Coastguard Worker while (retry--) {
358*d83cc019SAndroid Build Coastguard Worker inject_hang(fd_bad, 0, e, BAN);
359*d83cc019SAndroid Build Coastguard Worker active_count++;
360*d83cc019SAndroid Build Coastguard Worker
361*d83cc019SAndroid Build Coastguard Worker ban = noop(fd_bad, 0, e);
362*d83cc019SAndroid Build Coastguard Worker if (ban == -EIO)
363*d83cc019SAndroid Build Coastguard Worker break;
364*d83cc019SAndroid Build Coastguard Worker
365*d83cc019SAndroid Build Coastguard Worker /* Should not happen often but sometimes hang is declared too
366*d83cc019SAndroid Build Coastguard Worker * slow due to our way of faking hang using loop */
367*d83cc019SAndroid Build Coastguard Worker gem_close(fd_bad, ban);
368*d83cc019SAndroid Build Coastguard Worker
369*d83cc019SAndroid Build Coastguard Worker igt_info("retrying for ban (%d)\n", retry);
370*d83cc019SAndroid Build Coastguard Worker }
371*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ban, -EIO);
372*d83cc019SAndroid Build Coastguard Worker igt_assert_lt(0, noop(fd_good, 0, e));
373*d83cc019SAndroid Build Coastguard Worker
374*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd_bad, fd_bad, 0, RS_BATCH_ACTIVE);
375*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(gem_reset_stats(fd_bad, 0, &rs_bad), 0);
376*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(rs_bad.batch_active, active_count);
377*d83cc019SAndroid Build Coastguard Worker
378*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd_good, fd_good, 0, RS_NO_ERROR);
379*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(gem_reset_stats(fd_good, 0, &rs_good), 0);
380*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(rs_good.batch_active, 0);
381*d83cc019SAndroid Build Coastguard Worker
382*d83cc019SAndroid Build Coastguard Worker close(fd_bad);
383*d83cc019SAndroid Build Coastguard Worker close(fd_good);
384*d83cc019SAndroid Build Coastguard Worker }
385*d83cc019SAndroid Build Coastguard Worker
test_ban_ctx(const struct intel_execution_engine * e)386*d83cc019SAndroid Build Coastguard Worker static void test_ban_ctx(const struct intel_execution_engine *e)
387*d83cc019SAndroid Build Coastguard Worker {
388*d83cc019SAndroid Build Coastguard Worker struct local_drm_i915_reset_stats rs_bad, rs_good;
389*d83cc019SAndroid Build Coastguard Worker int fd, ban, retry = 10;
390*d83cc019SAndroid Build Coastguard Worker uint32_t ctx_good, ctx_bad;
391*d83cc019SAndroid Build Coastguard Worker int active_count = 0;
392*d83cc019SAndroid Build Coastguard Worker
393*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
394*d83cc019SAndroid Build Coastguard Worker
395*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, 0, RS_NO_ERROR);
396*d83cc019SAndroid Build Coastguard Worker
397*d83cc019SAndroid Build Coastguard Worker ctx_good = gem_context_create(fd);
398*d83cc019SAndroid Build Coastguard Worker ctx_bad = gem_context_create(fd);
399*d83cc019SAndroid Build Coastguard Worker
400*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, 0, RS_NO_ERROR);
401*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx_good, RS_NO_ERROR);
402*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx_bad, RS_NO_ERROR);
403*d83cc019SAndroid Build Coastguard Worker
404*d83cc019SAndroid Build Coastguard Worker noop(fd, ctx_bad, e);
405*d83cc019SAndroid Build Coastguard Worker noop(fd, ctx_good, e);
406*d83cc019SAndroid Build Coastguard Worker
407*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx_good, RS_NO_ERROR);
408*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx_bad, RS_NO_ERROR);
409*d83cc019SAndroid Build Coastguard Worker
410*d83cc019SAndroid Build Coastguard Worker inject_hang(fd, ctx_bad, e, BAN | ASYNC);
411*d83cc019SAndroid Build Coastguard Worker active_count++;
412*d83cc019SAndroid Build Coastguard Worker
413*d83cc019SAndroid Build Coastguard Worker noop(fd, ctx_good, e);
414*d83cc019SAndroid Build Coastguard Worker noop(fd, ctx_good, e);
415*d83cc019SAndroid Build Coastguard Worker
416*d83cc019SAndroid Build Coastguard Worker while (retry--) {
417*d83cc019SAndroid Build Coastguard Worker inject_hang(fd, ctx_bad, e, BAN);
418*d83cc019SAndroid Build Coastguard Worker active_count++;
419*d83cc019SAndroid Build Coastguard Worker
420*d83cc019SAndroid Build Coastguard Worker ban = noop(fd, ctx_bad, e);
421*d83cc019SAndroid Build Coastguard Worker if (ban == -EIO)
422*d83cc019SAndroid Build Coastguard Worker break;
423*d83cc019SAndroid Build Coastguard Worker
424*d83cc019SAndroid Build Coastguard Worker /* Should not happen often but sometimes hang is declared too
425*d83cc019SAndroid Build Coastguard Worker * slow due to our way of faking hang using loop */
426*d83cc019SAndroid Build Coastguard Worker gem_close(fd, ban);
427*d83cc019SAndroid Build Coastguard Worker
428*d83cc019SAndroid Build Coastguard Worker igt_info("retrying for ban (%d)\n", retry);
429*d83cc019SAndroid Build Coastguard Worker }
430*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ban, -EIO);
431*d83cc019SAndroid Build Coastguard Worker igt_assert_lt(0, noop(fd, ctx_good, e));
432*d83cc019SAndroid Build Coastguard Worker
433*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx_bad, RS_BATCH_ACTIVE);
434*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(gem_reset_stats(fd, ctx_bad, &rs_bad), 0);
435*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(rs_bad.batch_active, active_count);
436*d83cc019SAndroid Build Coastguard Worker
437*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx_good, RS_NO_ERROR);
438*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(gem_reset_stats(fd, ctx_good, &rs_good), 0);
439*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(rs_good.batch_active, 0);
440*d83cc019SAndroid Build Coastguard Worker
441*d83cc019SAndroid Build Coastguard Worker close(fd);
442*d83cc019SAndroid Build Coastguard Worker }
443*d83cc019SAndroid Build Coastguard Worker
test_unrelated_ctx(const struct intel_execution_engine * e)444*d83cc019SAndroid Build Coastguard Worker static void test_unrelated_ctx(const struct intel_execution_engine *e)
445*d83cc019SAndroid Build Coastguard Worker {
446*d83cc019SAndroid Build Coastguard Worker int fd1,fd2;
447*d83cc019SAndroid Build Coastguard Worker int ctx_guilty, ctx_unrelated;
448*d83cc019SAndroid Build Coastguard Worker
449*d83cc019SAndroid Build Coastguard Worker fd1 = drm_open_driver(DRIVER_INTEL);
450*d83cc019SAndroid Build Coastguard Worker fd2 = drm_open_driver(DRIVER_INTEL);
451*d83cc019SAndroid Build Coastguard Worker assert_reset_status(0, fd1, 0, RS_NO_ERROR);
452*d83cc019SAndroid Build Coastguard Worker assert_reset_status(1, fd2, 0, RS_NO_ERROR);
453*d83cc019SAndroid Build Coastguard Worker ctx_guilty = gem_context_create(fd1);
454*d83cc019SAndroid Build Coastguard Worker ctx_unrelated = gem_context_create(fd2);
455*d83cc019SAndroid Build Coastguard Worker
456*d83cc019SAndroid Build Coastguard Worker assert_reset_status(0, fd1, ctx_guilty, RS_NO_ERROR);
457*d83cc019SAndroid Build Coastguard Worker assert_reset_status(1, fd2, ctx_unrelated, RS_NO_ERROR);
458*d83cc019SAndroid Build Coastguard Worker
459*d83cc019SAndroid Build Coastguard Worker inject_hang(fd1, ctx_guilty, e, 0);
460*d83cc019SAndroid Build Coastguard Worker assert_reset_status(0, fd1, ctx_guilty, RS_BATCH_ACTIVE);
461*d83cc019SAndroid Build Coastguard Worker assert_reset_status(1, fd2, ctx_unrelated, RS_NO_ERROR);
462*d83cc019SAndroid Build Coastguard Worker
463*d83cc019SAndroid Build Coastguard Worker gem_sync(fd2, noop(fd2, ctx_unrelated, e));
464*d83cc019SAndroid Build Coastguard Worker assert_reset_status(0, fd1, ctx_guilty, RS_BATCH_ACTIVE);
465*d83cc019SAndroid Build Coastguard Worker assert_reset_status(1, fd2, ctx_unrelated, RS_NO_ERROR);
466*d83cc019SAndroid Build Coastguard Worker
467*d83cc019SAndroid Build Coastguard Worker close(fd1);
468*d83cc019SAndroid Build Coastguard Worker close(fd2);
469*d83cc019SAndroid Build Coastguard Worker }
470*d83cc019SAndroid Build Coastguard Worker
get_reset_count(int fd,int ctx)471*d83cc019SAndroid Build Coastguard Worker static int get_reset_count(int fd, int ctx)
472*d83cc019SAndroid Build Coastguard Worker {
473*d83cc019SAndroid Build Coastguard Worker int ret;
474*d83cc019SAndroid Build Coastguard Worker struct local_drm_i915_reset_stats rs;
475*d83cc019SAndroid Build Coastguard Worker
476*d83cc019SAndroid Build Coastguard Worker ret = gem_reset_stats(fd, ctx, &rs);
477*d83cc019SAndroid Build Coastguard Worker if (ret)
478*d83cc019SAndroid Build Coastguard Worker return ret;
479*d83cc019SAndroid Build Coastguard Worker
480*d83cc019SAndroid Build Coastguard Worker return rs.reset_count;
481*d83cc019SAndroid Build Coastguard Worker }
482*d83cc019SAndroid Build Coastguard Worker
test_close_pending_ctx(const struct intel_execution_engine * e)483*d83cc019SAndroid Build Coastguard Worker static void test_close_pending_ctx(const struct intel_execution_engine *e)
484*d83cc019SAndroid Build Coastguard Worker {
485*d83cc019SAndroid Build Coastguard Worker int fd = drm_open_driver(DRIVER_INTEL);
486*d83cc019SAndroid Build Coastguard Worker uint32_t ctx = gem_context_create(fd);
487*d83cc019SAndroid Build Coastguard Worker
488*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx, RS_NO_ERROR);
489*d83cc019SAndroid Build Coastguard Worker
490*d83cc019SAndroid Build Coastguard Worker inject_hang(fd, ctx, e, 0);
491*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, ctx);
492*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_destroy(fd, ctx), -ENOENT);
493*d83cc019SAndroid Build Coastguard Worker
494*d83cc019SAndroid Build Coastguard Worker close(fd);
495*d83cc019SAndroid Build Coastguard Worker }
496*d83cc019SAndroid Build Coastguard Worker
test_close_pending(const struct intel_execution_engine * e)497*d83cc019SAndroid Build Coastguard Worker static void test_close_pending(const struct intel_execution_engine *e)
498*d83cc019SAndroid Build Coastguard Worker {
499*d83cc019SAndroid Build Coastguard Worker int fd = drm_open_driver(DRIVER_INTEL);
500*d83cc019SAndroid Build Coastguard Worker
501*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, 0, RS_NO_ERROR);
502*d83cc019SAndroid Build Coastguard Worker
503*d83cc019SAndroid Build Coastguard Worker inject_hang(fd, 0, e, 0);
504*d83cc019SAndroid Build Coastguard Worker close(fd);
505*d83cc019SAndroid Build Coastguard Worker }
506*d83cc019SAndroid Build Coastguard Worker
noop_on_each_ring(int fd,const bool reverse)507*d83cc019SAndroid Build Coastguard Worker static void noop_on_each_ring(int fd, const bool reverse)
508*d83cc019SAndroid Build Coastguard Worker {
509*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
510*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 eb;
511*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj;
512*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine *e;
513*d83cc019SAndroid Build Coastguard Worker
514*d83cc019SAndroid Build Coastguard Worker memset(&obj, 0, sizeof(obj));
515*d83cc019SAndroid Build Coastguard Worker obj.handle = gem_create(fd, 4096);
516*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
517*d83cc019SAndroid Build Coastguard Worker
518*d83cc019SAndroid Build Coastguard Worker memset(&eb, 0, sizeof(eb));
519*d83cc019SAndroid Build Coastguard Worker eb.buffers_ptr = to_user_pointer(&obj);
520*d83cc019SAndroid Build Coastguard Worker eb.buffer_count = 1;
521*d83cc019SAndroid Build Coastguard Worker
522*d83cc019SAndroid Build Coastguard Worker if (reverse) {
523*d83cc019SAndroid Build Coastguard Worker for (e = intel_execution_engines; e->name; e++)
524*d83cc019SAndroid Build Coastguard Worker ;
525*d83cc019SAndroid Build Coastguard Worker while (--e >= intel_execution_engines) {
526*d83cc019SAndroid Build Coastguard Worker eb.flags = e->exec_id | e->flags;
527*d83cc019SAndroid Build Coastguard Worker __gem_execbuf(fd, &eb);
528*d83cc019SAndroid Build Coastguard Worker }
529*d83cc019SAndroid Build Coastguard Worker } else {
530*d83cc019SAndroid Build Coastguard Worker for (e = intel_execution_engines; e->name; e++) {
531*d83cc019SAndroid Build Coastguard Worker eb.flags = e->exec_id | e->flags;
532*d83cc019SAndroid Build Coastguard Worker __gem_execbuf(fd, &eb);
533*d83cc019SAndroid Build Coastguard Worker }
534*d83cc019SAndroid Build Coastguard Worker }
535*d83cc019SAndroid Build Coastguard Worker
536*d83cc019SAndroid Build Coastguard Worker gem_sync(fd, obj.handle);
537*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj.handle);
538*d83cc019SAndroid Build Coastguard Worker }
539*d83cc019SAndroid Build Coastguard Worker
test_close_pending_fork(const struct intel_execution_engine * e,const bool reverse)540*d83cc019SAndroid Build Coastguard Worker static void test_close_pending_fork(const struct intel_execution_engine *e,
541*d83cc019SAndroid Build Coastguard Worker const bool reverse)
542*d83cc019SAndroid Build Coastguard Worker {
543*d83cc019SAndroid Build Coastguard Worker int fd = drm_open_driver(DRIVER_INTEL);
544*d83cc019SAndroid Build Coastguard Worker igt_hang_t hang;
545*d83cc019SAndroid Build Coastguard Worker int pid;
546*d83cc019SAndroid Build Coastguard Worker
547*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, 0, RS_NO_ERROR);
548*d83cc019SAndroid Build Coastguard Worker
549*d83cc019SAndroid Build Coastguard Worker hang = igt_hang_ctx(fd, 0, e->exec_id | e->flags, 0);
550*d83cc019SAndroid Build Coastguard Worker sleep(1);
551*d83cc019SAndroid Build Coastguard Worker
552*d83cc019SAndroid Build Coastguard Worker /* Avoid helpers as we need to kill the child
553*d83cc019SAndroid Build Coastguard Worker * without any extra signal handling on behalf of
554*d83cc019SAndroid Build Coastguard Worker * lib/drmtest.c
555*d83cc019SAndroid Build Coastguard Worker */
556*d83cc019SAndroid Build Coastguard Worker pid = fork();
557*d83cc019SAndroid Build Coastguard Worker if (pid == 0) {
558*d83cc019SAndroid Build Coastguard Worker const int fd2 = drm_open_driver(DRIVER_INTEL);
559*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(0, fd2);
560*d83cc019SAndroid Build Coastguard Worker
561*d83cc019SAndroid Build Coastguard Worker /* The crucial component is that we schedule the same noop batch
562*d83cc019SAndroid Build Coastguard Worker * on each ring. This exercises batch_obj reference counting,
563*d83cc019SAndroid Build Coastguard Worker * when gpu is reset and ring lists are cleared.
564*d83cc019SAndroid Build Coastguard Worker */
565*d83cc019SAndroid Build Coastguard Worker noop_on_each_ring(fd2, reverse);
566*d83cc019SAndroid Build Coastguard Worker close(fd2);
567*d83cc019SAndroid Build Coastguard Worker pause();
568*d83cc019SAndroid Build Coastguard Worker exit(0);
569*d83cc019SAndroid Build Coastguard Worker } else {
570*d83cc019SAndroid Build Coastguard Worker igt_assert_lt(0, pid);
571*d83cc019SAndroid Build Coastguard Worker sleep(1);
572*d83cc019SAndroid Build Coastguard Worker
573*d83cc019SAndroid Build Coastguard Worker /* Kill the child to reduce refcounts on
574*d83cc019SAndroid Build Coastguard Worker batch_objs */
575*d83cc019SAndroid Build Coastguard Worker kill(pid, SIGKILL);
576*d83cc019SAndroid Build Coastguard Worker }
577*d83cc019SAndroid Build Coastguard Worker
578*d83cc019SAndroid Build Coastguard Worker igt_post_hang_ring(fd, hang);
579*d83cc019SAndroid Build Coastguard Worker close(fd);
580*d83cc019SAndroid Build Coastguard Worker }
581*d83cc019SAndroid Build Coastguard Worker
test_reset_count(const struct intel_execution_engine * e,const bool create_ctx)582*d83cc019SAndroid Build Coastguard Worker static void test_reset_count(const struct intel_execution_engine *e,
583*d83cc019SAndroid Build Coastguard Worker const bool create_ctx)
584*d83cc019SAndroid Build Coastguard Worker {
585*d83cc019SAndroid Build Coastguard Worker int fd = drm_open_driver(DRIVER_INTEL);
586*d83cc019SAndroid Build Coastguard Worker int ctx;
587*d83cc019SAndroid Build Coastguard Worker long c1, c2;
588*d83cc019SAndroid Build Coastguard Worker
589*d83cc019SAndroid Build Coastguard Worker if (create_ctx)
590*d83cc019SAndroid Build Coastguard Worker ctx = gem_context_create(fd);
591*d83cc019SAndroid Build Coastguard Worker else
592*d83cc019SAndroid Build Coastguard Worker ctx = 0;
593*d83cc019SAndroid Build Coastguard Worker
594*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx, RS_NO_ERROR);
595*d83cc019SAndroid Build Coastguard Worker
596*d83cc019SAndroid Build Coastguard Worker c1 = get_reset_count(fd, ctx);
597*d83cc019SAndroid Build Coastguard Worker igt_assert(c1 >= 0);
598*d83cc019SAndroid Build Coastguard Worker
599*d83cc019SAndroid Build Coastguard Worker inject_hang(fd, ctx, e, 0);
600*d83cc019SAndroid Build Coastguard Worker
601*d83cc019SAndroid Build Coastguard Worker assert_reset_status(fd, fd, ctx, RS_BATCH_ACTIVE);
602*d83cc019SAndroid Build Coastguard Worker c2 = get_reset_count(fd, ctx);
603*d83cc019SAndroid Build Coastguard Worker igt_assert(c2 >= 0);
604*d83cc019SAndroid Build Coastguard Worker igt_assert(c2 == (c1 + 1));
605*d83cc019SAndroid Build Coastguard Worker
606*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 1) {
607*d83cc019SAndroid Build Coastguard Worker igt_drop_root();
608*d83cc019SAndroid Build Coastguard Worker
609*d83cc019SAndroid Build Coastguard Worker c2 = get_reset_count(fd, ctx);
610*d83cc019SAndroid Build Coastguard Worker
611*d83cc019SAndroid Build Coastguard Worker igt_assert(c2 == 0);
612*d83cc019SAndroid Build Coastguard Worker }
613*d83cc019SAndroid Build Coastguard Worker
614*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
615*d83cc019SAndroid Build Coastguard Worker
616*d83cc019SAndroid Build Coastguard Worker if (create_ctx)
617*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, ctx);
618*d83cc019SAndroid Build Coastguard Worker
619*d83cc019SAndroid Build Coastguard Worker close(fd);
620*d83cc019SAndroid Build Coastguard Worker }
621*d83cc019SAndroid Build Coastguard Worker
_test_params(int fd,int ctx,uint32_t flags,uint32_t pad)622*d83cc019SAndroid Build Coastguard Worker static int _test_params(int fd, int ctx, uint32_t flags, uint32_t pad)
623*d83cc019SAndroid Build Coastguard Worker {
624*d83cc019SAndroid Build Coastguard Worker struct local_drm_i915_reset_stats rs;
625*d83cc019SAndroid Build Coastguard Worker
626*d83cc019SAndroid Build Coastguard Worker memset(&rs, 0, sizeof(rs));
627*d83cc019SAndroid Build Coastguard Worker rs.ctx_id = ctx;
628*d83cc019SAndroid Build Coastguard Worker rs.flags = flags;
629*d83cc019SAndroid Build Coastguard Worker rs.reset_count = rand();
630*d83cc019SAndroid Build Coastguard Worker rs.batch_active = rand();
631*d83cc019SAndroid Build Coastguard Worker rs.batch_pending = rand();
632*d83cc019SAndroid Build Coastguard Worker rs.pad = pad;
633*d83cc019SAndroid Build Coastguard Worker
634*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(fd, GET_RESET_STATS_IOCTL, &rs))
635*d83cc019SAndroid Build Coastguard Worker return -errno;
636*d83cc019SAndroid Build Coastguard Worker
637*d83cc019SAndroid Build Coastguard Worker return 0;
638*d83cc019SAndroid Build Coastguard Worker }
639*d83cc019SAndroid Build Coastguard Worker
640*d83cc019SAndroid Build Coastguard Worker typedef enum { root = 0, user } cap_t;
641*d83cc019SAndroid Build Coastguard Worker
_check_param_ctx(const int fd,const int ctx,const cap_t cap)642*d83cc019SAndroid Build Coastguard Worker static void _check_param_ctx(const int fd, const int ctx, const cap_t cap)
643*d83cc019SAndroid Build Coastguard Worker {
644*d83cc019SAndroid Build Coastguard Worker const uint32_t bad = rand() + 1;
645*d83cc019SAndroid Build Coastguard Worker
646*d83cc019SAndroid Build Coastguard Worker if (ctx == 0) {
647*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(_test_params(fd, ctx, 0, 0), 0);
648*d83cc019SAndroid Build Coastguard Worker
649*d83cc019SAndroid Build Coastguard Worker if (cap != root) {
650*d83cc019SAndroid Build Coastguard Worker igt_assert(get_reset_count(fd, ctx) == 0);
651*d83cc019SAndroid Build Coastguard Worker }
652*d83cc019SAndroid Build Coastguard Worker }
653*d83cc019SAndroid Build Coastguard Worker
654*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(_test_params(fd, ctx, 0, bad), -EINVAL);
655*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(_test_params(fd, ctx, bad, 0), -EINVAL);
656*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(_test_params(fd, ctx, bad, bad), -EINVAL);
657*d83cc019SAndroid Build Coastguard Worker }
658*d83cc019SAndroid Build Coastguard Worker
check_params(const int fd,const int ctx,cap_t cap)659*d83cc019SAndroid Build Coastguard Worker static void check_params(const int fd, const int ctx, cap_t cap)
660*d83cc019SAndroid Build Coastguard Worker {
661*d83cc019SAndroid Build Coastguard Worker igt_assert(ioctl(fd, GET_RESET_STATS_IOCTL, 0) == -1);
662*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(_test_params(fd, 0xbadbad, 0, 0), -ENOENT);
663*d83cc019SAndroid Build Coastguard Worker
664*d83cc019SAndroid Build Coastguard Worker _check_param_ctx(fd, ctx, cap);
665*d83cc019SAndroid Build Coastguard Worker }
666*d83cc019SAndroid Build Coastguard Worker
_test_param(const int fd,const int ctx)667*d83cc019SAndroid Build Coastguard Worker static void _test_param(const int fd, const int ctx)
668*d83cc019SAndroid Build Coastguard Worker {
669*d83cc019SAndroid Build Coastguard Worker check_params(fd, ctx, root);
670*d83cc019SAndroid Build Coastguard Worker
671*d83cc019SAndroid Build Coastguard Worker igt_fork(child, 1) {
672*d83cc019SAndroid Build Coastguard Worker check_params(fd, ctx, root);
673*d83cc019SAndroid Build Coastguard Worker
674*d83cc019SAndroid Build Coastguard Worker igt_drop_root();
675*d83cc019SAndroid Build Coastguard Worker
676*d83cc019SAndroid Build Coastguard Worker check_params(fd, ctx, user);
677*d83cc019SAndroid Build Coastguard Worker }
678*d83cc019SAndroid Build Coastguard Worker
679*d83cc019SAndroid Build Coastguard Worker check_params(fd, ctx, root);
680*d83cc019SAndroid Build Coastguard Worker
681*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
682*d83cc019SAndroid Build Coastguard Worker }
683*d83cc019SAndroid Build Coastguard Worker
test_params_ctx(void)684*d83cc019SAndroid Build Coastguard Worker static void test_params_ctx(void)
685*d83cc019SAndroid Build Coastguard Worker {
686*d83cc019SAndroid Build Coastguard Worker int fd;
687*d83cc019SAndroid Build Coastguard Worker
688*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
689*d83cc019SAndroid Build Coastguard Worker _test_param(fd, gem_context_create(fd));
690*d83cc019SAndroid Build Coastguard Worker close(fd);
691*d83cc019SAndroid Build Coastguard Worker }
692*d83cc019SAndroid Build Coastguard Worker
test_params(void)693*d83cc019SAndroid Build Coastguard Worker static void test_params(void)
694*d83cc019SAndroid Build Coastguard Worker {
695*d83cc019SAndroid Build Coastguard Worker int fd;
696*d83cc019SAndroid Build Coastguard Worker
697*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
698*d83cc019SAndroid Build Coastguard Worker _test_param(fd, 0);
699*d83cc019SAndroid Build Coastguard Worker close(fd);
700*d83cc019SAndroid Build Coastguard Worker }
701*d83cc019SAndroid Build Coastguard Worker
702*d83cc019SAndroid Build Coastguard Worker static const struct intel_execution_engine *
next_engine(int fd,const struct intel_execution_engine * e)703*d83cc019SAndroid Build Coastguard Worker next_engine(int fd, const struct intel_execution_engine *e)
704*d83cc019SAndroid Build Coastguard Worker {
705*d83cc019SAndroid Build Coastguard Worker do {
706*d83cc019SAndroid Build Coastguard Worker e++;
707*d83cc019SAndroid Build Coastguard Worker if (e->name == NULL)
708*d83cc019SAndroid Build Coastguard Worker e = intel_execution_engines;
709*d83cc019SAndroid Build Coastguard Worker if (e->exec_id == 0)
710*d83cc019SAndroid Build Coastguard Worker e++;
711*d83cc019SAndroid Build Coastguard Worker } while (!has_engine(fd, 0, e));
712*d83cc019SAndroid Build Coastguard Worker
713*d83cc019SAndroid Build Coastguard Worker return e;
714*d83cc019SAndroid Build Coastguard Worker }
715*d83cc019SAndroid Build Coastguard Worker
defer_hangcheck(const struct intel_execution_engine * engine)716*d83cc019SAndroid Build Coastguard Worker static void defer_hangcheck(const struct intel_execution_engine *engine)
717*d83cc019SAndroid Build Coastguard Worker {
718*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine *next;
719*d83cc019SAndroid Build Coastguard Worker int fd, count_start, count_end;
720*d83cc019SAndroid Build Coastguard Worker int seconds = 30;
721*d83cc019SAndroid Build Coastguard Worker
722*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
723*d83cc019SAndroid Build Coastguard Worker
724*d83cc019SAndroid Build Coastguard Worker next = next_engine(fd, engine);
725*d83cc019SAndroid Build Coastguard Worker igt_skip_on(next == engine);
726*d83cc019SAndroid Build Coastguard Worker
727*d83cc019SAndroid Build Coastguard Worker count_start = get_reset_count(fd, 0);
728*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(0, count_start);
729*d83cc019SAndroid Build Coastguard Worker
730*d83cc019SAndroid Build Coastguard Worker inject_hang(fd, 0, engine, 0);
731*d83cc019SAndroid Build Coastguard Worker while (--seconds) {
732*d83cc019SAndroid Build Coastguard Worker noop(fd, 0, next);
733*d83cc019SAndroid Build Coastguard Worker
734*d83cc019SAndroid Build Coastguard Worker count_end = get_reset_count(fd, 0);
735*d83cc019SAndroid Build Coastguard Worker igt_assert_lte(0, count_end);
736*d83cc019SAndroid Build Coastguard Worker
737*d83cc019SAndroid Build Coastguard Worker if (count_end > count_start)
738*d83cc019SAndroid Build Coastguard Worker break;
739*d83cc019SAndroid Build Coastguard Worker
740*d83cc019SAndroid Build Coastguard Worker sleep(1);
741*d83cc019SAndroid Build Coastguard Worker }
742*d83cc019SAndroid Build Coastguard Worker
743*d83cc019SAndroid Build Coastguard Worker igt_assert_lt(count_start, count_end);
744*d83cc019SAndroid Build Coastguard Worker
745*d83cc019SAndroid Build Coastguard Worker close(fd);
746*d83cc019SAndroid Build Coastguard Worker }
747*d83cc019SAndroid Build Coastguard Worker
gem_has_reset_stats(int fd)748*d83cc019SAndroid Build Coastguard Worker static bool gem_has_reset_stats(int fd)
749*d83cc019SAndroid Build Coastguard Worker {
750*d83cc019SAndroid Build Coastguard Worker struct local_drm_i915_reset_stats rs;
751*d83cc019SAndroid Build Coastguard Worker int ret;
752*d83cc019SAndroid Build Coastguard Worker
753*d83cc019SAndroid Build Coastguard Worker /* Carefully set flags and pad to zero, otherwise
754*d83cc019SAndroid Build Coastguard Worker we get -EINVAL
755*d83cc019SAndroid Build Coastguard Worker */
756*d83cc019SAndroid Build Coastguard Worker memset(&rs, 0, sizeof(rs));
757*d83cc019SAndroid Build Coastguard Worker
758*d83cc019SAndroid Build Coastguard Worker ret = drmIoctl(fd, GET_RESET_STATS_IOCTL, &rs);
759*d83cc019SAndroid Build Coastguard Worker if (ret == 0)
760*d83cc019SAndroid Build Coastguard Worker return true;
761*d83cc019SAndroid Build Coastguard Worker
762*d83cc019SAndroid Build Coastguard Worker /* If we get EPERM, we have support but did not
763*d83cc019SAndroid Build Coastguard Worker have CAP_SYSADM */
764*d83cc019SAndroid Build Coastguard Worker if (ret == -1 && errno == EPERM)
765*d83cc019SAndroid Build Coastguard Worker return true;
766*d83cc019SAndroid Build Coastguard Worker
767*d83cc019SAndroid Build Coastguard Worker return false;
768*d83cc019SAndroid Build Coastguard Worker }
769*d83cc019SAndroid Build Coastguard Worker
770*d83cc019SAndroid Build Coastguard Worker #define RUN_TEST(...) do { sync_gpu(); __VA_ARGS__; sync_gpu(); } while (0)
771*d83cc019SAndroid Build Coastguard Worker #define RUN_CTX_TEST(...) do { check_context(e); RUN_TEST(__VA_ARGS__); } while (0)
772*d83cc019SAndroid Build Coastguard Worker
773*d83cc019SAndroid Build Coastguard Worker igt_main
774*d83cc019SAndroid Build Coastguard Worker {
775*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine *e;
776*d83cc019SAndroid Build Coastguard Worker igt_skip_on_simulation();
777*d83cc019SAndroid Build Coastguard Worker
778*d83cc019SAndroid Build Coastguard Worker igt_fixture {
779*d83cc019SAndroid Build Coastguard Worker int fd;
780*d83cc019SAndroid Build Coastguard Worker
781*d83cc019SAndroid Build Coastguard Worker bool has_reset_stats;
782*d83cc019SAndroid Build Coastguard Worker bool using_full_reset;
783*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
784*d83cc019SAndroid Build Coastguard Worker devid = intel_get_drm_devid(fd);
785*d83cc019SAndroid Build Coastguard Worker
786*d83cc019SAndroid Build Coastguard Worker has_reset_stats = gem_has_reset_stats(fd);
787*d83cc019SAndroid Build Coastguard Worker
788*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_sysfs_set_parameter
789*d83cc019SAndroid Build Coastguard Worker (fd, "reset", "%d", 1 /* only global reset */));
790*d83cc019SAndroid Build Coastguard Worker
791*d83cc019SAndroid Build Coastguard Worker using_full_reset = !gem_engine_reset_enabled(fd) &&
792*d83cc019SAndroid Build Coastguard Worker gem_gpu_reset_enabled(fd);
793*d83cc019SAndroid Build Coastguard Worker
794*d83cc019SAndroid Build Coastguard Worker close(fd);
795*d83cc019SAndroid Build Coastguard Worker
796*d83cc019SAndroid Build Coastguard Worker igt_require_f(has_reset_stats,
797*d83cc019SAndroid Build Coastguard Worker "No reset stats ioctl support. Too old kernel?\n");
798*d83cc019SAndroid Build Coastguard Worker igt_require_f(using_full_reset,
799*d83cc019SAndroid Build Coastguard Worker "Full GPU reset is not enabled. Is enable_hangcheck set?\n");
800*d83cc019SAndroid Build Coastguard Worker }
801*d83cc019SAndroid Build Coastguard Worker
802*d83cc019SAndroid Build Coastguard Worker igt_subtest("params")
803*d83cc019SAndroid Build Coastguard Worker test_params();
804*d83cc019SAndroid Build Coastguard Worker
805*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("params-ctx")
806*d83cc019SAndroid Build Coastguard Worker RUN_TEST(test_params_ctx());
807*d83cc019SAndroid Build Coastguard Worker
808*d83cc019SAndroid Build Coastguard Worker for (e = intel_execution_engines; e->name; e++) {
809*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("reset-stats-%s", e->name)
810*d83cc019SAndroid Build Coastguard Worker RUN_TEST(test_rs(e, 4, 1, 0));
811*d83cc019SAndroid Build Coastguard Worker
812*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("reset-stats-ctx-%s", e->name)
813*d83cc019SAndroid Build Coastguard Worker RUN_CTX_TEST(test_rs_ctx(e, 4, 4, 1, 2));
814*d83cc019SAndroid Build Coastguard Worker
815*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("ban-%s", e->name)
816*d83cc019SAndroid Build Coastguard Worker RUN_TEST(test_ban(e));
817*d83cc019SAndroid Build Coastguard Worker
818*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("ban-ctx-%s", e->name)
819*d83cc019SAndroid Build Coastguard Worker RUN_CTX_TEST(test_ban_ctx(e));
820*d83cc019SAndroid Build Coastguard Worker
821*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("reset-count-%s", e->name)
822*d83cc019SAndroid Build Coastguard Worker RUN_TEST(test_reset_count(e, false));
823*d83cc019SAndroid Build Coastguard Worker
824*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("reset-count-ctx-%s", e->name)
825*d83cc019SAndroid Build Coastguard Worker RUN_CTX_TEST(test_reset_count(e, true));
826*d83cc019SAndroid Build Coastguard Worker
827*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("unrelated-ctx-%s", e->name)
828*d83cc019SAndroid Build Coastguard Worker RUN_CTX_TEST(test_unrelated_ctx(e));
829*d83cc019SAndroid Build Coastguard Worker
830*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("close-pending-%s", e->name)
831*d83cc019SAndroid Build Coastguard Worker RUN_TEST(test_close_pending(e));
832*d83cc019SAndroid Build Coastguard Worker
833*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("close-pending-ctx-%s", e->name)
834*d83cc019SAndroid Build Coastguard Worker RUN_CTX_TEST(test_close_pending_ctx(e));
835*d83cc019SAndroid Build Coastguard Worker
836*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("close-pending-fork-%s", e->name)
837*d83cc019SAndroid Build Coastguard Worker RUN_TEST(test_close_pending_fork(e, false));
838*d83cc019SAndroid Build Coastguard Worker
839*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("close-pending-fork-reverse-%s", e->name)
840*d83cc019SAndroid Build Coastguard Worker RUN_TEST(test_close_pending_fork(e, true));
841*d83cc019SAndroid Build Coastguard Worker
842*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("defer-hangcheck-%s", e->name)
843*d83cc019SAndroid Build Coastguard Worker RUN_TEST(defer_hangcheck(e));
844*d83cc019SAndroid Build Coastguard Worker }
845*d83cc019SAndroid Build Coastguard Worker
846*d83cc019SAndroid Build Coastguard Worker igt_fixture {
847*d83cc019SAndroid Build Coastguard Worker int fd;
848*d83cc019SAndroid Build Coastguard Worker
849*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
850*d83cc019SAndroid Build Coastguard Worker igt_assert(igt_sysfs_set_parameter
851*d83cc019SAndroid Build Coastguard Worker (fd, "reset", "%d", INT_MAX /* any reset method */));
852*d83cc019SAndroid Build Coastguard Worker close(fd);
853*d83cc019SAndroid Build Coastguard Worker }
854*d83cc019SAndroid Build Coastguard Worker }
855