xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_wait.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1 /*
2  * Copyright © 2012 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  *    Ben Widawsky <[email protected]>
25  *
26  */
27 
28 #include "igt.h"
29 #include "igt_vgem.h"
30 
__gem_wait(int fd,struct drm_i915_gem_wait * w)31 static int __gem_wait(int fd, struct drm_i915_gem_wait *w)
32 {
33 	int err;
34 
35 	err = 0;
36 	if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_WAIT, w))
37 		err = -errno;
38 
39 	return err;
40 }
41 
invalid_flags(int fd)42 static void invalid_flags(int fd)
43 {
44 	struct drm_i915_gem_wait wait;
45 
46 	memset(&wait, 0, sizeof(wait));
47 	wait.bo_handle = gem_create(fd, 4096);
48 	wait.timeout_ns = 1;
49 	/* NOTE: This test intentionally tests for just the next available flag.
50 	 * Don't "fix" this testcase without the ABI testcases for new flags
51 	 * first. */
52 	wait.flags = 1;
53 
54 	igt_assert_eq(__gem_wait(fd, &wait), -EINVAL);
55 
56 	gem_close(fd, wait.bo_handle);
57 }
58 
invalid_buf(int fd)59 static void invalid_buf(int fd)
60 {
61 	struct drm_i915_gem_wait wait;
62 
63 	memset(&wait, 0, sizeof(wait));
64 	igt_assert_eq(__gem_wait(fd, &wait), -ENOENT);
65 }
66 
67 #define BUSY 1
68 #define HANG 2
69 #define AWAIT 4
70 #define WRITE 8
71 
basic(int fd,unsigned engine,unsigned flags)72 static void basic(int fd, unsigned engine, unsigned flags)
73 {
74 	IGT_CORK_HANDLE(cork);
75 	uint32_t plug =
76 		flags & (WRITE | AWAIT) ? igt_cork_plug(&cork, fd) : 0;
77 	igt_spin_t *spin = igt_spin_new(fd,
78 					.engine = engine,
79 					.dependency = plug);
80 	struct drm_i915_gem_wait wait = {
81 		flags & WRITE ? plug : spin->handle
82 	};
83 
84 	igt_assert_eq(__gem_wait(fd, &wait), -ETIME);
85 
86 	if (flags & BUSY) {
87 		struct timespec tv = {};
88 		int timeout;
89 
90 		timeout = 120;
91 		if ((flags & HANG) == 0) {
92 			igt_spin_set_timeout(spin, NSEC_PER_SEC/2);
93 			timeout = 1;
94 		}
95 
96 		if (flags & (WRITE | AWAIT))
97 			igt_cork_unplug(&cork);
98 
99 		igt_assert_eq(__gem_wait(fd, &wait), -ETIME);
100 
101 		while (__gem_wait(fd, &wait) == -ETIME)
102 			igt_assert(igt_seconds_elapsed(&tv) < timeout);
103 	} else {
104 		wait.timeout_ns = NSEC_PER_SEC / 2; /* 0.5s */
105 		igt_assert_eq(__gem_wait(fd, &wait), -ETIME);
106 		igt_assert_eq_s64(wait.timeout_ns, 0);
107 
108 		if (flags & (WRITE | AWAIT))
109 			igt_cork_unplug(&cork);
110 
111 		wait.timeout_ns = 0;
112 		igt_assert_eq(__gem_wait(fd, &wait), -ETIME);
113 
114 		if ((flags & HANG) == 0) {
115 			igt_spin_set_timeout(spin, NSEC_PER_SEC/2);
116 			wait.timeout_ns = NSEC_PER_SEC; /* 1.0s */
117 			igt_assert_eq(__gem_wait(fd, &wait), 0);
118 			igt_assert(wait.timeout_ns >= 0);
119 		} else {
120 			wait.timeout_ns = -1;
121 			igt_assert_eq(__gem_wait(fd, &wait), 0);
122 			igt_assert(wait.timeout_ns == -1);
123 		}
124 
125 		wait.timeout_ns = 0;
126 		igt_assert_eq(__gem_wait(fd, &wait), 0);
127 		igt_assert(wait.timeout_ns == 0);
128 	}
129 
130 	if (plug)
131 		gem_close(fd, plug);
132 	igt_spin_free(fd, spin);
133 }
134 
135 igt_main
136 {
137 	const struct intel_execution_engine2 *e;
138 	int fd = -1;
139 
140 	igt_skip_on_simulation();
141 
142 	igt_fixture {
143 		fd = drm_open_driver_master(DRIVER_INTEL);
144 		igt_require_gem(fd);
145 	}
146 
147 	igt_subtest("invalid-flags")
148 		invalid_flags(fd);
149 
150 	igt_subtest("invalid-buf")
151 		invalid_buf(fd);
152 
153 	igt_subtest_group {
154 		igt_fixture {
155 			igt_fork_hang_detector(fd);
156 			igt_fork_signal_helper();
157 		}
158 
159 		igt_subtest("basic-busy-all") {
160 			gem_quiescent_gpu(fd);
161 			basic(fd, ALL_ENGINES, BUSY);
162 		}
163 		igt_subtest("basic-wait-all") {
164 			gem_quiescent_gpu(fd);
165 			basic(fd, ALL_ENGINES, 0);
166 		}
167 		igt_subtest("basic-await-all") {
168 			gem_quiescent_gpu(fd);
169 			basic(fd, ALL_ENGINES, AWAIT);
170 		}
171 		igt_subtest("basic-busy-write-all") {
172 			gem_quiescent_gpu(fd);
173 			basic(fd, ALL_ENGINES, BUSY | WRITE);
174 		}
175 		igt_subtest("basic-wait-write-all") {
176 			gem_quiescent_gpu(fd);
177 			basic(fd, ALL_ENGINES, WRITE);
178 		}
179 
__for_each_physical_engine(fd,e)180 		__for_each_physical_engine(fd, e) {
181 			igt_subtest_group {
182 				igt_subtest_f("busy-%s", e->name) {
183 					gem_quiescent_gpu(fd);
184 					basic(fd, e->flags, BUSY);
185 				}
186 				igt_subtest_f("wait-%s", e->name) {
187 					gem_quiescent_gpu(fd);
188 					basic(fd, e->flags, 0);
189 				}
190 				igt_subtest_f("await-%s", e->name) {
191 					gem_quiescent_gpu(fd);
192 					basic(fd, e->flags, AWAIT);
193 				}
194 				igt_subtest_f("write-busy-%s", e->name) {
195 					gem_quiescent_gpu(fd);
196 					basic(fd, e->flags, BUSY | WRITE);
197 				}
198 				igt_subtest_f("write-wait-%s", e->name) {
199 					gem_quiescent_gpu(fd);
200 					basic(fd, e->flags, WRITE);
201 				}
202 			}
203 		}
204 
205 		igt_fixture {
206 			igt_stop_signal_helper();
207 			igt_stop_hang_detector();
208 		}
209 	}
210 
211 	igt_subtest_group {
212 		igt_hang_t hang;
213 
214 		igt_fixture {
215 			hang = igt_allow_hang(fd, 0, 0);
216 			igt_fork_signal_helper();
217 		}
218 
219 		igt_subtest("hang-busy-all") {
220 			gem_quiescent_gpu(fd);
221 			basic(fd, ALL_ENGINES, BUSY | HANG);
222 		}
223 		igt_subtest("hang-wait-all") {
224 			gem_quiescent_gpu(fd);
225 			basic(fd, ALL_ENGINES, HANG);
226 		}
227 
228 		igt_subtest("hang-busy-write-all") {
229 			gem_quiescent_gpu(fd);
230 			basic(fd, ALL_ENGINES, BUSY | WRITE | HANG);
231 		}
232 		igt_subtest("hang-wait-write-all") {
233 			gem_quiescent_gpu(fd);
234 			basic(fd, ALL_ENGINES, WRITE | HANG);
235 		}
236 
__for_each_physical_engine(fd,e)237 		__for_each_physical_engine(fd, e) {
238 			igt_subtest_f("hang-busy-%s", e->name) {
239 				gem_quiescent_gpu(fd);
240 				basic(fd, e->flags, HANG | BUSY);
241 			}
242 			igt_subtest_f("hang-wait-%s", e->name) {
243 				gem_quiescent_gpu(fd);
244 				basic(fd, e->flags, HANG);
245 			}
246 			igt_subtest_f("hang-busy-write-%s", e->name) {
247 				gem_quiescent_gpu(fd);
248 				basic(fd, e->flags, HANG | WRITE | BUSY);
249 			}
250 			igt_subtest_f("hang-wait-write-%s", e->name) {
251 				gem_quiescent_gpu(fd);
252 				basic(fd, e->flags, HANG | WRITE);
253 			}
254 		}
255 
256 		igt_fixture {
257 			igt_stop_signal_helper();
258 			igt_disallow_hang(fd, hang);
259 		}
260 	}
261 
262 	igt_fixture {
263 		close(fd);
264 	}
265 }
266