1 /* 2 * Copyright © 2014, 2015 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 * Daniel Vetter <daniel.vetter@ffwll.ch> 25 * 26 */ 27 28 #ifndef IGT_AUX_H 29 #define IGT_AUX_H 30 31 #include <inttypes.h> 32 #include <stdbool.h> 33 #include <stddef.h> 34 #include <sys/time.h> 35 #include <sys/types.h> 36 #include <unistd.h> 37 #ifdef __linux__ 38 # include <sys/syscall.h> 39 #endif 40 41 #include <i915/gem_submission.h> 42 43 /* signal interrupt helpers */ 44 #ifdef __linux__ 45 # ifndef HAVE_GETTID 46 # define gettid() (pid_t)(syscall(__NR_gettid)) 47 # endif 48 #endif 49 #define sigev_notify_thread_id _sigev_un._tid 50 51 /* auxialiary igt helpers from igt_aux.c */ 52 /* generally useful helpers */ 53 void igt_fork_signal_helper(void); 54 void igt_stop_signal_helper(void); 55 void igt_suspend_signal_helper(void); 56 void igt_resume_signal_helper(void); 57 58 void igt_fork_shrink_helper(int fd); 59 void igt_stop_shrink_helper(void); 60 61 void igt_fork_hang_detector(int fd); 62 void igt_stop_hang_detector(void); 63 64 struct __igt_sigiter { 65 unsigned pass; 66 }; 67 68 bool __igt_sigiter_continue(struct __igt_sigiter *iter, bool interrupt); 69 70 /** 71 * igt_while_interruptible: 72 * @enable: enable igt_ioctl interrupting or not 73 * 74 * Provides control flow such that all drmIoctl() (strictly igt_ioctl()) 75 * within the loop are forcibly injected with signals (SIGRTMIN). 76 * 77 * This is useful to exercise ioctl error paths, at least where those can be 78 * exercises by interrupting blocking waits, like stalling for the gpu. 79 * 80 * The code block attached to this macro is run in a loop with doubling the 81 * interrupt timeout on each ioctl for every run, until no ioctl gets 82 * interrupted any more. The starting timeout is taken to be the signal delivery 83 * latency, measured at runtime. This way the any ioctls called from this code 84 * block should be exhaustively tested for all signal interruption paths. 85 * 86 * Note that since this overloads the igt_ioctl(), this method is not useful 87 * for widespread signal injection, for example providing coverage of 88 * pagefaults. To interrupt everything, see igt_fork_signal_helper(). 89 */ 90 #define igt_while_interruptible(enable) \ 91 for (struct __igt_sigiter iter__={}; __igt_sigiter_continue(&iter__, (enable)); ) 92 93 /** 94 * igt_until_timeout: 95 * @timeout: timeout in seconds 96 * 97 * Convenience macro loop to run the provided code block in a loop until the 98 * timeout has expired. Of course when an individual execution takes too long, 99 * the actual execution time could be a lot longer. 100 * 101 * The code block will be executed at least once. 102 */ 103 #define igt_until_timeout(timeout) \ 104 for (struct timespec t__={}; igt_seconds_elapsed(&t__) < (timeout); ) 105 106 /** 107 * igt_for_milliseconds: 108 * @time: how long to run the loop in milliseconds 109 * 110 * Convenience macro loop to run the provided code block in a loop until the 111 * target interval has expired. Of course when an individual execution takes 112 * too long, the actual execution time could be a lot longer. 113 * 114 * The code block will be executed at least once. 115 */ 116 #define igt_for_milliseconds(t) \ 117 for (struct timespec t__={}; igt_nsec_elapsed(&t__)>>20 < (t); ) 118 119 void igt_exchange_int(void *array, unsigned i, unsigned j); 120 void igt_exchange_int64(void *array, unsigned i, unsigned j); 121 void igt_permute_array(void *array, unsigned size, 122 void (*exchange_func)(void *array, 123 unsigned i, 124 unsigned j)); 125 void igt_progress(const char *header, uint64_t i, uint64_t total); 126 void igt_print_activity(void); 127 bool igt_check_boolean_env_var(const char *env_var, bool default_value); 128 129 bool igt_aub_dump_enabled(void); 130 131 /* suspend/hibernate and auto-resume system */ 132 133 /** 134 * igt_suspend_state: 135 * @SUSPEND_STATE_FREEZE: suspend-to-idle target state, aka S0ix or freeze, 136 * first non-hibernation state 137 * @SUSPEND_STATE_STANDBY: standby target state, aka S1, second 138 * non-hibernation state 139 * @SUSPEND_STATE_MEM: suspend-to-mem target state aka S3, third 140 * non-hibernation state 141 * @SUSPEND_STATE_DISK: suspend-to-disk target state, aka S4 or hibernation 142 * 143 * Target suspend states used with igt_system_suspend_autoresume(). 144 * See /sys/power/state for the available states on a given machine. 145 */ 146 enum igt_suspend_state { 147 SUSPEND_STATE_FREEZE, 148 SUSPEND_STATE_STANDBY, 149 SUSPEND_STATE_MEM, 150 SUSPEND_STATE_DISK, 151 152 /*< private >*/ 153 SUSPEND_STATE_NUM, 154 }; 155 156 /** 157 * igt_suspend_test: 158 * @SUSPEND_TEST_NONE: no testing, perform a full suspend/resume cycle 159 * @SUSPEND_TEST_FREEZER: complete cycle after freezing all freezable threads 160 * @SUSPEND_TEST_DEVICES: complete cycle after the above step and suspending 161 * devices (before calling the drivers' suspend late and 162 * no_irq hooks). Platform and system devices are not 163 * suspended here, see #SUSPEND_TEST_CORE. 164 * @SUSPEND_TEST_PLATFORM: complete cycle after all the above steps and calling 165 * the ACPI platform global control methods (applies 166 * only with /sys/power/disk set to platform) 167 * @SUSPEND_TEST_PROCESSORS: complete cycle after all the above steps and 168 * disabling non-boot CPUs 169 * @SUSPEND_TEST_CORE: complete cycle after all the above steps and suspending 170 * platform and system devices 171 * 172 * Test points used with igt_system_suspend_autoresume(). Specifies if and where 173 * the suspend sequence is to be terminated. 174 */ 175 enum igt_suspend_test { 176 SUSPEND_TEST_NONE, 177 SUSPEND_TEST_FREEZER, 178 SUSPEND_TEST_DEVICES, 179 SUSPEND_TEST_PLATFORM, 180 SUSPEND_TEST_PROCESSORS, 181 SUSPEND_TEST_CORE, 182 183 /*< private >*/ 184 SUSPEND_TEST_NUM, 185 }; 186 187 void igt_system_suspend_autoresume(enum igt_suspend_state state, 188 enum igt_suspend_test test); 189 void igt_set_autoresume_delay(int delay_secs); 190 int igt_get_autoresume_delay(enum igt_suspend_state state); 191 192 /* dropping priviledges */ 193 void igt_drop_root(void); 194 195 void igt_debug_wait_for_keypress(const char *var); 196 void igt_debug_manual_check(const char *var, const char *expected); 197 198 /* sysinfo cross-arch wrappers from intel_os.c */ 199 200 /* These are separate to allow easier testing when porting, see the comment at 201 * the bottom of intel_os.c. */ 202 void intel_purge_vm_caches(int fd); 203 uint64_t intel_get_avail_ram_mb(void); 204 uint64_t intel_get_total_ram_mb(void); 205 uint64_t intel_get_total_swap_mb(void); 206 void *intel_get_total_pinnable_mem(size_t *pinned); 207 208 int __intel_check_memory(uint64_t count, uint64_t size, unsigned mode, 209 uint64_t *out_required, uint64_t *out_total); 210 void intel_require_memory(uint64_t count, uint64_t size, unsigned mode); 211 void intel_require_files(uint64_t count); 212 #define CHECK_RAM 0x1 213 #define CHECK_SWAP 0x2 214 215 #define min(a, b) ({ \ 216 typeof(a) _a = (a); \ 217 typeof(b) _b = (b); \ 218 _a < _b ? _a : _b; \ 219 }) 220 #define max(a, b) ({ \ 221 typeof(a) _a = (a); \ 222 typeof(b) _b = (b); \ 223 _a > _b ? _a : _b; \ 224 }) 225 226 #define clamp(x, min, max) ({ \ 227 typeof(min) _min = (min); \ 228 typeof(max) _max = (max); \ 229 typeof(x) _x = (x); \ 230 _x < _min ? _min : _x > _max ? _max : _x; \ 231 }) 232 233 #define igt_swap(a, b) do { \ 234 typeof(a) _tmp = (a); \ 235 (a) = (b); \ 236 (b) = _tmp; \ 237 } while (0) 238 239 void igt_lock_mem(size_t size); 240 void igt_unlock_mem(void); 241 242 /** 243 * igt_wait: 244 * @COND: condition to wait 245 * @timeout_ms: timeout in milliseconds 246 * @interval_ms: amount of time we try to sleep between COND checks 247 * 248 * Waits until COND evaluates to true or the timeout passes. 249 * 250 * It is safe to call this macro if the signal helper is active. The only 251 * problem is that the usleep() calls will return early, making us evaluate COND 252 * too often, possibly eating valuable CPU cycles. 253 * 254 * Returns: 255 * True of COND evaluated to true, false otherwise. 256 */ 257 #define igt_wait(COND, timeout_ms, interval_ms) ({ \ 258 const unsigned long interval_us__ = 1000 * (interval_ms); \ 259 const unsigned long timeout_ms__ = (timeout_ms); \ 260 struct timespec tv__ = {}; \ 261 bool ret__; \ 262 \ 263 do { \ 264 uint64_t elapsed__ = igt_nsec_elapsed(&tv__) >> 20; \ 265 \ 266 if (COND) { \ 267 igt_debug("%s took %"PRIu64"ms\n", #COND, elapsed__); \ 268 ret__ = true; \ 269 break; \ 270 } \ 271 if (elapsed__ > timeout_ms__) { \ 272 ret__ = false; \ 273 break; \ 274 } \ 275 \ 276 usleep(interval_us__); \ 277 } while (1); \ 278 \ 279 ret__; \ 280 }) 281 282 struct igt_mean; 283 void igt_start_siglatency(int sig); /* 0 => SIGRTMIN (default) */ 284 double igt_stop_siglatency(struct igt_mean *result); 285 286 bool igt_allow_unlimited_files(void); 287 288 void igt_set_module_param(const char *name, const char *val); 289 void igt_set_module_param_int(const char *name, int val); 290 291 int igt_is_process_running(const char *comm); 292 int igt_terminate_process(int sig, const char *comm); 293 void igt_lsof(const char *dpath); 294 295 #define igt_hweight(x) \ 296 __builtin_choose_expr(sizeof(x) == 8, \ 297 __builtin_popcountll(x), \ 298 __builtin_popcount(x)) 299 300 #define is_power_of_two(x) (((x) & ((x)-1)) == 0) 301 302 #define igt_fls(x) ((x) ? __builtin_choose_expr(sizeof(x) == 8, \ 303 64 - __builtin_clzll(x), \ 304 32 - __builtin_clz(x)) : 0) 305 306 #define roundup_power_of_two(x) ((x) != 0 ? 1 << igt_fls((x) - 1) : 0) 307 308 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) 309 310 uint64_t vfs_file_max(void); 311 312 #endif /* IGT_AUX_H */ 313