blob: 688ad1b87994fac5c1fe26add7c5a3db8805068f [file] [log] [blame]
Daniel Vetterf5daeec2014-03-23 13:35:09 +01001/*
David Weinehall7890b092015-02-11 16:46:02 +02002 * Copyright © 2014, 2015 Intel Corporation
Daniel Vetterf5daeec2014-03-23 13:35:09 +01003 *
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 * Daniel Vetter <daniel.vetter@ffwll.ch>
25 *
26 */
27
28#ifndef IGT_AUX_H
29#define IGT_AUX_H
30
31#include <intel_bufmgr.h>
Thomas Woodd96490a2014-06-16 16:21:35 +010032#include <stdbool.h>
Lyuded57ae362016-11-21 13:43:36 -050033#include <stddef.h>
Paulo Zanoni9bb04d32014-12-03 16:12:49 -020034#include <sys/time.h>
Daniel Vetterf5daeec2014-03-23 13:35:09 +010035
Imre Deakb35b1502014-11-13 13:33:54 +020036extern drm_intel_bo **trash_bos;
37extern int num_trash_bos;
38
Abdiel Janulgued529a572016-11-16 21:38:20 +020039/* signal interrupt helpers */
40
41#define MSEC_PER_SEC (1000)
42#define USEC_PER_SEC (1000*MSEC_PER_SEC)
43#define NSEC_PER_SEC (1000*USEC_PER_SEC)
44
45/* signal interrupt helpers */
Arkadiusz Hiler86b59f82017-04-12 09:28:45 +020046#ifdef ANDROID
47#include <unistd.h> /* on Android bionic has this implemented */
48#else
Abdiel Janulgued529a572016-11-16 21:38:20 +020049#define gettid() syscall(__NR_gettid)
Arkadiusz Hiler86b59f82017-04-12 09:28:45 +020050#endif
51
Abdiel Janulgued529a572016-11-16 21:38:20 +020052#define sigev_notify_thread_id _sigev_un._tid
53
Daniel Vetterf5daeec2014-03-23 13:35:09 +010054/* auxialiary igt helpers from igt_aux.c */
55/* generally useful helpers */
56void igt_fork_signal_helper(void);
57void igt_stop_signal_helper(void);
Imre Deak40d6f192017-10-13 14:30:08 +030058void igt_suspend_signal_helper(void);
59void igt_resume_signal_helper(void);
Chris Wilsona3154762014-09-06 08:16:27 +010060
Chris Wilson83884e92017-03-21 17:16:03 +000061void igt_fork_shrink_helper(int fd);
Chris Wilsone8eb9af2017-03-08 13:09:00 +000062void igt_stop_shrink_helper(void);
63
Chris Wilson756f3e02016-03-22 11:33:41 +000064void igt_fork_hang_detector(int fd);
65void igt_stop_hang_detector(void);
66
Daniel Vetterd7050f92016-05-11 17:06:28 +020067struct __igt_sigiter {
Chris Wilsond5456102016-03-19 13:04:02 +000068 unsigned pass;
69};
70
Daniel Vetterd7050f92016-05-11 17:06:28 +020071bool __igt_sigiter_continue(struct __igt_sigiter *iter, bool interrupt);
72
73/**
74 * igt_while_interruptible:
75 * @enable: enable igt_ioctl interrupting or not
76 *
77 * Provides control flow such that all drmIoctl() (strictly igt_ioctl())
78 * within the loop are forcibly injected with signals (SIGRTMIN).
79 *
80 * This is useful to exercise ioctl error paths, at least where those can be
81 * exercises by interrupting blocking waits, like stalling for the gpu.
82 *
83 * The code block attached to this macro is run in a loop with doubling the
84 * interrupt timeout on each ioctl for every run, until no ioctl gets
85 * interrupted any more. The starting timeout is taken to be the signal delivery
86 * latency, measured at runtime. This way the any ioctls called from this code
87 * block should be exhaustively tested for all signal interruption paths.
88 *
89 * Note that since this overloads the igt_ioctl(), this method is not useful
90 * for widespread signal injection, for example providing coverage of
91 * pagefaults. To interrupt everything, see igt_fork_signal_helper().
92 */
93#define igt_while_interruptible(enable) \
94 for (struct __igt_sigiter iter__={}; __igt_sigiter_continue(&iter__, (enable)); )
Chris Wilsond5456102016-03-19 13:04:02 +000095
Daniel Vetter88648202016-05-11 17:07:26 +020096/**
97 * igt_until_timeout:
98 * @timeout: timeout in seconds
99 *
100 * Convenience macro loop to run the provided code block in a loop until the
101 * timeout has expired. Of course when an individual execution takes too long,
102 * the actual execution time could be a lot longer.
103 *
104 * The code block will be executed at least once.
105 */
106#define igt_until_timeout(timeout) \
107 for (struct timespec t__={}; igt_seconds_elapsed(&t__) < (timeout); )
Chris Wilsonf650aa22016-04-20 18:35:37 +0100108
Chris Wilson12f052b2016-08-01 12:58:13 +0100109/**
110 * igt_for_milliseconds:
111 * @time: how long to run the loop in milliseconds
112 *
113 * Convenience macro loop to run the provided code block in a loop until the
114 * target interval has expired. Of course when an individual execution takes
115 * too long, the actual execution time could be a lot longer.
116 *
117 * The code block will be executed at least once.
118 */
119#define igt_for_milliseconds(t) \
120 for (struct timespec t__={}; igt_nsec_elapsed(&t__)>>20 < (t); )
121
Daniel Vetterf5daeec2014-03-23 13:35:09 +0100122void igt_exchange_int(void *array, unsigned i, unsigned j);
123void igt_permute_array(void *array, unsigned size,
124 void (*exchange_func)(void *array,
125 unsigned i,
126 unsigned j));
127void igt_progress(const char *header, uint64_t i, uint64_t total);
Thomas Wood6a8d33c2014-09-30 17:05:39 +0100128void igt_print_activity(void);
Daniel Vetter8221fda2014-03-23 14:38:17 +0100129bool igt_check_boolean_env_var(const char *env_var, bool default_value);
Daniel Vetterf5daeec2014-03-23 13:35:09 +0100130
131bool igt_aub_dump_enabled(void);
132
133/* helpers based upon the libdrm buffer manager */
134void igt_init_aperture_trashers(drm_intel_bufmgr *bufmgr);
135void igt_trash_aperture(void);
136void igt_cleanup_aperture_trashers(void);
137
David Weinehall7890b092015-02-11 16:46:02 +0200138/* suspend/hibernate and auto-resume system */
Imre Deak022e6f82016-09-30 17:28:53 +0300139
Imre Deakf7fe18a2016-10-14 17:51:14 +0300140/**
141 * igt_suspend_state:
142 * @SUSPEND_STATE_FREEZE: suspend-to-idle target state, aka S0ix or freeze,
143 * first non-hibernation state
144 * @SUSPEND_STATE_STANDBY: standby target state, aka S1, second
145 * non-hibernation state
146 * @SUSPEND_STATE_MEM: suspend-to-mem target state aka S3, third
147 * non-hibernation state
148 * @SUSPEND_STATE_DISK: suspend-to-disk target state, aka S4 or hibernation
149 *
150 * Target suspend states used with igt_system_suspend_autoresume().
151 * See /sys/power/state for the available states on a given machine.
152 */
Imre Deak022e6f82016-09-30 17:28:53 +0300153enum igt_suspend_state {
154 SUSPEND_STATE_FREEZE,
Imre Deak022e6f82016-09-30 17:28:53 +0300155 SUSPEND_STATE_STANDBY,
Imre Deakf7fe18a2016-10-14 17:51:14 +0300156 SUSPEND_STATE_MEM,
Imre Deak022e6f82016-09-30 17:28:53 +0300157 SUSPEND_STATE_DISK,
158
Imre Deakf7fe18a2016-10-14 17:51:14 +0300159 /*< private >*/
Imre Deak022e6f82016-09-30 17:28:53 +0300160 SUSPEND_STATE_NUM,
161};
162
Imre Deakf7fe18a2016-10-14 17:51:14 +0300163/**
164 * igt_suspend_test:
165 * @SUSPEND_TEST_NONE: no testing, perform a full suspend/resume cycle
166 * @SUSPEND_TEST_FREEZER: complete cycle after freezing all freezable threads
167 * @SUSPEND_TEST_DEVICES: complete cycle after the above step and suspending
168 * devices (before calling the drivers' suspend late and
169 * no_irq hooks). Platform and system devices are not
170 * suspended here, see #SUSPEND_TEST_CORE.
171 * @SUSPEND_TEST_PLATFORM: complete cycle after all the above steps and calling
172 * the ACPI platform global control methods (applies
173 * only with /sys/power/disk set to platform)
174 * @SUSPEND_TEST_PROCESSORS: complete cycle after all the above steps and
175 * disabling non-boot CPUs
176 * @SUSPEND_TEST_CORE: complete cycle after all the above steps and suspending
177 * platform and system devices
178 *
179 * Test points used with igt_system_suspend_autoresume(). Specifies if and where
180 * the suspend sequence is to be terminated.
181 */
Imre Deak022e6f82016-09-30 17:28:53 +0300182enum igt_suspend_test {
183 SUSPEND_TEST_NONE,
184 SUSPEND_TEST_FREEZER,
185 SUSPEND_TEST_DEVICES,
186 SUSPEND_TEST_PLATFORM,
187 SUSPEND_TEST_PROCESSORS,
188 SUSPEND_TEST_CORE,
189
Imre Deakf7fe18a2016-10-14 17:51:14 +0300190 /*< private >*/
Imre Deak022e6f82016-09-30 17:28:53 +0300191 SUSPEND_TEST_NUM,
192};
193
194void igt_system_suspend_autoresume(enum igt_suspend_state state,
195 enum igt_suspend_test test);
Lyudec2ddb812016-11-04 16:27:12 -0400196void igt_set_autoresume_delay(int delay_secs);
Paul Kocialkowskiebd6eb62017-07-04 16:33:19 +0300197int igt_get_autoresume_delay(enum igt_suspend_state state);
Daniel Vetterf5daeec2014-03-23 13:35:09 +0100198
199/* dropping priviledges */
200void igt_drop_root(void);
201
Rodrigo Vivi3d65ff72015-01-12 10:21:58 -0800202void igt_debug_wait_for_keypress(const char *var);
Rodrigo Viviae9c6852014-12-09 20:44:11 -0500203void igt_debug_manual_check(const char *var, const char *expected);
Daniel Vetterf5daeec2014-03-23 13:35:09 +0100204
205/* sysinfo cross-arch wrappers from intel_os.c */
206
207/* These are separate to allow easier testing when porting, see the comment at
208 * the bottom of intel_os.c. */
Chris Wilson83884e92017-03-21 17:16:03 +0000209void intel_purge_vm_caches(int fd);
Chris Wilsone8869c42014-04-03 09:43:58 +0100210uint64_t intel_get_avail_ram_mb(void);
Daniel Vetterf5daeec2014-03-23 13:35:09 +0100211uint64_t intel_get_total_ram_mb(void);
212uint64_t intel_get_total_swap_mb(void);
213
Chris Wilson4a3a8262016-01-13 14:02:50 +0000214int __intel_check_memory(uint64_t count, uint64_t size, unsigned mode,
Chris Wilson42291f22016-01-07 11:19:26 +0000215 uint64_t *out_required, uint64_t *out_total);
Chris Wilson4a3a8262016-01-13 14:02:50 +0000216void intel_require_memory(uint64_t count, uint64_t size, unsigned mode);
Chris Wilsone85613b2016-03-19 14:01:38 +0000217void intel_require_files(uint64_t count);
Chris Wilson321273f2014-05-28 09:01:56 +0100218#define CHECK_RAM 0x1
219#define CHECK_SWAP 0x2
220
Damien Lespiau390653a2015-06-30 00:15:15 +0100221#define min(a, b) ({ \
222 typeof(a) _a = (a); \
223 typeof(b) _b = (b); \
224 _a < _b ? _a : _b; \
225})
226#define max(a, b) ({ \
227 typeof(a) _a = (a); \
228 typeof(b) _b = (b); \
229 _a > _b ? _a : _b; \
230})
Thomas Woodbe4710a2014-10-10 11:20:35 +0100231
Daniel Vetter2eca38e2015-02-07 12:37:48 +0100232#define igt_swap(a, b) do { \
Ville Syrjälä1658edc2014-11-28 10:03:38 +0200233 typeof(a) _tmp = (a); \
234 (a) = (b); \
235 (b) = _tmp; \
236} while (0)
237
Thomas Wood42b02c22014-12-08 11:12:51 +0000238void igt_lock_mem(size_t size);
239void igt_unlock_mem(void);
240
Paulo Zanoni9bb04d32014-12-03 16:12:49 -0200241/**
242 * igt_wait:
243 * @COND: condition to wait
244 * @timeout_ms: timeout in milliseconds
245 * @interval_ms: amount of time we try to sleep between COND checks
246 *
247 * Waits until COND evaluates to true or the timeout passes.
248 *
249 * It is safe to call this macro if the signal helper is active. The only
250 * problem is that the usleep() calls will return early, making us evaluate COND
251 * too often, possibly eating valuable CPU cycles.
252 *
253 * Returns:
254 * True of COND evaluated to true, false otherwise.
255 */
256#define igt_wait(COND, timeout_ms, interval_ms) ({ \
257 struct timeval start_, end_, diff_; \
258 int elapsed_ms_; \
259 bool ret_ = false; \
260 \
261 igt_assert(gettimeofday(&start_, NULL) == 0); \
262 do { \
263 if (COND) { \
264 ret_ = true; \
265 break; \
266 } \
267 \
268 usleep(interval_ms * 1000); \
269 \
270 igt_assert(gettimeofday(&end_, NULL) == 0); \
271 timersub(&end_, &start_, &diff_); \
272 \
273 elapsed_ms_ = diff_.tv_sec * 1000 + \
274 diff_.tv_usec / 1000; \
275 } while (elapsed_ms_ < timeout_ms); \
276 \
277 if (!ret_ && (COND)) \
278 ret_ = true; \
279 \
280 ret_; \
281})
282
Chris Wilson76bc11b2016-03-18 18:30:37 +0000283struct igt_mean;
284void igt_start_siglatency(int sig); /* 0 => SIGRTMIN (default) */
285double igt_stop_siglatency(struct igt_mean *result);
Paulo Zanonid9ff9b32015-06-01 19:06:10 -0300286
287void igt_set_module_param(const char *name, const char *val);
288void igt_set_module_param_int(const char *name, int val);
289
Marius Vlad0268d732016-12-01 21:45:47 +0000290int igt_terminate_process(int sig, const char *comm);
291void igt_lsof(const char *dpath);
292
Lyuded57ae362016-11-21 13:43:36 -0500293/*
294 * This list data structure is a verbatim copy from wayland-util.h from the
295 * Wayland project; except that wl_ prefix has been removed.
296 */
297
298struct igt_list {
299 struct igt_list *prev;
300 struct igt_list *next;
301};
302
Rodrigo Vivid20b8702016-11-29 12:06:31 -0800303#define __IGT_INIT_LIST(name) { &(name), &(name) }
Chris Wilson2e2a7d02016-12-13 12:27:47 +0000304#define IGT_LIST(name) struct igt_list name = __IGT_INIT_LIST(name)
Lyuded57ae362016-11-21 13:43:36 -0500305
306static inline void igt_list_init(struct igt_list *list)
307{
308 list->prev = list;
309 list->next = list;
310}
311
312static inline void __igt_list_add(struct igt_list *list,
313 struct igt_list *prev,
314 struct igt_list *next)
315{
316 next->prev = list;
317 list->next = next;
318 list->prev = prev;
319 prev->next = list;
320}
321
322static inline void igt_list_add(struct igt_list *elm, struct igt_list *list)
323{
324 __igt_list_add(elm, list, list->next);
325}
326
327static inline void igt_list_add_tail(struct igt_list *elm,
328 struct igt_list *list)
329{
330 __igt_list_add(elm, list->prev, list);
331}
332
333static inline void __igt_list_del(struct igt_list *prev, struct igt_list *next)
334{
335 next->prev = prev;
336 prev->next = next;
337}
338
339static inline void igt_list_del(struct igt_list *elm)
340{
341 __igt_list_del(elm->prev, elm->next);
342}
343
344static inline void igt_list_move(struct igt_list *elm, struct igt_list *list)
345{
346 igt_list_del(elm);
347 igt_list_add(elm, list);
348}
349
350static inline void igt_list_move_tail(struct igt_list *elm,
351 struct igt_list *list)
352{
353 igt_list_del(elm);
354 igt_list_add_tail(elm, list);
355}
356
357static inline bool igt_list_empty(const struct igt_list *list)
358{
359 return list->next == list;
360}
361
362#define container_of(ptr, sample, member) \
363 (typeof(sample))((char *)(ptr) - offsetof(typeof(*sample), member))
364
365#define igt_list_first_entry(head, pos, member) \
366 container_of((head)->next, (pos), member)
Chris Wilson2e2a7d02016-12-13 12:27:47 +0000367#define igt_list_last_entry(head, pos, member) \
368 container_of((head)->prev, (pos), member)
369
Lyuded57ae362016-11-21 13:43:36 -0500370#define igt_list_next_entry(pos, member) \
371 container_of((pos)->member.next, (pos), member)
Chris Wilson2e2a7d02016-12-13 12:27:47 +0000372#define igt_list_prev_entry(pos, member) \
373 container_of((pos)->member.prev, (pos), member)
Lyuded57ae362016-11-21 13:43:36 -0500374
375#define igt_list_for_each(pos, head, member) \
Chris Wilson2e2a7d02016-12-13 12:27:47 +0000376 for (pos = igt_list_first_entry(head, pos, member); \
Lyuded57ae362016-11-21 13:43:36 -0500377 &pos->member != (head); \
378 pos = igt_list_next_entry(pos, member))
379
Chris Wilson2e2a7d02016-12-13 12:27:47 +0000380#define igt_list_for_each_reverse(pos, head, member) \
381 for (pos = igt_list_last_entry(head, pos, member); \
382 &pos->member != (head); \
383 pos = igt_list_prev_entry(pos, member))
384
Lyuded57ae362016-11-21 13:43:36 -0500385#define igt_list_for_each_safe(pos, tmp, head, member) \
386 for (pos = igt_list_first_entry(head, pos, member), \
387 tmp = igt_list_next_entry(pos, member); \
388 &pos->member != (head); \
389 pos = tmp, tmp = igt_list_next_entry(pos, member))
390
Daniel Vetterf5daeec2014-03-23 13:35:09 +0100391#endif /* IGT_AUX_H */