xref: /aosp_15_r20/external/igt-gpu-tools/lib/igt_aux.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2007, 2011, 2013, 2014, 2015 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  *    Eric Anholt <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker  *    Daniel Vetter <[email protected]>
26*d83cc019SAndroid Build Coastguard Worker  *
27*d83cc019SAndroid Build Coastguard Worker  */
28*d83cc019SAndroid Build Coastguard Worker 
29*d83cc019SAndroid Build Coastguard Worker #ifdef HAVE_LIBGEN_H
30*d83cc019SAndroid Build Coastguard Worker #include <libgen.h>
31*d83cc019SAndroid Build Coastguard Worker #endif
32*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
33*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
34*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
35*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
36*d83cc019SAndroid Build Coastguard Worker #include <string.h>
37*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
38*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
39*d83cc019SAndroid Build Coastguard Worker #include <pciaccess.h>
40*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
41*d83cc019SAndroid Build Coastguard Worker #include <time.h>
42*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
43*d83cc019SAndroid Build Coastguard Worker #include <sys/poll.h>
44*d83cc019SAndroid Build Coastguard Worker #include <sys/wait.h>
45*d83cc019SAndroid Build Coastguard Worker #include <sys/resource.h>
46*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
47*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
48*d83cc019SAndroid Build Coastguard Worker #include <sys/syscall.h>
49*d83cc019SAndroid Build Coastguard Worker #include <sys/utsname.h>
50*d83cc019SAndroid Build Coastguard Worker #include <termios.h>
51*d83cc019SAndroid Build Coastguard Worker #include <assert.h>
52*d83cc019SAndroid Build Coastguard Worker #include <grp.h>
53*d83cc019SAndroid Build Coastguard Worker 
54*d83cc019SAndroid Build Coastguard Worker #ifndef ANDROID
55*d83cc019SAndroid Build Coastguard Worker #include <proc/readproc.h>
56*d83cc019SAndroid Build Coastguard Worker #include <libudev.h>
57*d83cc019SAndroid Build Coastguard Worker #endif
58*d83cc019SAndroid Build Coastguard Worker 
59*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
60*d83cc019SAndroid Build Coastguard Worker #include "i915_drm.h"
61*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
62*d83cc019SAndroid Build Coastguard Worker #include "igt_aux.h"
63*d83cc019SAndroid Build Coastguard Worker #include "igt_debugfs.h"
64*d83cc019SAndroid Build Coastguard Worker #include "igt_gt.h"
65*d83cc019SAndroid Build Coastguard Worker #include "igt_rand.h"
66*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
67*d83cc019SAndroid Build Coastguard Worker #include "config.h"
68*d83cc019SAndroid Build Coastguard Worker #include "intel_reg.h"
69*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
70*d83cc019SAndroid Build Coastguard Worker #include "igt_kms.h"
71*d83cc019SAndroid Build Coastguard Worker #include "igt_stats.h"
72*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
73*d83cc019SAndroid Build Coastguard Worker 
74*d83cc019SAndroid Build Coastguard Worker #ifdef HAVE_LIBGEN_H
75*d83cc019SAndroid Build Coastguard Worker #include <libgen.h>   /* for dirname() */
76*d83cc019SAndroid Build Coastguard Worker #endif
77*d83cc019SAndroid Build Coastguard Worker 
78*d83cc019SAndroid Build Coastguard Worker /**
79*d83cc019SAndroid Build Coastguard Worker  * SECTION:igt_aux
80*d83cc019SAndroid Build Coastguard Worker  * @short_description: Auxiliary libraries and support functions
81*d83cc019SAndroid Build Coastguard Worker  * @title: aux
82*d83cc019SAndroid Build Coastguard Worker  * @include: igt.h
83*d83cc019SAndroid Build Coastguard Worker  *
84*d83cc019SAndroid Build Coastguard Worker  * This library provides various auxiliary helper functions that don't really
85*d83cc019SAndroid Build Coastguard Worker  * fit into any other topic.
86*d83cc019SAndroid Build Coastguard Worker  */
87*d83cc019SAndroid Build Coastguard Worker 
88*d83cc019SAndroid Build Coastguard Worker static struct __igt_sigiter_global {
89*d83cc019SAndroid Build Coastguard Worker 	pid_t tid;
90*d83cc019SAndroid Build Coastguard Worker 	timer_t timer;
91*d83cc019SAndroid Build Coastguard Worker 	struct timespec offset;
92*d83cc019SAndroid Build Coastguard Worker 	struct {
93*d83cc019SAndroid Build Coastguard Worker 		long hit, miss;
94*d83cc019SAndroid Build Coastguard Worker 		long ioctls, signals;
95*d83cc019SAndroid Build Coastguard Worker 	} stat;
96*d83cc019SAndroid Build Coastguard Worker } __igt_sigiter;
97*d83cc019SAndroid Build Coastguard Worker 
sigiter(int sig,siginfo_t * info,void * arg)98*d83cc019SAndroid Build Coastguard Worker static void sigiter(int sig, siginfo_t *info, void *arg)
99*d83cc019SAndroid Build Coastguard Worker {
100*d83cc019SAndroid Build Coastguard Worker 	__igt_sigiter.stat.signals++;
101*d83cc019SAndroid Build Coastguard Worker }
102*d83cc019SAndroid Build Coastguard Worker 
103*d83cc019SAndroid Build Coastguard Worker #if 0
104*d83cc019SAndroid Build Coastguard Worker #define SIG_ASSERT(expr) igt_assert(expr)
105*d83cc019SAndroid Build Coastguard Worker #else
106*d83cc019SAndroid Build Coastguard Worker #define SIG_ASSERT(expr)
107*d83cc019SAndroid Build Coastguard Worker #endif
108*d83cc019SAndroid Build Coastguard Worker 
109*d83cc019SAndroid Build Coastguard Worker static int
sig_ioctl(int fd,unsigned long request,void * arg)110*d83cc019SAndroid Build Coastguard Worker sig_ioctl(int fd, unsigned long request, void *arg)
111*d83cc019SAndroid Build Coastguard Worker {
112*d83cc019SAndroid Build Coastguard Worker 	struct itimerspec its;
113*d83cc019SAndroid Build Coastguard Worker 	int ret;
114*d83cc019SAndroid Build Coastguard Worker 
115*d83cc019SAndroid Build Coastguard Worker 	SIG_ASSERT(__igt_sigiter.timer);
116*d83cc019SAndroid Build Coastguard Worker 	SIG_ASSERT(__igt_sigiter.tid == gettid());
117*d83cc019SAndroid Build Coastguard Worker 
118*d83cc019SAndroid Build Coastguard Worker 	memset(&its, 0, sizeof(its));
119*d83cc019SAndroid Build Coastguard Worker 	if (timer_settime(__igt_sigiter.timer, 0, &its, NULL)) {
120*d83cc019SAndroid Build Coastguard Worker 		/* oops, we didn't undo the interrupter (i.e. !unwound abort) */
121*d83cc019SAndroid Build Coastguard Worker 		igt_ioctl = drmIoctl;
122*d83cc019SAndroid Build Coastguard Worker 		return drmIoctl(fd, request, arg);
123*d83cc019SAndroid Build Coastguard Worker 	}
124*d83cc019SAndroid Build Coastguard Worker 
125*d83cc019SAndroid Build Coastguard Worker 	its.it_value = __igt_sigiter.offset;
126*d83cc019SAndroid Build Coastguard Worker 	do {
127*d83cc019SAndroid Build Coastguard Worker 		long serial;
128*d83cc019SAndroid Build Coastguard Worker 
129*d83cc019SAndroid Build Coastguard Worker 		__igt_sigiter.stat.ioctls++;
130*d83cc019SAndroid Build Coastguard Worker 
131*d83cc019SAndroid Build Coastguard Worker 		ret = 0;
132*d83cc019SAndroid Build Coastguard Worker 		serial = __igt_sigiter.stat.signals;
133*d83cc019SAndroid Build Coastguard Worker 		igt_assert(timer_settime(__igt_sigiter.timer, 0, &its, NULL) == 0);
134*d83cc019SAndroid Build Coastguard Worker 		if (ioctl(fd, request, arg))
135*d83cc019SAndroid Build Coastguard Worker 			ret = errno;
136*d83cc019SAndroid Build Coastguard Worker 		if (__igt_sigiter.stat.signals == serial)
137*d83cc019SAndroid Build Coastguard Worker 			__igt_sigiter.stat.miss++;
138*d83cc019SAndroid Build Coastguard Worker 		if (ret == 0)
139*d83cc019SAndroid Build Coastguard Worker 			break;
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker 		if (ret == EINTR) {
142*d83cc019SAndroid Build Coastguard Worker 			__igt_sigiter.stat.hit++;
143*d83cc019SAndroid Build Coastguard Worker 
144*d83cc019SAndroid Build Coastguard Worker 			its.it_value.tv_sec *= 2;
145*d83cc019SAndroid Build Coastguard Worker 			its.it_value.tv_nsec *= 2;
146*d83cc019SAndroid Build Coastguard Worker 			while (its.it_value.tv_nsec >= NSEC_PER_SEC) {
147*d83cc019SAndroid Build Coastguard Worker 				its.it_value.tv_nsec -= NSEC_PER_SEC;
148*d83cc019SAndroid Build Coastguard Worker 				its.it_value.tv_sec += 1;
149*d83cc019SAndroid Build Coastguard Worker 			}
150*d83cc019SAndroid Build Coastguard Worker 
151*d83cc019SAndroid Build Coastguard Worker 			SIG_ASSERT(its.it_value.tv_nsec >= 0);
152*d83cc019SAndroid Build Coastguard Worker 			SIG_ASSERT(its.it_value.tv_sec >= 0);
153*d83cc019SAndroid Build Coastguard Worker 		}
154*d83cc019SAndroid Build Coastguard Worker 	} while (ret == EAGAIN || ret == EINTR);
155*d83cc019SAndroid Build Coastguard Worker 
156*d83cc019SAndroid Build Coastguard Worker 	memset(&its, 0, sizeof(its));
157*d83cc019SAndroid Build Coastguard Worker 	timer_settime(__igt_sigiter.timer, 0, &its, NULL);
158*d83cc019SAndroid Build Coastguard Worker 
159*d83cc019SAndroid Build Coastguard Worker 	errno = ret;
160*d83cc019SAndroid Build Coastguard Worker 	return ret ? -1 : 0;
161*d83cc019SAndroid Build Coastguard Worker }
162*d83cc019SAndroid Build Coastguard Worker 
igt_sigiter_start(struct __igt_sigiter * iter,bool enable)163*d83cc019SAndroid Build Coastguard Worker static bool igt_sigiter_start(struct __igt_sigiter *iter, bool enable)
164*d83cc019SAndroid Build Coastguard Worker {
165*d83cc019SAndroid Build Coastguard Worker 	/* Note that until we can automatically clean up on failed/skipped
166*d83cc019SAndroid Build Coastguard Worker 	 * tests, we cannot assume the state of the igt_ioctl indirection.
167*d83cc019SAndroid Build Coastguard Worker 	 */
168*d83cc019SAndroid Build Coastguard Worker 	SIG_ASSERT(igt_ioctl == drmIoctl);
169*d83cc019SAndroid Build Coastguard Worker 	igt_ioctl = drmIoctl;
170*d83cc019SAndroid Build Coastguard Worker 
171*d83cc019SAndroid Build Coastguard Worker 	if (enable) {
172*d83cc019SAndroid Build Coastguard Worker 		struct timespec start, end;
173*d83cc019SAndroid Build Coastguard Worker 		struct sigevent sev;
174*d83cc019SAndroid Build Coastguard Worker 		struct sigaction act;
175*d83cc019SAndroid Build Coastguard Worker 		struct itimerspec its;
176*d83cc019SAndroid Build Coastguard Worker 
177*d83cc019SAndroid Build Coastguard Worker 		igt_ioctl = sig_ioctl;
178*d83cc019SAndroid Build Coastguard Worker 		__igt_sigiter.tid = gettid();
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 		memset(&sev, 0, sizeof(sev));
181*d83cc019SAndroid Build Coastguard Worker 		sev.sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID;
182*d83cc019SAndroid Build Coastguard Worker 		sev.sigev_notify_thread_id = __igt_sigiter.tid;
183*d83cc019SAndroid Build Coastguard Worker 		sev.sigev_signo = SIGRTMIN;
184*d83cc019SAndroid Build Coastguard Worker 		igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &__igt_sigiter.timer) == 0);
185*d83cc019SAndroid Build Coastguard Worker 
186*d83cc019SAndroid Build Coastguard Worker 		memset(&its, 0, sizeof(its));
187*d83cc019SAndroid Build Coastguard Worker 		igt_assert(timer_settime(__igt_sigiter.timer, 0, &its, NULL) == 0);
188*d83cc019SAndroid Build Coastguard Worker 
189*d83cc019SAndroid Build Coastguard Worker 		memset(&act, 0, sizeof(act));
190*d83cc019SAndroid Build Coastguard Worker 		act.sa_sigaction = sigiter;
191*d83cc019SAndroid Build Coastguard Worker 		act.sa_flags = SA_SIGINFO;
192*d83cc019SAndroid Build Coastguard Worker 		igt_assert(sigaction(SIGRTMIN, &act, NULL) == 0);
193*d83cc019SAndroid Build Coastguard Worker 
194*d83cc019SAndroid Build Coastguard Worker 		/* Try to find the approximate delay required to skip over
195*d83cc019SAndroid Build Coastguard Worker 		 * the timer_setttime and into the following ioctl() to try
196*d83cc019SAndroid Build Coastguard Worker 		 * and avoid the timer firing before we enter the drmIoctl.
197*d83cc019SAndroid Build Coastguard Worker 		 */
198*d83cc019SAndroid Build Coastguard Worker 		igt_assert(clock_gettime(CLOCK_MONOTONIC, &start) == 0);
199*d83cc019SAndroid Build Coastguard Worker 		igt_assert(timer_settime(__igt_sigiter.timer, 0, &its, NULL) == 0);
200*d83cc019SAndroid Build Coastguard Worker 		igt_assert(clock_gettime(CLOCK_MONOTONIC, &end) == 0);
201*d83cc019SAndroid Build Coastguard Worker 
202*d83cc019SAndroid Build Coastguard Worker 		__igt_sigiter.offset.tv_sec = end.tv_sec - start.tv_sec;
203*d83cc019SAndroid Build Coastguard Worker 		__igt_sigiter.offset.tv_nsec = end.tv_nsec - start.tv_nsec;
204*d83cc019SAndroid Build Coastguard Worker 		if (__igt_sigiter.offset.tv_nsec < 0) {
205*d83cc019SAndroid Build Coastguard Worker 			__igt_sigiter.offset.tv_nsec += NSEC_PER_SEC;
206*d83cc019SAndroid Build Coastguard Worker 			__igt_sigiter.offset.tv_sec -= 1;
207*d83cc019SAndroid Build Coastguard Worker 		}
208*d83cc019SAndroid Build Coastguard Worker 		if (__igt_sigiter.offset.tv_sec < 0) {
209*d83cc019SAndroid Build Coastguard Worker 			__igt_sigiter.offset.tv_nsec = 0;
210*d83cc019SAndroid Build Coastguard Worker 			__igt_sigiter.offset.tv_sec = 0;
211*d83cc019SAndroid Build Coastguard Worker 		}
212*d83cc019SAndroid Build Coastguard Worker 		igt_assert(__igt_sigiter.offset.tv_sec == 0);
213*d83cc019SAndroid Build Coastguard Worker 
214*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Initial delay for interruption: %ld.%09lds\n",
215*d83cc019SAndroid Build Coastguard Worker 			  __igt_sigiter.offset.tv_sec,
216*d83cc019SAndroid Build Coastguard Worker 			  __igt_sigiter.offset.tv_nsec);
217*d83cc019SAndroid Build Coastguard Worker 	}
218*d83cc019SAndroid Build Coastguard Worker 
219*d83cc019SAndroid Build Coastguard Worker 	return true;
220*d83cc019SAndroid Build Coastguard Worker }
221*d83cc019SAndroid Build Coastguard Worker 
igt_sigiter_stop(struct __igt_sigiter * iter,bool enable)222*d83cc019SAndroid Build Coastguard Worker static bool igt_sigiter_stop(struct __igt_sigiter *iter, bool enable)
223*d83cc019SAndroid Build Coastguard Worker {
224*d83cc019SAndroid Build Coastguard Worker 	if (enable) {
225*d83cc019SAndroid Build Coastguard Worker 		struct sigaction act;
226*d83cc019SAndroid Build Coastguard Worker 
227*d83cc019SAndroid Build Coastguard Worker 		SIG_ASSERT(igt_ioctl == sig_ioctl);
228*d83cc019SAndroid Build Coastguard Worker 		SIG_ASSERT(__igt_sigiter.tid == gettid());
229*d83cc019SAndroid Build Coastguard Worker 		igt_ioctl = drmIoctl;
230*d83cc019SAndroid Build Coastguard Worker 
231*d83cc019SAndroid Build Coastguard Worker 		timer_delete(__igt_sigiter.timer);
232*d83cc019SAndroid Build Coastguard Worker 
233*d83cc019SAndroid Build Coastguard Worker 		memset(&act, 0, sizeof(act));
234*d83cc019SAndroid Build Coastguard Worker 		act.sa_handler = SIG_IGN;
235*d83cc019SAndroid Build Coastguard Worker 		sigaction(SIGRTMIN, &act, NULL);
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 		memset(&__igt_sigiter, 0, sizeof(__igt_sigiter));
238*d83cc019SAndroid Build Coastguard Worker 	}
239*d83cc019SAndroid Build Coastguard Worker 
240*d83cc019SAndroid Build Coastguard Worker 	memset(iter, 0, sizeof(*iter));
241*d83cc019SAndroid Build Coastguard Worker 	return false;
242*d83cc019SAndroid Build Coastguard Worker }
243*d83cc019SAndroid Build Coastguard Worker 
__igt_sigiter_continue(struct __igt_sigiter * iter,bool enable)244*d83cc019SAndroid Build Coastguard Worker bool __igt_sigiter_continue(struct __igt_sigiter *iter, bool enable)
245*d83cc019SAndroid Build Coastguard Worker {
246*d83cc019SAndroid Build Coastguard Worker 	if (iter->pass++ == 0)
247*d83cc019SAndroid Build Coastguard Worker 		return igt_sigiter_start(iter, enable);
248*d83cc019SAndroid Build Coastguard Worker 
249*d83cc019SAndroid Build Coastguard Worker 	/* If nothing reported SIGINT, nothing will on the next pass, so
250*d83cc019SAndroid Build Coastguard Worker 	 * give up! Also give up if everything is now executing faster
251*d83cc019SAndroid Build Coastguard Worker 	 * than current sigtimer.
252*d83cc019SAndroid Build Coastguard Worker 	 */
253*d83cc019SAndroid Build Coastguard Worker 	if (__igt_sigiter.stat.hit == 0 ||
254*d83cc019SAndroid Build Coastguard Worker 	    __igt_sigiter.stat.miss == __igt_sigiter.stat.ioctls)
255*d83cc019SAndroid Build Coastguard Worker 		return igt_sigiter_stop(iter, enable);
256*d83cc019SAndroid Build Coastguard Worker 
257*d83cc019SAndroid Build Coastguard Worker 	igt_debug("%s: pass %d, missed %ld/%ld\n",
258*d83cc019SAndroid Build Coastguard Worker 		  __func__, iter->pass - 1,
259*d83cc019SAndroid Build Coastguard Worker 		  __igt_sigiter.stat.miss,
260*d83cc019SAndroid Build Coastguard Worker 		  __igt_sigiter.stat.ioctls);
261*d83cc019SAndroid Build Coastguard Worker 
262*d83cc019SAndroid Build Coastguard Worker 	SIG_ASSERT(igt_ioctl == sig_ioctl);
263*d83cc019SAndroid Build Coastguard Worker 	SIG_ASSERT(__igt_sigiter.timer);
264*d83cc019SAndroid Build Coastguard Worker 
265*d83cc019SAndroid Build Coastguard Worker 	__igt_sigiter.offset.tv_sec *= 2;
266*d83cc019SAndroid Build Coastguard Worker 	__igt_sigiter.offset.tv_nsec *= 2;
267*d83cc019SAndroid Build Coastguard Worker 	while (__igt_sigiter.offset.tv_nsec >= NSEC_PER_SEC) {
268*d83cc019SAndroid Build Coastguard Worker 		__igt_sigiter.offset.tv_nsec -= NSEC_PER_SEC;
269*d83cc019SAndroid Build Coastguard Worker 		__igt_sigiter.offset.tv_sec += 1;
270*d83cc019SAndroid Build Coastguard Worker 	}
271*d83cc019SAndroid Build Coastguard Worker 	SIG_ASSERT(__igt_sigiter.offset.tv_nsec >= 0);
272*d83cc019SAndroid Build Coastguard Worker 	SIG_ASSERT(__igt_sigiter.offset.tv_sec >= 0);
273*d83cc019SAndroid Build Coastguard Worker 
274*d83cc019SAndroid Build Coastguard Worker 	memset(&__igt_sigiter.stat, 0, sizeof(__igt_sigiter.stat));
275*d83cc019SAndroid Build Coastguard Worker 	return true;
276*d83cc019SAndroid Build Coastguard Worker }
277*d83cc019SAndroid Build Coastguard Worker 
278*d83cc019SAndroid Build Coastguard Worker static struct igt_helper_process signal_helper;
279*d83cc019SAndroid Build Coastguard Worker long long int sig_stat;
signal_helper_process(pid_t pid)280*d83cc019SAndroid Build Coastguard Worker static void __attribute__((noreturn)) signal_helper_process(pid_t pid)
281*d83cc019SAndroid Build Coastguard Worker {
282*d83cc019SAndroid Build Coastguard Worker 	/* Interrupt the parent process at 500Hz, just to be annoying */
283*d83cc019SAndroid Build Coastguard Worker 	while (1) {
284*d83cc019SAndroid Build Coastguard Worker 		usleep(1000 * 1000 / 500);
285*d83cc019SAndroid Build Coastguard Worker 		if (kill(pid, SIGCONT)) /* Parent has died, so must we. */
286*d83cc019SAndroid Build Coastguard Worker 			exit(0);
287*d83cc019SAndroid Build Coastguard Worker 	}
288*d83cc019SAndroid Build Coastguard Worker }
289*d83cc019SAndroid Build Coastguard Worker 
sig_handler(int i)290*d83cc019SAndroid Build Coastguard Worker static void sig_handler(int i)
291*d83cc019SAndroid Build Coastguard Worker {
292*d83cc019SAndroid Build Coastguard Worker 	sig_stat++;
293*d83cc019SAndroid Build Coastguard Worker }
294*d83cc019SAndroid Build Coastguard Worker 
295*d83cc019SAndroid Build Coastguard Worker /**
296*d83cc019SAndroid Build Coastguard Worker  * igt_fork_signal_helper:
297*d83cc019SAndroid Build Coastguard Worker  *
298*d83cc019SAndroid Build Coastguard Worker  * Fork a child process using #igt_fork_helper to interrupt the parent process
299*d83cc019SAndroid Build Coastguard Worker  * with a SIGCONT signal at regular quick intervals. The corresponding dummy
300*d83cc019SAndroid Build Coastguard Worker  * signal handler is installed in the parent process.
301*d83cc019SAndroid Build Coastguard Worker  *
302*d83cc019SAndroid Build Coastguard Worker  * This is useful to exercise ioctl error paths, at least where those can be
303*d83cc019SAndroid Build Coastguard Worker  * exercises by interrupting blocking waits, like stalling for the gpu. This
304*d83cc019SAndroid Build Coastguard Worker  * helper can also be used from children spawned with #igt_fork.
305*d83cc019SAndroid Build Coastguard Worker  *
306*d83cc019SAndroid Build Coastguard Worker  * In tests with subtests this function can be called outside of failure
307*d83cc019SAndroid Build Coastguard Worker  * catching code blocks like #igt_fixture or #igt_subtest.
308*d83cc019SAndroid Build Coastguard Worker  *
309*d83cc019SAndroid Build Coastguard Worker  * Note that this just spews signals at the current process unconditionally and
310*d83cc019SAndroid Build Coastguard Worker  * hence incurs quite a bit of overhead. For a more focused approach, with less
311*d83cc019SAndroid Build Coastguard Worker  * overhead, look at the #igt_while_interruptible code block macro.
312*d83cc019SAndroid Build Coastguard Worker  */
igt_fork_signal_helper(void)313*d83cc019SAndroid Build Coastguard Worker void igt_fork_signal_helper(void)
314*d83cc019SAndroid Build Coastguard Worker {
315*d83cc019SAndroid Build Coastguard Worker 	if (igt_only_list_subtests())
316*d83cc019SAndroid Build Coastguard Worker 		return;
317*d83cc019SAndroid Build Coastguard Worker 
318*d83cc019SAndroid Build Coastguard Worker 	/* We pick SIGCONT as it is a "safe" signal - if we send SIGCONT to
319*d83cc019SAndroid Build Coastguard Worker 	 * an unexpecting process it spuriously wakes up and does nothing.
320*d83cc019SAndroid Build Coastguard Worker 	 * Most other signals (e.g. SIGUSR1) cause the process to die if they
321*d83cc019SAndroid Build Coastguard Worker 	 * are not handled. This is an issue in case the sighandler is not
322*d83cc019SAndroid Build Coastguard Worker 	 * inherited correctly (or if there is a race in the inheritance
323*d83cc019SAndroid Build Coastguard Worker 	 * and we send the signal at exactly the wrong time).
324*d83cc019SAndroid Build Coastguard Worker 	 */
325*d83cc019SAndroid Build Coastguard Worker 	signal(SIGCONT, sig_handler);
326*d83cc019SAndroid Build Coastguard Worker 	setpgrp(); /* define a new process group for the tests */
327*d83cc019SAndroid Build Coastguard Worker 
328*d83cc019SAndroid Build Coastguard Worker 	igt_fork_helper(&signal_helper) {
329*d83cc019SAndroid Build Coastguard Worker 		setpgrp(); /* Escape from the test process group */
330*d83cc019SAndroid Build Coastguard Worker 
331*d83cc019SAndroid Build Coastguard Worker 		/* Pass along the test process group identifier,
332*d83cc019SAndroid Build Coastguard Worker 		 * negative pid => send signal to everyone in the group.
333*d83cc019SAndroid Build Coastguard Worker 		 */
334*d83cc019SAndroid Build Coastguard Worker 		signal_helper_process(-getppid());
335*d83cc019SAndroid Build Coastguard Worker 	}
336*d83cc019SAndroid Build Coastguard Worker }
337*d83cc019SAndroid Build Coastguard Worker 
338*d83cc019SAndroid Build Coastguard Worker /**
339*d83cc019SAndroid Build Coastguard Worker  * igt_stop_signal_helper:
340*d83cc019SAndroid Build Coastguard Worker  *
341*d83cc019SAndroid Build Coastguard Worker  * Stops the child process spawned with igt_fork_signal_helper() again.
342*d83cc019SAndroid Build Coastguard Worker  *
343*d83cc019SAndroid Build Coastguard Worker  * In tests with subtests this function can be called outside of failure
344*d83cc019SAndroid Build Coastguard Worker  * catching code blocks like #igt_fixture or #igt_subtest.
345*d83cc019SAndroid Build Coastguard Worker  */
igt_stop_signal_helper(void)346*d83cc019SAndroid Build Coastguard Worker void igt_stop_signal_helper(void)
347*d83cc019SAndroid Build Coastguard Worker {
348*d83cc019SAndroid Build Coastguard Worker 	if (igt_only_list_subtests())
349*d83cc019SAndroid Build Coastguard Worker 		return;
350*d83cc019SAndroid Build Coastguard Worker 
351*d83cc019SAndroid Build Coastguard Worker 	igt_stop_helper(&signal_helper);
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker 	sig_stat = 0;
354*d83cc019SAndroid Build Coastguard Worker }
355*d83cc019SAndroid Build Coastguard Worker 
356*d83cc019SAndroid Build Coastguard Worker /**
357*d83cc019SAndroid Build Coastguard Worker  * igt_suspend_signal_helper:
358*d83cc019SAndroid Build Coastguard Worker  *
359*d83cc019SAndroid Build Coastguard Worker  * Suspends the child process spawned with igt_fork_signal_helper(). This
360*d83cc019SAndroid Build Coastguard Worker  * should be called before a critical section of code that has difficulty to
361*d83cc019SAndroid Build Coastguard Worker  * make progress if interrupted frequently, like the clone() syscall called
362*d83cc019SAndroid Build Coastguard Worker  * from a largish executable. igt_resume_signal_helper() must be called after
363*d83cc019SAndroid Build Coastguard Worker  * the critical section to restart interruptions for the test.
364*d83cc019SAndroid Build Coastguard Worker  */
igt_suspend_signal_helper(void)365*d83cc019SAndroid Build Coastguard Worker void igt_suspend_signal_helper(void)
366*d83cc019SAndroid Build Coastguard Worker {
367*d83cc019SAndroid Build Coastguard Worker 	int status;
368*d83cc019SAndroid Build Coastguard Worker 
369*d83cc019SAndroid Build Coastguard Worker 	if (!signal_helper.running)
370*d83cc019SAndroid Build Coastguard Worker 		return;
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker 	kill(signal_helper.pid, SIGSTOP);
373*d83cc019SAndroid Build Coastguard Worker 	while (waitpid(signal_helper.pid, &status, WUNTRACED) == -1 &&
374*d83cc019SAndroid Build Coastguard Worker 	       errno == EINTR)
375*d83cc019SAndroid Build Coastguard Worker 		;
376*d83cc019SAndroid Build Coastguard Worker }
377*d83cc019SAndroid Build Coastguard Worker 
378*d83cc019SAndroid Build Coastguard Worker /**
379*d83cc019SAndroid Build Coastguard Worker  * igt_resume_signal_helper:
380*d83cc019SAndroid Build Coastguard Worker  *
381*d83cc019SAndroid Build Coastguard Worker  * Resumes the child process spawned with igt_fork_signal_helper().
382*d83cc019SAndroid Build Coastguard Worker  *
383*d83cc019SAndroid Build Coastguard Worker  * This should be paired with igt_suspend_signal_helper() and called after the
384*d83cc019SAndroid Build Coastguard Worker  * problematic code sensitive to signals.
385*d83cc019SAndroid Build Coastguard Worker  */
igt_resume_signal_helper(void)386*d83cc019SAndroid Build Coastguard Worker void igt_resume_signal_helper(void)
387*d83cc019SAndroid Build Coastguard Worker {
388*d83cc019SAndroid Build Coastguard Worker 	if (!signal_helper.running)
389*d83cc019SAndroid Build Coastguard Worker 		return;
390*d83cc019SAndroid Build Coastguard Worker 
391*d83cc019SAndroid Build Coastguard Worker 	kill(signal_helper.pid, SIGCONT);
392*d83cc019SAndroid Build Coastguard Worker }
393*d83cc019SAndroid Build Coastguard Worker 
394*d83cc019SAndroid Build Coastguard Worker static struct igt_helper_process shrink_helper;
shrink_helper_process(int fd,pid_t pid)395*d83cc019SAndroid Build Coastguard Worker static void __attribute__((noreturn)) shrink_helper_process(int fd, pid_t pid)
396*d83cc019SAndroid Build Coastguard Worker {
397*d83cc019SAndroid Build Coastguard Worker 	while (1) {
398*d83cc019SAndroid Build Coastguard Worker 		igt_drop_caches_set(fd, DROP_SHRINK_ALL);
399*d83cc019SAndroid Build Coastguard Worker 		usleep(1000 * 1000 / 50);
400*d83cc019SAndroid Build Coastguard Worker 		if (kill(pid, 0)) /* Parent has died, so must we. */
401*d83cc019SAndroid Build Coastguard Worker 			exit(0);
402*d83cc019SAndroid Build Coastguard Worker 	}
403*d83cc019SAndroid Build Coastguard Worker }
404*d83cc019SAndroid Build Coastguard Worker 
405*d83cc019SAndroid Build Coastguard Worker /**
406*d83cc019SAndroid Build Coastguard Worker  * igt_fork_shrink_helper:
407*d83cc019SAndroid Build Coastguard Worker  *
408*d83cc019SAndroid Build Coastguard Worker  * Fork a child process using #igt_fork_helper to force all available objects
409*d83cc019SAndroid Build Coastguard Worker  * to be paged out (via i915_gem_shrink()).
410*d83cc019SAndroid Build Coastguard Worker  *
411*d83cc019SAndroid Build Coastguard Worker  * This is useful to exercise swapping paths, without requiring us to hit swap.
412*d83cc019SAndroid Build Coastguard Worker  *
413*d83cc019SAndroid Build Coastguard Worker  * This should only be used from an igt_fixture.
414*d83cc019SAndroid Build Coastguard Worker  */
igt_fork_shrink_helper(int drm_fd)415*d83cc019SAndroid Build Coastguard Worker void igt_fork_shrink_helper(int drm_fd)
416*d83cc019SAndroid Build Coastguard Worker {
417*d83cc019SAndroid Build Coastguard Worker 	assert(!igt_only_list_subtests());
418*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_drop_caches_has(drm_fd, DROP_SHRINK_ALL));
419*d83cc019SAndroid Build Coastguard Worker 	igt_fork_helper(&shrink_helper)
420*d83cc019SAndroid Build Coastguard Worker 		shrink_helper_process(drm_fd, getppid());
421*d83cc019SAndroid Build Coastguard Worker }
422*d83cc019SAndroid Build Coastguard Worker 
423*d83cc019SAndroid Build Coastguard Worker /**
424*d83cc019SAndroid Build Coastguard Worker  * igt_stop_shrink_helper:
425*d83cc019SAndroid Build Coastguard Worker  *
426*d83cc019SAndroid Build Coastguard Worker  * Stops the child process spawned with igt_fork_shrink_helper().
427*d83cc019SAndroid Build Coastguard Worker  */
igt_stop_shrink_helper(void)428*d83cc019SAndroid Build Coastguard Worker void igt_stop_shrink_helper(void)
429*d83cc019SAndroid Build Coastguard Worker {
430*d83cc019SAndroid Build Coastguard Worker 	igt_stop_helper(&shrink_helper);
431*d83cc019SAndroid Build Coastguard Worker }
432*d83cc019SAndroid Build Coastguard Worker 
433*d83cc019SAndroid Build Coastguard Worker #ifndef ANDROID
434*d83cc019SAndroid Build Coastguard Worker 
show_kernel_stack(pid_t pid)435*d83cc019SAndroid Build Coastguard Worker static void show_kernel_stack(pid_t pid)
436*d83cc019SAndroid Build Coastguard Worker {
437*d83cc019SAndroid Build Coastguard Worker 	char buf[80], *str;
438*d83cc019SAndroid Build Coastguard Worker 	int dir;
439*d83cc019SAndroid Build Coastguard Worker 
440*d83cc019SAndroid Build Coastguard Worker 	snprintf(buf, sizeof(buf), "/proc/%d", pid);
441*d83cc019SAndroid Build Coastguard Worker 	dir = open(buf, O_RDONLY);
442*d83cc019SAndroid Build Coastguard Worker 	if (dir < 0)
443*d83cc019SAndroid Build Coastguard Worker 		return;
444*d83cc019SAndroid Build Coastguard Worker 
445*d83cc019SAndroid Build Coastguard Worker 	str = igt_sysfs_get(dir, "stack");
446*d83cc019SAndroid Build Coastguard Worker 	if (str) {
447*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Kernel stack for pid %d:\n%s\n", pid, str);
448*d83cc019SAndroid Build Coastguard Worker 		free(str);
449*d83cc019SAndroid Build Coastguard Worker 	}
450*d83cc019SAndroid Build Coastguard Worker 
451*d83cc019SAndroid Build Coastguard Worker 	close(dir);
452*d83cc019SAndroid Build Coastguard Worker }
453*d83cc019SAndroid Build Coastguard Worker 
454*d83cc019SAndroid Build Coastguard Worker static struct igt_helper_process hang_detector;
455*d83cc019SAndroid Build Coastguard Worker static void __attribute__((noreturn))
hang_detector_process(int fd,pid_t pid,dev_t rdev)456*d83cc019SAndroid Build Coastguard Worker hang_detector_process(int fd, pid_t pid, dev_t rdev)
457*d83cc019SAndroid Build Coastguard Worker {
458*d83cc019SAndroid Build Coastguard Worker 	struct udev_monitor *mon =
459*d83cc019SAndroid Build Coastguard Worker 		udev_monitor_new_from_netlink(udev_new(), "kernel");
460*d83cc019SAndroid Build Coastguard Worker 	struct pollfd pfd;
461*d83cc019SAndroid Build Coastguard Worker 	int ret;
462*d83cc019SAndroid Build Coastguard Worker 
463*d83cc019SAndroid Build Coastguard Worker 	udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", NULL);
464*d83cc019SAndroid Build Coastguard Worker 	udev_monitor_enable_receiving(mon);
465*d83cc019SAndroid Build Coastguard Worker 
466*d83cc019SAndroid Build Coastguard Worker 	pfd.fd = udev_monitor_get_fd(mon);
467*d83cc019SAndroid Build Coastguard Worker 	pfd.events = POLLIN;
468*d83cc019SAndroid Build Coastguard Worker 
469*d83cc019SAndroid Build Coastguard Worker 	while ((ret = poll(&pfd, 1, 2000)) >= 0) {
470*d83cc019SAndroid Build Coastguard Worker 		struct udev_device *dev;
471*d83cc019SAndroid Build Coastguard Worker 		dev_t devnum;
472*d83cc019SAndroid Build Coastguard Worker 
473*d83cc019SAndroid Build Coastguard Worker 		if (kill(pid, 0)) { /* Parent has died, so must we. */
474*d83cc019SAndroid Build Coastguard Worker 			igt_warn("Parent died without killing its children (%s)\n",
475*d83cc019SAndroid Build Coastguard Worker 				 __func__);
476*d83cc019SAndroid Build Coastguard Worker 			break;
477*d83cc019SAndroid Build Coastguard Worker 		}
478*d83cc019SAndroid Build Coastguard Worker 
479*d83cc019SAndroid Build Coastguard Worker 		dev = NULL;
480*d83cc019SAndroid Build Coastguard Worker 		if (ret > 0)
481*d83cc019SAndroid Build Coastguard Worker 			dev = udev_monitor_receive_device(mon);
482*d83cc019SAndroid Build Coastguard Worker 		if (dev == NULL)
483*d83cc019SAndroid Build Coastguard Worker 			continue;
484*d83cc019SAndroid Build Coastguard Worker 
485*d83cc019SAndroid Build Coastguard Worker 		devnum = udev_device_get_devnum(dev);
486*d83cc019SAndroid Build Coastguard Worker 		if (memcmp(&rdev, &devnum, sizeof(dev_t)) == 0) {
487*d83cc019SAndroid Build Coastguard Worker 			const char *str;
488*d83cc019SAndroid Build Coastguard Worker 
489*d83cc019SAndroid Build Coastguard Worker 			str = udev_device_get_property_value(dev, "ERROR");
490*d83cc019SAndroid Build Coastguard Worker 			if (str && atoi(str) == 1) {
491*d83cc019SAndroid Build Coastguard Worker 				igt_debugfs_dump(fd, "i915_error_state");
492*d83cc019SAndroid Build Coastguard Worker 				show_kernel_stack(pid);
493*d83cc019SAndroid Build Coastguard Worker 				kill(pid, SIGIO);
494*d83cc019SAndroid Build Coastguard Worker 			}
495*d83cc019SAndroid Build Coastguard Worker 		}
496*d83cc019SAndroid Build Coastguard Worker 
497*d83cc019SAndroid Build Coastguard Worker 		udev_device_unref(dev);
498*d83cc019SAndroid Build Coastguard Worker 	}
499*d83cc019SAndroid Build Coastguard Worker 
500*d83cc019SAndroid Build Coastguard Worker 	exit(0);
501*d83cc019SAndroid Build Coastguard Worker }
502*d83cc019SAndroid Build Coastguard Worker 
sig_abort(int sig)503*d83cc019SAndroid Build Coastguard Worker static void sig_abort(int sig)
504*d83cc019SAndroid Build Coastguard Worker {
505*d83cc019SAndroid Build Coastguard Worker 	errno = 0; /* inside a signal, last errno reporting is confusing */
506*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!"GPU hung");
507*d83cc019SAndroid Build Coastguard Worker }
508*d83cc019SAndroid Build Coastguard Worker 
igt_fork_hang_detector(int fd)509*d83cc019SAndroid Build Coastguard Worker void igt_fork_hang_detector(int fd)
510*d83cc019SAndroid Build Coastguard Worker {
511*d83cc019SAndroid Build Coastguard Worker 	struct stat st;
512*d83cc019SAndroid Build Coastguard Worker 
513*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fstat(fd, &st) == 0);
514*d83cc019SAndroid Build Coastguard Worker 
515*d83cc019SAndroid Build Coastguard Worker 	/*
516*d83cc019SAndroid Build Coastguard Worker 	 * Disable per-engine reset to force an error uevent. We don't
517*d83cc019SAndroid Build Coastguard Worker 	 * expect to get any hangs whilst the detector is enabled (if we do
518*d83cc019SAndroid Build Coastguard Worker 	 * they are a test failure!) and so the loss of per-engine reset
519*d83cc019SAndroid Build Coastguard Worker 	 * functionality is not an issue.
520*d83cc019SAndroid Build Coastguard Worker 	 */
521*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_sysfs_set_parameter
522*d83cc019SAndroid Build Coastguard Worker 		   (fd, "reset", "%d", 1 /* only global reset */));
523*d83cc019SAndroid Build Coastguard Worker 
524*d83cc019SAndroid Build Coastguard Worker 	signal(SIGIO, sig_abort);
525*d83cc019SAndroid Build Coastguard Worker 	igt_fork_helper(&hang_detector)
526*d83cc019SAndroid Build Coastguard Worker 		hang_detector_process(fd, getppid(), st.st_rdev);
527*d83cc019SAndroid Build Coastguard Worker }
528*d83cc019SAndroid Build Coastguard Worker 
igt_stop_hang_detector(void)529*d83cc019SAndroid Build Coastguard Worker void igt_stop_hang_detector(void)
530*d83cc019SAndroid Build Coastguard Worker {
531*d83cc019SAndroid Build Coastguard Worker 	igt_stop_helper(&hang_detector);
532*d83cc019SAndroid Build Coastguard Worker }
533*d83cc019SAndroid Build Coastguard Worker #endif
534*d83cc019SAndroid Build Coastguard Worker 
535*d83cc019SAndroid Build Coastguard Worker /**
536*d83cc019SAndroid Build Coastguard Worker  * igt_check_boolean_env_var:
537*d83cc019SAndroid Build Coastguard Worker  * @env_var: environment variable name
538*d83cc019SAndroid Build Coastguard Worker  * @default_value: default value for the environment variable
539*d83cc019SAndroid Build Coastguard Worker  *
540*d83cc019SAndroid Build Coastguard Worker  * This function should be used to parse boolean environment variable options.
541*d83cc019SAndroid Build Coastguard Worker  *
542*d83cc019SAndroid Build Coastguard Worker  * Returns:
543*d83cc019SAndroid Build Coastguard Worker  * The boolean value of the environment variable @env_var as decoded by atoi()
544*d83cc019SAndroid Build Coastguard Worker  * if it is set and @default_value if the variable is not set.
545*d83cc019SAndroid Build Coastguard Worker  */
igt_check_boolean_env_var(const char * env_var,bool default_value)546*d83cc019SAndroid Build Coastguard Worker bool igt_check_boolean_env_var(const char *env_var, bool default_value)
547*d83cc019SAndroid Build Coastguard Worker {
548*d83cc019SAndroid Build Coastguard Worker 	char *val;
549*d83cc019SAndroid Build Coastguard Worker 
550*d83cc019SAndroid Build Coastguard Worker 	val = getenv(env_var);
551*d83cc019SAndroid Build Coastguard Worker 	if (!val)
552*d83cc019SAndroid Build Coastguard Worker 		return default_value;
553*d83cc019SAndroid Build Coastguard Worker 
554*d83cc019SAndroid Build Coastguard Worker 	return atoi(val) != 0;
555*d83cc019SAndroid Build Coastguard Worker }
556*d83cc019SAndroid Build Coastguard Worker 
557*d83cc019SAndroid Build Coastguard Worker /**
558*d83cc019SAndroid Build Coastguard Worker  * igt_aub_dump_enabled:
559*d83cc019SAndroid Build Coastguard Worker  *
560*d83cc019SAndroid Build Coastguard Worker  * Returns:
561*d83cc019SAndroid Build Coastguard Worker  * True if AUB dumping is enabled with IGT_DUMP_AUB=1 in the environment, false
562*d83cc019SAndroid Build Coastguard Worker  * otherwise.
563*d83cc019SAndroid Build Coastguard Worker  */
igt_aub_dump_enabled(void)564*d83cc019SAndroid Build Coastguard Worker bool igt_aub_dump_enabled(void)
565*d83cc019SAndroid Build Coastguard Worker {
566*d83cc019SAndroid Build Coastguard Worker 	static int dump_aub = -1;
567*d83cc019SAndroid Build Coastguard Worker 
568*d83cc019SAndroid Build Coastguard Worker 	if (dump_aub == -1)
569*d83cc019SAndroid Build Coastguard Worker 		dump_aub = igt_check_boolean_env_var("IGT_DUMP_AUB", false);
570*d83cc019SAndroid Build Coastguard Worker 
571*d83cc019SAndroid Build Coastguard Worker 	return dump_aub;
572*d83cc019SAndroid Build Coastguard Worker }
573*d83cc019SAndroid Build Coastguard Worker 
574*d83cc019SAndroid Build Coastguard Worker /* other helpers */
575*d83cc019SAndroid Build Coastguard Worker /**
576*d83cc019SAndroid Build Coastguard Worker  * igt_exchange_int:
577*d83cc019SAndroid Build Coastguard Worker  * @array: pointer to the array of integers
578*d83cc019SAndroid Build Coastguard Worker  * @i: first position
579*d83cc019SAndroid Build Coastguard Worker  * @j: second position
580*d83cc019SAndroid Build Coastguard Worker  *
581*d83cc019SAndroid Build Coastguard Worker  * Exchanges the two values at array indices @i and @j. Useful as an exchange
582*d83cc019SAndroid Build Coastguard Worker  * function for igt_permute_array().
583*d83cc019SAndroid Build Coastguard Worker  */
igt_exchange_int(void * array,unsigned i,unsigned j)584*d83cc019SAndroid Build Coastguard Worker void igt_exchange_int(void *array, unsigned i, unsigned j)
585*d83cc019SAndroid Build Coastguard Worker {
586*d83cc019SAndroid Build Coastguard Worker 	int *int_arr, tmp;
587*d83cc019SAndroid Build Coastguard Worker 	int_arr = array;
588*d83cc019SAndroid Build Coastguard Worker 
589*d83cc019SAndroid Build Coastguard Worker 	tmp = int_arr[i];
590*d83cc019SAndroid Build Coastguard Worker 	int_arr[i] = int_arr[j];
591*d83cc019SAndroid Build Coastguard Worker 	int_arr[j] = tmp;
592*d83cc019SAndroid Build Coastguard Worker }
593*d83cc019SAndroid Build Coastguard Worker 
594*d83cc019SAndroid Build Coastguard Worker /**
595*d83cc019SAndroid Build Coastguard Worker  * igt_exchange_int64:
596*d83cc019SAndroid Build Coastguard Worker  * @array: pointer to the array of int64_t
597*d83cc019SAndroid Build Coastguard Worker  * @i: first position
598*d83cc019SAndroid Build Coastguard Worker  * @j: second position
599*d83cc019SAndroid Build Coastguard Worker  *
600*d83cc019SAndroid Build Coastguard Worker  * Exchanges the two values at array indices @i and @j. Useful as an exchange
601*d83cc019SAndroid Build Coastguard Worker  * function for igt_permute_array().
602*d83cc019SAndroid Build Coastguard Worker  */
igt_exchange_int64(void * array,unsigned i,unsigned j)603*d83cc019SAndroid Build Coastguard Worker void igt_exchange_int64(void *array, unsigned i, unsigned j)
604*d83cc019SAndroid Build Coastguard Worker {
605*d83cc019SAndroid Build Coastguard Worker 	int64_t *a = array;
606*d83cc019SAndroid Build Coastguard Worker 
607*d83cc019SAndroid Build Coastguard Worker 	igt_swap(a[i], a[j]);
608*d83cc019SAndroid Build Coastguard Worker }
609*d83cc019SAndroid Build Coastguard Worker 
610*d83cc019SAndroid Build Coastguard Worker /**
611*d83cc019SAndroid Build Coastguard Worker  * igt_permute_array:
612*d83cc019SAndroid Build Coastguard Worker  * @array: pointer to array
613*d83cc019SAndroid Build Coastguard Worker  * @size: size of the array
614*d83cc019SAndroid Build Coastguard Worker  * @exchange_func: function to exchange array elements
615*d83cc019SAndroid Build Coastguard Worker  *
616*d83cc019SAndroid Build Coastguard Worker  * This function randomly permutes the array using random() as the PRNG source.
617*d83cc019SAndroid Build Coastguard Worker  * The @exchange_func function is called to exchange two elements in the array
618*d83cc019SAndroid Build Coastguard Worker  * when needed.
619*d83cc019SAndroid Build Coastguard Worker  */
igt_permute_array(void * array,unsigned size,void (* exchange_func)(void * array,unsigned i,unsigned j))620*d83cc019SAndroid Build Coastguard Worker void igt_permute_array(void *array, unsigned size,
621*d83cc019SAndroid Build Coastguard Worker                        void (*exchange_func)(void *array,
622*d83cc019SAndroid Build Coastguard Worker                                              unsigned i,
623*d83cc019SAndroid Build Coastguard Worker                                              unsigned j))
624*d83cc019SAndroid Build Coastguard Worker {
625*d83cc019SAndroid Build Coastguard Worker 	int i;
626*d83cc019SAndroid Build Coastguard Worker 
627*d83cc019SAndroid Build Coastguard Worker 	for (i = size - 1; i > 0; i--) {
628*d83cc019SAndroid Build Coastguard Worker 		/* yes, not perfectly uniform, who cares */
629*d83cc019SAndroid Build Coastguard Worker 		long l = hars_petruska_f54_1_random_unsafe() % (i +1);
630*d83cc019SAndroid Build Coastguard Worker 		if (i != l)
631*d83cc019SAndroid Build Coastguard Worker 			exchange_func(array, i, l);
632*d83cc019SAndroid Build Coastguard Worker 	}
633*d83cc019SAndroid Build Coastguard Worker }
634*d83cc019SAndroid Build Coastguard Worker 
635*d83cc019SAndroid Build Coastguard Worker __attribute__((format(printf, 1, 2)))
igt_interactive_info(const char * format,...)636*d83cc019SAndroid Build Coastguard Worker static void igt_interactive_info(const char *format, ...)
637*d83cc019SAndroid Build Coastguard Worker {
638*d83cc019SAndroid Build Coastguard Worker 	va_list args;
639*d83cc019SAndroid Build Coastguard Worker 
640*d83cc019SAndroid Build Coastguard Worker 	if (!isatty(STDERR_FILENO) || __igt_plain_output) {
641*d83cc019SAndroid Build Coastguard Worker 		errno = 0; /* otherwise would be either ENOTTY or EBADF */
642*d83cc019SAndroid Build Coastguard Worker 		return;
643*d83cc019SAndroid Build Coastguard Worker 	}
644*d83cc019SAndroid Build Coastguard Worker 
645*d83cc019SAndroid Build Coastguard Worker 	if (igt_log_level > IGT_LOG_INFO)
646*d83cc019SAndroid Build Coastguard Worker 		return;
647*d83cc019SAndroid Build Coastguard Worker 
648*d83cc019SAndroid Build Coastguard Worker 	va_start(args, format);
649*d83cc019SAndroid Build Coastguard Worker 	vfprintf(stderr, format, args);
650*d83cc019SAndroid Build Coastguard Worker 	va_end(args);
651*d83cc019SAndroid Build Coastguard Worker }
652*d83cc019SAndroid Build Coastguard Worker 
653*d83cc019SAndroid Build Coastguard Worker 
654*d83cc019SAndroid Build Coastguard Worker /**
655*d83cc019SAndroid Build Coastguard Worker  * igt_progress:
656*d83cc019SAndroid Build Coastguard Worker  * @header: header string to prepend to the progress indicator
657*d83cc019SAndroid Build Coastguard Worker  * @i: work processed thus far
658*d83cc019SAndroid Build Coastguard Worker  * @total: total amount of work
659*d83cc019SAndroid Build Coastguard Worker  *
660*d83cc019SAndroid Build Coastguard Worker  * This function draws a progress indicator, which is useful for running
661*d83cc019SAndroid Build Coastguard Worker  * long-winded tests manually on the console. To avoid spamming log files in
662*d83cc019SAndroid Build Coastguard Worker  * automated runs the progress indicator is suppressed when not running on a
663*d83cc019SAndroid Build Coastguard Worker  * terminal.
664*d83cc019SAndroid Build Coastguard Worker  */
igt_progress(const char * header,uint64_t i,uint64_t total)665*d83cc019SAndroid Build Coastguard Worker void igt_progress(const char *header, uint64_t i, uint64_t total)
666*d83cc019SAndroid Build Coastguard Worker {
667*d83cc019SAndroid Build Coastguard Worker 	int divider = 200;
668*d83cc019SAndroid Build Coastguard Worker 
669*d83cc019SAndroid Build Coastguard Worker 	if (i+1 >= total) {
670*d83cc019SAndroid Build Coastguard Worker 		igt_interactive_info("\r%s100%%\n", header);
671*d83cc019SAndroid Build Coastguard Worker 		return;
672*d83cc019SAndroid Build Coastguard Worker 	}
673*d83cc019SAndroid Build Coastguard Worker 
674*d83cc019SAndroid Build Coastguard Worker 	if (total / 200 == 0)
675*d83cc019SAndroid Build Coastguard Worker 		divider = 1;
676*d83cc019SAndroid Build Coastguard Worker 
677*d83cc019SAndroid Build Coastguard Worker 	/* only bother updating about every 0.5% */
678*d83cc019SAndroid Build Coastguard Worker 	if (i % (total / divider) == 0)
679*d83cc019SAndroid Build Coastguard Worker 		igt_interactive_info("\r%s%3llu%%", header,
680*d83cc019SAndroid Build Coastguard Worker 				     (long long unsigned)i * 100 / total);
681*d83cc019SAndroid Build Coastguard Worker }
682*d83cc019SAndroid Build Coastguard Worker 
683*d83cc019SAndroid Build Coastguard Worker /**
684*d83cc019SAndroid Build Coastguard Worker  * igt_print_activity:
685*d83cc019SAndroid Build Coastguard Worker  *
686*d83cc019SAndroid Build Coastguard Worker  * Print a '.' to indicate activity. This is printed without a newline and
687*d83cc019SAndroid Build Coastguard Worker  * only if output is to a terminal.
688*d83cc019SAndroid Build Coastguard Worker  */
igt_print_activity(void)689*d83cc019SAndroid Build Coastguard Worker void igt_print_activity(void)
690*d83cc019SAndroid Build Coastguard Worker {
691*d83cc019SAndroid Build Coastguard Worker 	igt_interactive_info(".");
692*d83cc019SAndroid Build Coastguard Worker }
693*d83cc019SAndroid Build Coastguard Worker 
694*d83cc019SAndroid Build Coastguard Worker static int autoresume_delay;
695*d83cc019SAndroid Build Coastguard Worker 
696*d83cc019SAndroid Build Coastguard Worker static const char *suspend_state_name[] = {
697*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_STATE_FREEZE] = "freeze",
698*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_STATE_STANDBY] = "standby",
699*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_STATE_MEM] = "mem",
700*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_STATE_DISK] = "disk",
701*d83cc019SAndroid Build Coastguard Worker };
702*d83cc019SAndroid Build Coastguard Worker 
703*d83cc019SAndroid Build Coastguard Worker static const char *suspend_test_name[] = {
704*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_TEST_NONE] = "none",
705*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_TEST_FREEZER] = "freezer",
706*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_TEST_DEVICES] = "devices",
707*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_TEST_PLATFORM] = "platform",
708*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_TEST_PROCESSORS] = "processors",
709*d83cc019SAndroid Build Coastguard Worker 	[SUSPEND_TEST_CORE] = "core",
710*d83cc019SAndroid Build Coastguard Worker };
711*d83cc019SAndroid Build Coastguard Worker 
get_suspend_test(int power_dir)712*d83cc019SAndroid Build Coastguard Worker static enum igt_suspend_test get_suspend_test(int power_dir)
713*d83cc019SAndroid Build Coastguard Worker {
714*d83cc019SAndroid Build Coastguard Worker 	char *test_line;
715*d83cc019SAndroid Build Coastguard Worker 	char *test_name;
716*d83cc019SAndroid Build Coastguard Worker 	enum igt_suspend_test test;
717*d83cc019SAndroid Build Coastguard Worker 
718*d83cc019SAndroid Build Coastguard Worker 	if (faccessat(power_dir, "pm_test", R_OK, 0))
719*d83cc019SAndroid Build Coastguard Worker 		return SUSPEND_TEST_NONE;
720*d83cc019SAndroid Build Coastguard Worker 
721*d83cc019SAndroid Build Coastguard Worker 	igt_assert((test_line = igt_sysfs_get(power_dir, "pm_test")));
722*d83cc019SAndroid Build Coastguard Worker 	for (test_name = strtok(test_line, " "); test_name;
723*d83cc019SAndroid Build Coastguard Worker 	     test_name = strtok(NULL, " "))
724*d83cc019SAndroid Build Coastguard Worker 		if (test_name[0] == '[') {
725*d83cc019SAndroid Build Coastguard Worker 			test_name[strlen(test_name) - 1] = '\0';
726*d83cc019SAndroid Build Coastguard Worker 			test_name++;
727*d83cc019SAndroid Build Coastguard Worker 			break;
728*d83cc019SAndroid Build Coastguard Worker 		}
729*d83cc019SAndroid Build Coastguard Worker 
730*d83cc019SAndroid Build Coastguard Worker 	if (!test_name) {
731*d83cc019SAndroid Build Coastguard Worker 	  	free(test_line);
732*d83cc019SAndroid Build Coastguard Worker 		return SUSPEND_TEST_NONE;
733*d83cc019SAndroid Build Coastguard Worker 	}
734*d83cc019SAndroid Build Coastguard Worker 
735*d83cc019SAndroid Build Coastguard Worker 	for (test = SUSPEND_TEST_NONE; test < SUSPEND_TEST_NUM; test++)
736*d83cc019SAndroid Build Coastguard Worker 		if (strcmp(suspend_test_name[test], test_name) == 0)
737*d83cc019SAndroid Build Coastguard Worker 			break;
738*d83cc019SAndroid Build Coastguard Worker 
739*d83cc019SAndroid Build Coastguard Worker 	igt_assert(test < SUSPEND_TEST_NUM);
740*d83cc019SAndroid Build Coastguard Worker 
741*d83cc019SAndroid Build Coastguard Worker 	free(test_line);
742*d83cc019SAndroid Build Coastguard Worker 	return test;
743*d83cc019SAndroid Build Coastguard Worker }
744*d83cc019SAndroid Build Coastguard Worker 
set_suspend_test(int power_dir,enum igt_suspend_test test)745*d83cc019SAndroid Build Coastguard Worker static void set_suspend_test(int power_dir, enum igt_suspend_test test)
746*d83cc019SAndroid Build Coastguard Worker {
747*d83cc019SAndroid Build Coastguard Worker 	igt_assert(test < SUSPEND_TEST_NUM);
748*d83cc019SAndroid Build Coastguard Worker 
749*d83cc019SAndroid Build Coastguard Worker 	if (faccessat(power_dir, "pm_test", W_OK, 0)) {
750*d83cc019SAndroid Build Coastguard Worker 		igt_require(test == SUSPEND_TEST_NONE);
751*d83cc019SAndroid Build Coastguard Worker 		return;
752*d83cc019SAndroid Build Coastguard Worker 	}
753*d83cc019SAndroid Build Coastguard Worker 
754*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_sysfs_set(power_dir, "pm_test", suspend_test_name[test]));
755*d83cc019SAndroid Build Coastguard Worker }
756*d83cc019SAndroid Build Coastguard Worker 
757*d83cc019SAndroid Build Coastguard Worker #define SQUELCH ">/dev/null 2>&1"
758*d83cc019SAndroid Build Coastguard Worker 
suspend_via_rtcwake(enum igt_suspend_state state)759*d83cc019SAndroid Build Coastguard Worker static void suspend_via_rtcwake(enum igt_suspend_state state)
760*d83cc019SAndroid Build Coastguard Worker {
761*d83cc019SAndroid Build Coastguard Worker 	char cmd[128];
762*d83cc019SAndroid Build Coastguard Worker 	int delay, ret;
763*d83cc019SAndroid Build Coastguard Worker 
764*d83cc019SAndroid Build Coastguard Worker 	igt_assert(state < SUSPEND_STATE_NUM);
765*d83cc019SAndroid Build Coastguard Worker 
766*d83cc019SAndroid Build Coastguard Worker 	delay = igt_get_autoresume_delay(state);
767*d83cc019SAndroid Build Coastguard Worker 
768*d83cc019SAndroid Build Coastguard Worker 	/*
769*d83cc019SAndroid Build Coastguard Worker 	 * Skip if rtcwake would fail for a reason not related to the kernel's
770*d83cc019SAndroid Build Coastguard Worker 	 * suspend functionality.
771*d83cc019SAndroid Build Coastguard Worker 	 */
772*d83cc019SAndroid Build Coastguard Worker 	snprintf(cmd, sizeof(cmd), "rtcwake -n -s %d -m %s " SQUELCH,
773*d83cc019SAndroid Build Coastguard Worker 		 delay, suspend_state_name[state]);
774*d83cc019SAndroid Build Coastguard Worker 	ret = igt_system(cmd);
775*d83cc019SAndroid Build Coastguard Worker 	igt_require_f(ret == 0, "rtcwake test failed with %i\n"
776*d83cc019SAndroid Build Coastguard Worker 		     "This failure could mean that something is wrong with "
777*d83cc019SAndroid Build Coastguard Worker 		     "the rtcwake tool or how your distro is set up.\n",
778*d83cc019SAndroid Build Coastguard Worker 		      ret);
779*d83cc019SAndroid Build Coastguard Worker 
780*d83cc019SAndroid Build Coastguard Worker 	snprintf(cmd, sizeof(cmd), "rtcwake -s %d -m %s ",
781*d83cc019SAndroid Build Coastguard Worker 		 delay, suspend_state_name[state]);
782*d83cc019SAndroid Build Coastguard Worker 	ret = igt_system(cmd);
783*d83cc019SAndroid Build Coastguard Worker 	if (ret) {
784*d83cc019SAndroid Build Coastguard Worker 		const char *path = "suspend_stats";
785*d83cc019SAndroid Build Coastguard Worker 		char *info;
786*d83cc019SAndroid Build Coastguard Worker 		int dir;
787*d83cc019SAndroid Build Coastguard Worker 
788*d83cc019SAndroid Build Coastguard Worker 		igt_warn("rtcwake failed with %i\n"
789*d83cc019SAndroid Build Coastguard Worker 			 "Check dmesg for further details.\n",
790*d83cc019SAndroid Build Coastguard Worker 			 ret);
791*d83cc019SAndroid Build Coastguard Worker 
792*d83cc019SAndroid Build Coastguard Worker 		dir = open(igt_debugfs_mount(), O_RDONLY);
793*d83cc019SAndroid Build Coastguard Worker 		info = igt_sysfs_get(dir, path);
794*d83cc019SAndroid Build Coastguard Worker 		close(dir);
795*d83cc019SAndroid Build Coastguard Worker 		if (info) {
796*d83cc019SAndroid Build Coastguard Worker 			igt_debug("%s:\n%s\n", path, info);
797*d83cc019SAndroid Build Coastguard Worker 			free(info);
798*d83cc019SAndroid Build Coastguard Worker 		}
799*d83cc019SAndroid Build Coastguard Worker 	}
800*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
801*d83cc019SAndroid Build Coastguard Worker }
802*d83cc019SAndroid Build Coastguard Worker 
suspend_via_sysfs(int power_dir,enum igt_suspend_state state)803*d83cc019SAndroid Build Coastguard Worker static void suspend_via_sysfs(int power_dir, enum igt_suspend_state state)
804*d83cc019SAndroid Build Coastguard Worker {
805*d83cc019SAndroid Build Coastguard Worker 	igt_assert(state < SUSPEND_STATE_NUM);
806*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_sysfs_set(power_dir, "state",
807*d83cc019SAndroid Build Coastguard Worker 				 suspend_state_name[state]));
808*d83cc019SAndroid Build Coastguard Worker }
809*d83cc019SAndroid Build Coastguard Worker 
get_supported_suspend_states(int power_dir)810*d83cc019SAndroid Build Coastguard Worker static uint32_t get_supported_suspend_states(int power_dir)
811*d83cc019SAndroid Build Coastguard Worker {
812*d83cc019SAndroid Build Coastguard Worker 	char *states;
813*d83cc019SAndroid Build Coastguard Worker 	char *state_name;
814*d83cc019SAndroid Build Coastguard Worker 	uint32_t state_mask;
815*d83cc019SAndroid Build Coastguard Worker 
816*d83cc019SAndroid Build Coastguard Worker 	igt_assert((states = igt_sysfs_get(power_dir, "state")));
817*d83cc019SAndroid Build Coastguard Worker 	state_mask = 0;
818*d83cc019SAndroid Build Coastguard Worker 	for (state_name = strtok(states, " "); state_name;
819*d83cc019SAndroid Build Coastguard Worker 	     state_name = strtok(NULL, " ")) {
820*d83cc019SAndroid Build Coastguard Worker 		enum igt_suspend_state state;
821*d83cc019SAndroid Build Coastguard Worker 
822*d83cc019SAndroid Build Coastguard Worker 		for (state = SUSPEND_STATE_FREEZE; state < SUSPEND_STATE_NUM;
823*d83cc019SAndroid Build Coastguard Worker 		     state++)
824*d83cc019SAndroid Build Coastguard Worker 			if (strcmp(state_name, suspend_state_name[state]) == 0)
825*d83cc019SAndroid Build Coastguard Worker 				break;
826*d83cc019SAndroid Build Coastguard Worker 		igt_assert(state < SUSPEND_STATE_NUM);
827*d83cc019SAndroid Build Coastguard Worker 		state_mask |= 1 << state;
828*d83cc019SAndroid Build Coastguard Worker 	}
829*d83cc019SAndroid Build Coastguard Worker 
830*d83cc019SAndroid Build Coastguard Worker 	free(states);
831*d83cc019SAndroid Build Coastguard Worker 
832*d83cc019SAndroid Build Coastguard Worker 	return state_mask;
833*d83cc019SAndroid Build Coastguard Worker }
834*d83cc019SAndroid Build Coastguard Worker 
835*d83cc019SAndroid Build Coastguard Worker /**
836*d83cc019SAndroid Build Coastguard Worker  * igt_system_suspend_autoresume:
837*d83cc019SAndroid Build Coastguard Worker  * @state: an #igt_suspend_state, the target suspend state
838*d83cc019SAndroid Build Coastguard Worker  * @test: an #igt_suspend_test, test point at which to complete the suspend
839*d83cc019SAndroid Build Coastguard Worker  *	  cycle
840*d83cc019SAndroid Build Coastguard Worker  *
841*d83cc019SAndroid Build Coastguard Worker  * Execute a system suspend cycle targeting the given @state optionally
842*d83cc019SAndroid Build Coastguard Worker  * completing the cycle at the given @test point and automaically wake up
843*d83cc019SAndroid Build Coastguard Worker  * again. Waking up is either achieved using the RTC wake-up alarm for a full
844*d83cc019SAndroid Build Coastguard Worker  * suspend cycle or a kernel timer for a suspend test cycle. The kernel timer
845*d83cc019SAndroid Build Coastguard Worker  * delay for a test cycle can be configured by the suspend.pm_test_delay
846*d83cc019SAndroid Build Coastguard Worker  * kernel parameter (5 sec by default).
847*d83cc019SAndroid Build Coastguard Worker  *
848*d83cc019SAndroid Build Coastguard Worker  * #SUSPEND_TEST_NONE specifies a full suspend cycle.
849*d83cc019SAndroid Build Coastguard Worker  * The #SUSPEND_TEST_FREEZER..#SUSPEND_TEST_CORE test points can make it
850*d83cc019SAndroid Build Coastguard Worker  * possible to collect error logs in case a full suspend cycle would prevent
851*d83cc019SAndroid Build Coastguard Worker  * this by hanging the machine, or they can provide an idea of the faulty
852*d83cc019SAndroid Build Coastguard Worker  * component by comparing fail/no-fail results at different test points.
853*d83cc019SAndroid Build Coastguard Worker  *
854*d83cc019SAndroid Build Coastguard Worker  * This is very handy for implementing any kind of suspend/resume test.
855*d83cc019SAndroid Build Coastguard Worker  */
igt_system_suspend_autoresume(enum igt_suspend_state state,enum igt_suspend_test test)856*d83cc019SAndroid Build Coastguard Worker void igt_system_suspend_autoresume(enum igt_suspend_state state,
857*d83cc019SAndroid Build Coastguard Worker 				   enum igt_suspend_test test)
858*d83cc019SAndroid Build Coastguard Worker {
859*d83cc019SAndroid Build Coastguard Worker 	int power_dir;
860*d83cc019SAndroid Build Coastguard Worker 	enum igt_suspend_test orig_test;
861*d83cc019SAndroid Build Coastguard Worker 
862*d83cc019SAndroid Build Coastguard Worker 	/* FIXME: Simulation doesn't like suspend/resume, and not even a lighter
863*d83cc019SAndroid Build Coastguard Worker 	 * approach using /sys/power/pm_test to just test our driver's callbacks
864*d83cc019SAndroid Build Coastguard Worker 	 * seems to fare better. We need to investigate what's going on. */
865*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
866*d83cc019SAndroid Build Coastguard Worker 
867*d83cc019SAndroid Build Coastguard Worker 	igt_require((power_dir = open("/sys/power", O_RDONLY)) >= 0);
868*d83cc019SAndroid Build Coastguard Worker 	igt_require(get_supported_suspend_states(power_dir) & (1 << state));
869*d83cc019SAndroid Build Coastguard Worker 	igt_require(test == SUSPEND_TEST_NONE ||
870*d83cc019SAndroid Build Coastguard Worker 		    faccessat(power_dir, "pm_test", R_OK | W_OK, 0) == 0);
871*d83cc019SAndroid Build Coastguard Worker 
872*d83cc019SAndroid Build Coastguard Worker 	orig_test = get_suspend_test(power_dir);
873*d83cc019SAndroid Build Coastguard Worker 	set_suspend_test(power_dir, test);
874*d83cc019SAndroid Build Coastguard Worker 
875*d83cc019SAndroid Build Coastguard Worker 	if (test == SUSPEND_TEST_NONE)
876*d83cc019SAndroid Build Coastguard Worker 		suspend_via_rtcwake(state);
877*d83cc019SAndroid Build Coastguard Worker 	else
878*d83cc019SAndroid Build Coastguard Worker 		suspend_via_sysfs(power_dir, state);
879*d83cc019SAndroid Build Coastguard Worker 
880*d83cc019SAndroid Build Coastguard Worker 	set_suspend_test(power_dir, orig_test);
881*d83cc019SAndroid Build Coastguard Worker 	close(power_dir);
882*d83cc019SAndroid Build Coastguard Worker }
883*d83cc019SAndroid Build Coastguard Worker 
884*d83cc019SAndroid Build Coastguard Worker static int original_autoresume_delay;
885*d83cc019SAndroid Build Coastguard Worker 
igt_restore_autoresume_delay(int sig)886*d83cc019SAndroid Build Coastguard Worker static void igt_restore_autoresume_delay(int sig)
887*d83cc019SAndroid Build Coastguard Worker {
888*d83cc019SAndroid Build Coastguard Worker 	int delay_fd;
889*d83cc019SAndroid Build Coastguard Worker 	char delay_str[10];
890*d83cc019SAndroid Build Coastguard Worker 
891*d83cc019SAndroid Build Coastguard Worker 	igt_require((delay_fd = open("/sys/module/suspend/parameters/pm_test_delay",
892*d83cc019SAndroid Build Coastguard Worker 				    O_WRONLY)) >= 0);
893*d83cc019SAndroid Build Coastguard Worker 
894*d83cc019SAndroid Build Coastguard Worker 	snprintf(delay_str, sizeof(delay_str), "%d", original_autoresume_delay);
895*d83cc019SAndroid Build Coastguard Worker 	igt_require(write(delay_fd, delay_str, strlen(delay_str)));
896*d83cc019SAndroid Build Coastguard Worker 
897*d83cc019SAndroid Build Coastguard Worker 	close(delay_fd);
898*d83cc019SAndroid Build Coastguard Worker }
899*d83cc019SAndroid Build Coastguard Worker 
900*d83cc019SAndroid Build Coastguard Worker /**
901*d83cc019SAndroid Build Coastguard Worker  * igt_set_autoresume_delay:
902*d83cc019SAndroid Build Coastguard Worker  * @delay_secs: The delay in seconds before resuming the system
903*d83cc019SAndroid Build Coastguard Worker  *
904*d83cc019SAndroid Build Coastguard Worker  * Sets how long we wait to resume the system after suspending it, using the
905*d83cc019SAndroid Build Coastguard Worker  * suspend.pm_test_delay variable. On exit, the original delay value is
906*d83cc019SAndroid Build Coastguard Worker  * restored.
907*d83cc019SAndroid Build Coastguard Worker  */
igt_set_autoresume_delay(int delay_secs)908*d83cc019SAndroid Build Coastguard Worker void igt_set_autoresume_delay(int delay_secs)
909*d83cc019SAndroid Build Coastguard Worker {
910*d83cc019SAndroid Build Coastguard Worker 	int delay_fd;
911*d83cc019SAndroid Build Coastguard Worker 	char delay_str[10];
912*d83cc019SAndroid Build Coastguard Worker 
913*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
914*d83cc019SAndroid Build Coastguard Worker 
915*d83cc019SAndroid Build Coastguard Worker 	delay_fd = open("/sys/module/suspend/parameters/pm_test_delay", O_RDWR);
916*d83cc019SAndroid Build Coastguard Worker 
917*d83cc019SAndroid Build Coastguard Worker 	if (delay_fd >= 0) {
918*d83cc019SAndroid Build Coastguard Worker 		if (!original_autoresume_delay) {
919*d83cc019SAndroid Build Coastguard Worker 			igt_require(read(delay_fd, delay_str,
920*d83cc019SAndroid Build Coastguard Worker 					 sizeof(delay_str)));
921*d83cc019SAndroid Build Coastguard Worker 			original_autoresume_delay = atoi(delay_str);
922*d83cc019SAndroid Build Coastguard Worker 			igt_install_exit_handler(igt_restore_autoresume_delay);
923*d83cc019SAndroid Build Coastguard Worker 		}
924*d83cc019SAndroid Build Coastguard Worker 
925*d83cc019SAndroid Build Coastguard Worker 		snprintf(delay_str, sizeof(delay_str), "%d", delay_secs);
926*d83cc019SAndroid Build Coastguard Worker 		igt_require(write(delay_fd, delay_str, strlen(delay_str)));
927*d83cc019SAndroid Build Coastguard Worker 
928*d83cc019SAndroid Build Coastguard Worker 		close(delay_fd);
929*d83cc019SAndroid Build Coastguard Worker 	}
930*d83cc019SAndroid Build Coastguard Worker 
931*d83cc019SAndroid Build Coastguard Worker 	autoresume_delay = delay_secs;
932*d83cc019SAndroid Build Coastguard Worker }
933*d83cc019SAndroid Build Coastguard Worker 
934*d83cc019SAndroid Build Coastguard Worker /**
935*d83cc019SAndroid Build Coastguard Worker  * igt_get_autoresume_delay:
936*d83cc019SAndroid Build Coastguard Worker  * @state: an #igt_suspend_state, the target suspend state
937*d83cc019SAndroid Build Coastguard Worker  *
938*d83cc019SAndroid Build Coastguard Worker  * Retrieves how long we wait to resume the system after suspending it.
939*d83cc019SAndroid Build Coastguard Worker  * This can either be set through igt_set_autoresume_delay or be a default
940*d83cc019SAndroid Build Coastguard Worker  * value that depends on the suspend state.
941*d83cc019SAndroid Build Coastguard Worker  *
942*d83cc019SAndroid Build Coastguard Worker  * Returns: The autoresume delay, in seconds.
943*d83cc019SAndroid Build Coastguard Worker  */
igt_get_autoresume_delay(enum igt_suspend_state state)944*d83cc019SAndroid Build Coastguard Worker int igt_get_autoresume_delay(enum igt_suspend_state state)
945*d83cc019SAndroid Build Coastguard Worker {
946*d83cc019SAndroid Build Coastguard Worker 	int delay;
947*d83cc019SAndroid Build Coastguard Worker 
948*d83cc019SAndroid Build Coastguard Worker 	if (autoresume_delay)
949*d83cc019SAndroid Build Coastguard Worker 		delay = autoresume_delay;
950*d83cc019SAndroid Build Coastguard Worker 	else
951*d83cc019SAndroid Build Coastguard Worker 		delay = state == SUSPEND_STATE_DISK ? 30 : 15;
952*d83cc019SAndroid Build Coastguard Worker 
953*d83cc019SAndroid Build Coastguard Worker 	return delay;
954*d83cc019SAndroid Build Coastguard Worker }
955*d83cc019SAndroid Build Coastguard Worker 
956*d83cc019SAndroid Build Coastguard Worker /**
957*d83cc019SAndroid Build Coastguard Worker  * igt_drop_root:
958*d83cc019SAndroid Build Coastguard Worker  *
959*d83cc019SAndroid Build Coastguard Worker  * Drop root privileges and make sure it actually worked. Useful for tests
960*d83cc019SAndroid Build Coastguard Worker  * which need to check security constraints. Note that this should only be
961*d83cc019SAndroid Build Coastguard Worker  * called from manually forked processes, since the lack of root privileges
962*d83cc019SAndroid Build Coastguard Worker  * will wreak havoc with the automatic cleanup handlers.
963*d83cc019SAndroid Build Coastguard Worker  */
igt_drop_root(void)964*d83cc019SAndroid Build Coastguard Worker void igt_drop_root(void)
965*d83cc019SAndroid Build Coastguard Worker {
966*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(getuid(), 0);
967*d83cc019SAndroid Build Coastguard Worker 
968*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(setgroups(0, NULL), 0);
969*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(setgid(2), 0);
970*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(setuid(2), 0);
971*d83cc019SAndroid Build Coastguard Worker 
972*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(getgroups(0, NULL), 0);
973*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(getgid(), 2);
974*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(getuid(), 2);
975*d83cc019SAndroid Build Coastguard Worker }
976*d83cc019SAndroid Build Coastguard Worker 
977*d83cc019SAndroid Build Coastguard Worker /**
978*d83cc019SAndroid Build Coastguard Worker  * igt_debug_wait_for_keypress:
979*d83cc019SAndroid Build Coastguard Worker  * @var: var lookup to to enable this wait
980*d83cc019SAndroid Build Coastguard Worker  *
981*d83cc019SAndroid Build Coastguard Worker  * Waits for a key press when run interactively and when the corresponding debug
982*d83cc019SAndroid Build Coastguard Worker  * var is set in the --interactive-debug=$var variable. Multiple keys
983*d83cc019SAndroid Build Coastguard Worker  * can be specified as a comma-separated list or alternatively "all" if a wait
984*d83cc019SAndroid Build Coastguard Worker  * should happen for all cases.
985*d83cc019SAndroid Build Coastguard Worker  *
986*d83cc019SAndroid Build Coastguard Worker  * When not connected to a terminal interactive_debug is ignored
987*d83cc019SAndroid Build Coastguard Worker  * and execution immediately continues.
988*d83cc019SAndroid Build Coastguard Worker  *
989*d83cc019SAndroid Build Coastguard Worker  * This is useful for display tests where under certain situation manual
990*d83cc019SAndroid Build Coastguard Worker  * inspection of the display is useful. Or when running a testcase in the
991*d83cc019SAndroid Build Coastguard Worker  * background.
992*d83cc019SAndroid Build Coastguard Worker  */
igt_debug_wait_for_keypress(const char * var)993*d83cc019SAndroid Build Coastguard Worker void igt_debug_wait_for_keypress(const char *var)
994*d83cc019SAndroid Build Coastguard Worker {
995*d83cc019SAndroid Build Coastguard Worker 	struct termios oldt, newt;
996*d83cc019SAndroid Build Coastguard Worker 
997*d83cc019SAndroid Build Coastguard Worker 	if (!isatty(STDIN_FILENO)) {
998*d83cc019SAndroid Build Coastguard Worker 		errno = 0; /* otherwise would be either ENOTTY or EBADF */
999*d83cc019SAndroid Build Coastguard Worker 		return;
1000*d83cc019SAndroid Build Coastguard Worker 	}
1001*d83cc019SAndroid Build Coastguard Worker 
1002*d83cc019SAndroid Build Coastguard Worker 	if (!igt_interactive_debug)
1003*d83cc019SAndroid Build Coastguard Worker 		return;
1004*d83cc019SAndroid Build Coastguard Worker 
1005*d83cc019SAndroid Build Coastguard Worker 	if (!strstr(igt_interactive_debug, var) &&
1006*d83cc019SAndroid Build Coastguard Worker 	    !strstr(igt_interactive_debug, "all"))
1007*d83cc019SAndroid Build Coastguard Worker 		return;
1008*d83cc019SAndroid Build Coastguard Worker 
1009*d83cc019SAndroid Build Coastguard Worker 	igt_info("Press any key to continue ...\n");
1010*d83cc019SAndroid Build Coastguard Worker 
1011*d83cc019SAndroid Build Coastguard Worker 	tcgetattr ( STDIN_FILENO, &oldt );
1012*d83cc019SAndroid Build Coastguard Worker 	newt = oldt;
1013*d83cc019SAndroid Build Coastguard Worker 	newt.c_lflag &= ~( ICANON | ECHO );
1014*d83cc019SAndroid Build Coastguard Worker 	tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
1015*d83cc019SAndroid Build Coastguard Worker 	getchar();
1016*d83cc019SAndroid Build Coastguard Worker 	tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
1017*d83cc019SAndroid Build Coastguard Worker }
1018*d83cc019SAndroid Build Coastguard Worker 
1019*d83cc019SAndroid Build Coastguard Worker /**
1020*d83cc019SAndroid Build Coastguard Worker  * igt_debug_manual_check:
1021*d83cc019SAndroid Build Coastguard Worker  * @var: var lookup to to enable this wait
1022*d83cc019SAndroid Build Coastguard Worker  * @expected: message to be printed as expected behaviour before wait for keys Y/n
1023*d83cc019SAndroid Build Coastguard Worker  *
1024*d83cc019SAndroid Build Coastguard Worker  * Waits for a key press when run interactively and when the corresponding debug
1025*d83cc019SAndroid Build Coastguard Worker  * var is set in the --interactive-debug=$var variable. Multiple vars
1026*d83cc019SAndroid Build Coastguard Worker  * can be specified as a comma-separated list or alternatively "all" if a wait
1027*d83cc019SAndroid Build Coastguard Worker  * should happen for all cases.
1028*d83cc019SAndroid Build Coastguard Worker  *
1029*d83cc019SAndroid Build Coastguard Worker  * This is useful for display tests where under certain situation manual
1030*d83cc019SAndroid Build Coastguard Worker  * inspection of the display is useful. Or when running a testcase in the
1031*d83cc019SAndroid Build Coastguard Worker  * background.
1032*d83cc019SAndroid Build Coastguard Worker  *
1033*d83cc019SAndroid Build Coastguard Worker  * When not connected to a terminal interactive_debug is ignored
1034*d83cc019SAndroid Build Coastguard Worker  * and execution immediately continues. For this reason by default this function
1035*d83cc019SAndroid Build Coastguard Worker  * returns true. It returns false only when N/n is pressed indicating the
1036*d83cc019SAndroid Build Coastguard Worker  * user isn't seeing what was expected.
1037*d83cc019SAndroid Build Coastguard Worker  *
1038*d83cc019SAndroid Build Coastguard Worker  * Force test fail when N/n is pressed.
1039*d83cc019SAndroid Build Coastguard Worker  */
igt_debug_manual_check(const char * var,const char * expected)1040*d83cc019SAndroid Build Coastguard Worker void igt_debug_manual_check(const char *var, const char *expected)
1041*d83cc019SAndroid Build Coastguard Worker {
1042*d83cc019SAndroid Build Coastguard Worker 	struct termios oldt, newt;
1043*d83cc019SAndroid Build Coastguard Worker 	char key;
1044*d83cc019SAndroid Build Coastguard Worker 
1045*d83cc019SAndroid Build Coastguard Worker 	if (!isatty(STDIN_FILENO)) {
1046*d83cc019SAndroid Build Coastguard Worker 		errno = 0; /* otherwise would be either ENOTTY or EBADF */
1047*d83cc019SAndroid Build Coastguard Worker 		return;
1048*d83cc019SAndroid Build Coastguard Worker 	}
1049*d83cc019SAndroid Build Coastguard Worker 
1050*d83cc019SAndroid Build Coastguard Worker 	if (!igt_interactive_debug)
1051*d83cc019SAndroid Build Coastguard Worker 		return;
1052*d83cc019SAndroid Build Coastguard Worker 
1053*d83cc019SAndroid Build Coastguard Worker 	if (!strstr(igt_interactive_debug, var) &&
1054*d83cc019SAndroid Build Coastguard Worker 	    !strstr(igt_interactive_debug, "all"))
1055*d83cc019SAndroid Build Coastguard Worker 		return;
1056*d83cc019SAndroid Build Coastguard Worker 
1057*d83cc019SAndroid Build Coastguard Worker 	igt_info("Is %s [Y/n]", expected);
1058*d83cc019SAndroid Build Coastguard Worker 
1059*d83cc019SAndroid Build Coastguard Worker 	tcgetattr ( STDIN_FILENO, &oldt );
1060*d83cc019SAndroid Build Coastguard Worker 	newt = oldt;
1061*d83cc019SAndroid Build Coastguard Worker 	newt.c_lflag &= ~ICANON;
1062*d83cc019SAndroid Build Coastguard Worker 	tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
1063*d83cc019SAndroid Build Coastguard Worker 	key = getchar();
1064*d83cc019SAndroid Build Coastguard Worker 	tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
1065*d83cc019SAndroid Build Coastguard Worker 
1066*d83cc019SAndroid Build Coastguard Worker 	igt_info("\n");
1067*d83cc019SAndroid Build Coastguard Worker 
1068*d83cc019SAndroid Build Coastguard Worker 	igt_assert(key != 'n' && key != 'N');
1069*d83cc019SAndroid Build Coastguard Worker }
1070*d83cc019SAndroid Build Coastguard Worker 
1071*d83cc019SAndroid Build Coastguard Worker /**
1072*d83cc019SAndroid Build Coastguard Worker  * igt_lock_mem:
1073*d83cc019SAndroid Build Coastguard Worker  * @size: the amount of memory to lock into RAM, in MB
1074*d83cc019SAndroid Build Coastguard Worker  *
1075*d83cc019SAndroid Build Coastguard Worker  * Allocate @size MB of memory and lock it into RAM. This releases any
1076*d83cc019SAndroid Build Coastguard Worker  * previously locked memory.
1077*d83cc019SAndroid Build Coastguard Worker  *
1078*d83cc019SAndroid Build Coastguard Worker  * Use #igt_unlock_mem to release the currently locked memory.
1079*d83cc019SAndroid Build Coastguard Worker  */
1080*d83cc019SAndroid Build Coastguard Worker static char *locked_mem;
1081*d83cc019SAndroid Build Coastguard Worker static size_t locked_size;
1082*d83cc019SAndroid Build Coastguard Worker 
igt_lock_mem(size_t size)1083*d83cc019SAndroid Build Coastguard Worker void igt_lock_mem(size_t size)
1084*d83cc019SAndroid Build Coastguard Worker {
1085*d83cc019SAndroid Build Coastguard Worker 	long pagesize = sysconf(_SC_PAGESIZE);
1086*d83cc019SAndroid Build Coastguard Worker 	size_t i;
1087*d83cc019SAndroid Build Coastguard Worker 	int ret;
1088*d83cc019SAndroid Build Coastguard Worker 
1089*d83cc019SAndroid Build Coastguard Worker 	if (size == 0) {
1090*d83cc019SAndroid Build Coastguard Worker 		return;
1091*d83cc019SAndroid Build Coastguard Worker 	}
1092*d83cc019SAndroid Build Coastguard Worker 
1093*d83cc019SAndroid Build Coastguard Worker 	if (locked_mem) {
1094*d83cc019SAndroid Build Coastguard Worker 		igt_unlock_mem();
1095*d83cc019SAndroid Build Coastguard Worker 		igt_warn("Unlocking previously locked memory.\n");
1096*d83cc019SAndroid Build Coastguard Worker 	}
1097*d83cc019SAndroid Build Coastguard Worker 
1098*d83cc019SAndroid Build Coastguard Worker 	locked_size = size * 1024 * 1024;
1099*d83cc019SAndroid Build Coastguard Worker 
1100*d83cc019SAndroid Build Coastguard Worker 	locked_mem = malloc(locked_size);
1101*d83cc019SAndroid Build Coastguard Worker 	igt_require_f(locked_mem,
1102*d83cc019SAndroid Build Coastguard Worker 		      "Could not malloc %zdMiB for locking.\n", size);
1103*d83cc019SAndroid Build Coastguard Worker 
1104*d83cc019SAndroid Build Coastguard Worker 	/* write into each page to ensure it is allocated */
1105*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < locked_size; i += pagesize)
1106*d83cc019SAndroid Build Coastguard Worker 		locked_mem[i] = i;
1107*d83cc019SAndroid Build Coastguard Worker 
1108*d83cc019SAndroid Build Coastguard Worker 	ret = mlock(locked_mem, locked_size);
1109*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(ret == 0, "Could not mlock %zdMiB.\n", size);
1110*d83cc019SAndroid Build Coastguard Worker }
1111*d83cc019SAndroid Build Coastguard Worker 
1112*d83cc019SAndroid Build Coastguard Worker /**
1113*d83cc019SAndroid Build Coastguard Worker  * igt_unlock_mem:
1114*d83cc019SAndroid Build Coastguard Worker  *
1115*d83cc019SAndroid Build Coastguard Worker  * Release and free the RAM used by #igt_lock_mem.
1116*d83cc019SAndroid Build Coastguard Worker  */
igt_unlock_mem(void)1117*d83cc019SAndroid Build Coastguard Worker void igt_unlock_mem(void)
1118*d83cc019SAndroid Build Coastguard Worker {
1119*d83cc019SAndroid Build Coastguard Worker 	if (!locked_mem)
1120*d83cc019SAndroid Build Coastguard Worker 		return;
1121*d83cc019SAndroid Build Coastguard Worker 
1122*d83cc019SAndroid Build Coastguard Worker 	munlock(locked_mem, locked_size);
1123*d83cc019SAndroid Build Coastguard Worker 
1124*d83cc019SAndroid Build Coastguard Worker 	free(locked_mem);
1125*d83cc019SAndroid Build Coastguard Worker 	locked_mem = NULL;
1126*d83cc019SAndroid Build Coastguard Worker }
1127*d83cc019SAndroid Build Coastguard Worker 
1128*d83cc019SAndroid Build Coastguard Worker 
1129*d83cc019SAndroid Build Coastguard Worker #define MODULE_PARAM_DIR "/sys/module/i915/parameters/"
1130*d83cc019SAndroid Build Coastguard Worker #define PARAM_NAME_MAX_SZ 32
1131*d83cc019SAndroid Build Coastguard Worker #define PARAM_VALUE_MAX_SZ 16
1132*d83cc019SAndroid Build Coastguard Worker #define PARAM_FILE_PATH_MAX_SZ (strlen(MODULE_PARAM_DIR) + PARAM_NAME_MAX_SZ)
1133*d83cc019SAndroid Build Coastguard Worker 
1134*d83cc019SAndroid Build Coastguard Worker struct module_param_data {
1135*d83cc019SAndroid Build Coastguard Worker 	char name[PARAM_NAME_MAX_SZ];
1136*d83cc019SAndroid Build Coastguard Worker 	char original_value[PARAM_VALUE_MAX_SZ];
1137*d83cc019SAndroid Build Coastguard Worker 
1138*d83cc019SAndroid Build Coastguard Worker 	struct module_param_data *next;
1139*d83cc019SAndroid Build Coastguard Worker };
1140*d83cc019SAndroid Build Coastguard Worker struct module_param_data *module_params = NULL;
1141*d83cc019SAndroid Build Coastguard Worker 
igt_module_param_exit_handler(int sig)1142*d83cc019SAndroid Build Coastguard Worker static void igt_module_param_exit_handler(int sig)
1143*d83cc019SAndroid Build Coastguard Worker {
1144*d83cc019SAndroid Build Coastguard Worker 	const size_t dir_len = strlen(MODULE_PARAM_DIR);
1145*d83cc019SAndroid Build Coastguard Worker 	char file_path[PARAM_FILE_PATH_MAX_SZ];
1146*d83cc019SAndroid Build Coastguard Worker 	struct module_param_data *data;
1147*d83cc019SAndroid Build Coastguard Worker 	int fd;
1148*d83cc019SAndroid Build Coastguard Worker 
1149*d83cc019SAndroid Build Coastguard Worker 	/* We don't need to assert string sizes on this function since they were
1150*d83cc019SAndroid Build Coastguard Worker 	 * already checked before being stored on the lists. Besides,
1151*d83cc019SAndroid Build Coastguard Worker 	 * igt_assert() is not AS-Safe. */
1152*d83cc019SAndroid Build Coastguard Worker 	strcpy(file_path, MODULE_PARAM_DIR);
1153*d83cc019SAndroid Build Coastguard Worker 
1154*d83cc019SAndroid Build Coastguard Worker 	for (data = module_params; data != NULL; data = data->next) {
1155*d83cc019SAndroid Build Coastguard Worker 		strcpy(file_path + dir_len, data->name);
1156*d83cc019SAndroid Build Coastguard Worker 
1157*d83cc019SAndroid Build Coastguard Worker 		fd = open(file_path, O_RDWR);
1158*d83cc019SAndroid Build Coastguard Worker 		if (fd >= 0) {
1159*d83cc019SAndroid Build Coastguard Worker 			int size = strlen (data->original_value);
1160*d83cc019SAndroid Build Coastguard Worker 
1161*d83cc019SAndroid Build Coastguard Worker 			if (size != write(fd, data->original_value, size)) {
1162*d83cc019SAndroid Build Coastguard Worker 				const char msg[] = "WARNING: Module parameters "
1163*d83cc019SAndroid Build Coastguard Worker 					"may not have been reset to their "
1164*d83cc019SAndroid Build Coastguard Worker 					"original values\n";
1165*d83cc019SAndroid Build Coastguard Worker 				assert(write(STDERR_FILENO, msg, sizeof(msg))
1166*d83cc019SAndroid Build Coastguard Worker 				       == sizeof(msg));
1167*d83cc019SAndroid Build Coastguard Worker 			}
1168*d83cc019SAndroid Build Coastguard Worker 
1169*d83cc019SAndroid Build Coastguard Worker 			close(fd);
1170*d83cc019SAndroid Build Coastguard Worker 		}
1171*d83cc019SAndroid Build Coastguard Worker 	}
1172*d83cc019SAndroid Build Coastguard Worker 	/* free() is not AS-Safe, so we can't call it here. */
1173*d83cc019SAndroid Build Coastguard Worker }
1174*d83cc019SAndroid Build Coastguard Worker 
1175*d83cc019SAndroid Build Coastguard Worker /**
1176*d83cc019SAndroid Build Coastguard Worker  * igt_save_module_param:
1177*d83cc019SAndroid Build Coastguard Worker  * @name: name of the i915.ko module parameter
1178*d83cc019SAndroid Build Coastguard Worker  * @file_path: full sysfs file path for the parameter
1179*d83cc019SAndroid Build Coastguard Worker  *
1180*d83cc019SAndroid Build Coastguard Worker  * Reads the current value of an i915.ko module parameter, saves it on an array,
1181*d83cc019SAndroid Build Coastguard Worker  * then installs an exit handler to restore it when the program exits.
1182*d83cc019SAndroid Build Coastguard Worker  *
1183*d83cc019SAndroid Build Coastguard Worker  * It is safe to call this function multiple times for the same parameter.
1184*d83cc019SAndroid Build Coastguard Worker  *
1185*d83cc019SAndroid Build Coastguard Worker  * Notice that this function is called by igt_set_module_param(), so that one -
1186*d83cc019SAndroid Build Coastguard Worker  * or one of its wrappers - is the only function the test programs need to call.
1187*d83cc019SAndroid Build Coastguard Worker  */
igt_save_module_param(const char * name,const char * file_path)1188*d83cc019SAndroid Build Coastguard Worker static void igt_save_module_param(const char *name, const char *file_path)
1189*d83cc019SAndroid Build Coastguard Worker {
1190*d83cc019SAndroid Build Coastguard Worker 	struct module_param_data *data;
1191*d83cc019SAndroid Build Coastguard Worker 	size_t n;
1192*d83cc019SAndroid Build Coastguard Worker 	int fd;
1193*d83cc019SAndroid Build Coastguard Worker 
1194*d83cc019SAndroid Build Coastguard Worker 	/* Check if this parameter is already saved. */
1195*d83cc019SAndroid Build Coastguard Worker 	for (data = module_params; data != NULL; data = data->next)
1196*d83cc019SAndroid Build Coastguard Worker 		if (strncmp(data->name, name, PARAM_NAME_MAX_SZ) == 0)
1197*d83cc019SAndroid Build Coastguard Worker 			return;
1198*d83cc019SAndroid Build Coastguard Worker 
1199*d83cc019SAndroid Build Coastguard Worker 	if (!module_params)
1200*d83cc019SAndroid Build Coastguard Worker 		igt_install_exit_handler(igt_module_param_exit_handler);
1201*d83cc019SAndroid Build Coastguard Worker 
1202*d83cc019SAndroid Build Coastguard Worker 	data = calloc(1, sizeof (*data));
1203*d83cc019SAndroid Build Coastguard Worker 	igt_assert(data);
1204*d83cc019SAndroid Build Coastguard Worker 
1205*d83cc019SAndroid Build Coastguard Worker 	strncpy(data->name, name, PARAM_NAME_MAX_SZ - 1);
1206*d83cc019SAndroid Build Coastguard Worker 
1207*d83cc019SAndroid Build Coastguard Worker 	fd = open(file_path, O_RDONLY);
1208*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fd >= 0);
1209*d83cc019SAndroid Build Coastguard Worker 
1210*d83cc019SAndroid Build Coastguard Worker 	n = read(fd, data->original_value, PARAM_VALUE_MAX_SZ);
1211*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(n > 0 && n < PARAM_VALUE_MAX_SZ,
1212*d83cc019SAndroid Build Coastguard Worker 		     "Need to increase PARAM_VALUE_MAX_SZ\n");
1213*d83cc019SAndroid Build Coastguard Worker 
1214*d83cc019SAndroid Build Coastguard Worker 	igt_assert(close(fd) == 0);
1215*d83cc019SAndroid Build Coastguard Worker 
1216*d83cc019SAndroid Build Coastguard Worker 	data->next = module_params;
1217*d83cc019SAndroid Build Coastguard Worker 	module_params = data;
1218*d83cc019SAndroid Build Coastguard Worker }
1219*d83cc019SAndroid Build Coastguard Worker 
1220*d83cc019SAndroid Build Coastguard Worker /**
1221*d83cc019SAndroid Build Coastguard Worker  * igt_set_module_param:
1222*d83cc019SAndroid Build Coastguard Worker  * @name: i915.ko parameter name
1223*d83cc019SAndroid Build Coastguard Worker  * @val: i915.ko parameter value
1224*d83cc019SAndroid Build Coastguard Worker  *
1225*d83cc019SAndroid Build Coastguard Worker  * This function sets the desired value for the given i915.ko parameter. It also
1226*d83cc019SAndroid Build Coastguard Worker  * takes care of saving and restoring the values that were already set before
1227*d83cc019SAndroid Build Coastguard Worker  * the test was run.
1228*d83cc019SAndroid Build Coastguard Worker  *
1229*d83cc019SAndroid Build Coastguard Worker  * Please consider using igt_set_module_param_int() for the integer and bool
1230*d83cc019SAndroid Build Coastguard Worker  * parameters.
1231*d83cc019SAndroid Build Coastguard Worker  */
igt_set_module_param(const char * name,const char * val)1232*d83cc019SAndroid Build Coastguard Worker void igt_set_module_param(const char *name, const char *val)
1233*d83cc019SAndroid Build Coastguard Worker {
1234*d83cc019SAndroid Build Coastguard Worker 	char file_path[PARAM_FILE_PATH_MAX_SZ];
1235*d83cc019SAndroid Build Coastguard Worker 	size_t len = strlen(val);
1236*d83cc019SAndroid Build Coastguard Worker 	int fd;
1237*d83cc019SAndroid Build Coastguard Worker 
1238*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(strlen(name) < PARAM_NAME_MAX_SZ,
1239*d83cc019SAndroid Build Coastguard Worker 		     "Need to increase PARAM_NAME_MAX_SZ\n");
1240*d83cc019SAndroid Build Coastguard Worker 	strcpy(file_path, MODULE_PARAM_DIR);
1241*d83cc019SAndroid Build Coastguard Worker 	strcpy(file_path + strlen(MODULE_PARAM_DIR), name);
1242*d83cc019SAndroid Build Coastguard Worker 
1243*d83cc019SAndroid Build Coastguard Worker 	igt_save_module_param(name, file_path);
1244*d83cc019SAndroid Build Coastguard Worker 
1245*d83cc019SAndroid Build Coastguard Worker 	fd = open(file_path, O_RDWR);
1246*d83cc019SAndroid Build Coastguard Worker 	igt_assert(write(fd, val, len) == len);
1247*d83cc019SAndroid Build Coastguard Worker 	igt_assert(close(fd) == 0);
1248*d83cc019SAndroid Build Coastguard Worker }
1249*d83cc019SAndroid Build Coastguard Worker 
1250*d83cc019SAndroid Build Coastguard Worker /**
1251*d83cc019SAndroid Build Coastguard Worker  * igt_set_module_param_int:
1252*d83cc019SAndroid Build Coastguard Worker  * @name: i915.ko parameter name
1253*d83cc019SAndroid Build Coastguard Worker  * @val: i915.ko parameter value
1254*d83cc019SAndroid Build Coastguard Worker  *
1255*d83cc019SAndroid Build Coastguard Worker  * This is a wrapper for igt_set_module_param() that takes an integer instead of
1256*d83cc019SAndroid Build Coastguard Worker  * a string. Please see igt_set_module_param().
1257*d83cc019SAndroid Build Coastguard Worker  */
igt_set_module_param_int(const char * name,int val)1258*d83cc019SAndroid Build Coastguard Worker void igt_set_module_param_int(const char *name, int val)
1259*d83cc019SAndroid Build Coastguard Worker {
1260*d83cc019SAndroid Build Coastguard Worker 	char str[PARAM_VALUE_MAX_SZ];
1261*d83cc019SAndroid Build Coastguard Worker 	int n;
1262*d83cc019SAndroid Build Coastguard Worker 
1263*d83cc019SAndroid Build Coastguard Worker 	n = snprintf(str, PARAM_VALUE_MAX_SZ, "%d\n", val);
1264*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(n < PARAM_VALUE_MAX_SZ,
1265*d83cc019SAndroid Build Coastguard Worker 		     "Need to increase PARAM_VALUE_MAX_SZ\n");
1266*d83cc019SAndroid Build Coastguard Worker 
1267*d83cc019SAndroid Build Coastguard Worker 	igt_set_module_param(name, str);
1268*d83cc019SAndroid Build Coastguard Worker }
1269*d83cc019SAndroid Build Coastguard Worker 
1270*d83cc019SAndroid Build Coastguard Worker #ifndef ANDROID
1271*d83cc019SAndroid Build Coastguard Worker 
1272*d83cc019SAndroid Build Coastguard Worker /**
1273*d83cc019SAndroid Build Coastguard Worker  * igt_is_process_running:
1274*d83cc019SAndroid Build Coastguard Worker  * @comm: Name of process in the form found in /proc/pid/comm (limited to 15
1275*d83cc019SAndroid Build Coastguard Worker  * chars)
1276*d83cc019SAndroid Build Coastguard Worker  *
1277*d83cc019SAndroid Build Coastguard Worker  * Returns: true in case the process has been found, false otherwise.
1278*d83cc019SAndroid Build Coastguard Worker  *
1279*d83cc019SAndroid Build Coastguard Worker  * This function checks in the process table for an entry with the name @comm.
1280*d83cc019SAndroid Build Coastguard Worker  */
igt_is_process_running(const char * comm)1281*d83cc019SAndroid Build Coastguard Worker int igt_is_process_running(const char *comm)
1282*d83cc019SAndroid Build Coastguard Worker {
1283*d83cc019SAndroid Build Coastguard Worker 	PROCTAB *proc;
1284*d83cc019SAndroid Build Coastguard Worker 	proc_t *proc_info;
1285*d83cc019SAndroid Build Coastguard Worker 	bool found = false;
1286*d83cc019SAndroid Build Coastguard Worker 
1287*d83cc019SAndroid Build Coastguard Worker 	proc = openproc(PROC_FILLCOM | PROC_FILLSTAT);
1288*d83cc019SAndroid Build Coastguard Worker 	igt_assert(proc != NULL);
1289*d83cc019SAndroid Build Coastguard Worker 
1290*d83cc019SAndroid Build Coastguard Worker 	while ((proc_info = readproc(proc, NULL))) {
1291*d83cc019SAndroid Build Coastguard Worker 		if (!strncasecmp(proc_info->cmd, comm, sizeof(proc_info->cmd))) {
1292*d83cc019SAndroid Build Coastguard Worker 			freeproc(proc_info);
1293*d83cc019SAndroid Build Coastguard Worker 			found = true;
1294*d83cc019SAndroid Build Coastguard Worker 			break;
1295*d83cc019SAndroid Build Coastguard Worker 		}
1296*d83cc019SAndroid Build Coastguard Worker 		freeproc(proc_info);
1297*d83cc019SAndroid Build Coastguard Worker 	}
1298*d83cc019SAndroid Build Coastguard Worker 
1299*d83cc019SAndroid Build Coastguard Worker 	closeproc(proc);
1300*d83cc019SAndroid Build Coastguard Worker 	return found;
1301*d83cc019SAndroid Build Coastguard Worker }
1302*d83cc019SAndroid Build Coastguard Worker 
1303*d83cc019SAndroid Build Coastguard Worker /**
1304*d83cc019SAndroid Build Coastguard Worker  * igt_terminate_process:
1305*d83cc019SAndroid Build Coastguard Worker  * @sig: Signal to send
1306*d83cc019SAndroid Build Coastguard Worker  * @comm: Name of process in the form found in /proc/pid/comm (limited to 15
1307*d83cc019SAndroid Build Coastguard Worker  * chars)
1308*d83cc019SAndroid Build Coastguard Worker  *
1309*d83cc019SAndroid Build Coastguard Worker  * Returns: 0 in case the process is not found running or the signal has been
1310*d83cc019SAndroid Build Coastguard Worker  * sent successfully or -errno otherwise.
1311*d83cc019SAndroid Build Coastguard Worker  *
1312*d83cc019SAndroid Build Coastguard Worker  * This function sends the signal @sig for a process found in process table
1313*d83cc019SAndroid Build Coastguard Worker  * with name @comm.
1314*d83cc019SAndroid Build Coastguard Worker  */
igt_terminate_process(int sig,const char * comm)1315*d83cc019SAndroid Build Coastguard Worker int igt_terminate_process(int sig, const char *comm)
1316*d83cc019SAndroid Build Coastguard Worker {
1317*d83cc019SAndroid Build Coastguard Worker 	PROCTAB *proc;
1318*d83cc019SAndroid Build Coastguard Worker 	proc_t *proc_info;
1319*d83cc019SAndroid Build Coastguard Worker 	int err = 0;
1320*d83cc019SAndroid Build Coastguard Worker 
1321*d83cc019SAndroid Build Coastguard Worker 	proc = openproc(PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLARG);
1322*d83cc019SAndroid Build Coastguard Worker 	igt_assert(proc != NULL);
1323*d83cc019SAndroid Build Coastguard Worker 
1324*d83cc019SAndroid Build Coastguard Worker 	while ((proc_info = readproc(proc, NULL))) {
1325*d83cc019SAndroid Build Coastguard Worker 		if (!strncasecmp(proc_info->cmd, comm, sizeof(proc_info->cmd))) {
1326*d83cc019SAndroid Build Coastguard Worker 
1327*d83cc019SAndroid Build Coastguard Worker 			if (kill(proc_info->tid, sig) < 0)
1328*d83cc019SAndroid Build Coastguard Worker 				err = -errno;
1329*d83cc019SAndroid Build Coastguard Worker 
1330*d83cc019SAndroid Build Coastguard Worker 			freeproc(proc_info);
1331*d83cc019SAndroid Build Coastguard Worker 			break;
1332*d83cc019SAndroid Build Coastguard Worker 		}
1333*d83cc019SAndroid Build Coastguard Worker 		freeproc(proc_info);
1334*d83cc019SAndroid Build Coastguard Worker 	}
1335*d83cc019SAndroid Build Coastguard Worker 
1336*d83cc019SAndroid Build Coastguard Worker 	closeproc(proc);
1337*d83cc019SAndroid Build Coastguard Worker 	return err;
1338*d83cc019SAndroid Build Coastguard Worker }
1339*d83cc019SAndroid Build Coastguard Worker 
1340*d83cc019SAndroid Build Coastguard Worker struct pinfo {
1341*d83cc019SAndroid Build Coastguard Worker 	pid_t pid;
1342*d83cc019SAndroid Build Coastguard Worker 	const char *comm;
1343*d83cc019SAndroid Build Coastguard Worker 	const char *fn;
1344*d83cc019SAndroid Build Coastguard Worker };
1345*d83cc019SAndroid Build Coastguard Worker 
1346*d83cc019SAndroid Build Coastguard Worker static void
__igt_show_stat(struct pinfo * info)1347*d83cc019SAndroid Build Coastguard Worker __igt_show_stat(struct pinfo *info)
1348*d83cc019SAndroid Build Coastguard Worker {
1349*d83cc019SAndroid Build Coastguard Worker 	const char *comm, *fn;
1350*d83cc019SAndroid Build Coastguard Worker 	const char *type = "";
1351*d83cc019SAndroid Build Coastguard Worker 	struct stat st;
1352*d83cc019SAndroid Build Coastguard Worker 
1353*d83cc019SAndroid Build Coastguard Worker 	pid_t pid = info->pid;
1354*d83cc019SAndroid Build Coastguard Worker 	igt_assert((comm = info->comm));
1355*d83cc019SAndroid Build Coastguard Worker 	igt_assert((fn = info->fn));
1356*d83cc019SAndroid Build Coastguard Worker 
1357*d83cc019SAndroid Build Coastguard Worker 	if (lstat(fn, &st) == -1)
1358*d83cc019SAndroid Build Coastguard Worker 		return;
1359*d83cc019SAndroid Build Coastguard Worker 
1360*d83cc019SAndroid Build Coastguard Worker 	igt_info("%20.20s ", comm);
1361*d83cc019SAndroid Build Coastguard Worker 	igt_info("%10d ", pid);
1362*d83cc019SAndroid Build Coastguard Worker 
1363*d83cc019SAndroid Build Coastguard Worker 	switch (st.st_mode & S_IFMT) {
1364*d83cc019SAndroid Build Coastguard Worker 	case S_IFBLK:
1365*d83cc019SAndroid Build Coastguard Worker 		type = "block";
1366*d83cc019SAndroid Build Coastguard Worker 		break;
1367*d83cc019SAndroid Build Coastguard Worker 	case S_IFCHR:
1368*d83cc019SAndroid Build Coastguard Worker 		type = "character";
1369*d83cc019SAndroid Build Coastguard Worker 		break;
1370*d83cc019SAndroid Build Coastguard Worker 	case S_IFDIR:
1371*d83cc019SAndroid Build Coastguard Worker 		type = "directory";
1372*d83cc019SAndroid Build Coastguard Worker 		break;
1373*d83cc019SAndroid Build Coastguard Worker 	case S_IFIFO:
1374*d83cc019SAndroid Build Coastguard Worker 		type = "FIFO/pipe";
1375*d83cc019SAndroid Build Coastguard Worker 		break;
1376*d83cc019SAndroid Build Coastguard Worker 	case S_IFLNK:
1377*d83cc019SAndroid Build Coastguard Worker 		type = "symlink";
1378*d83cc019SAndroid Build Coastguard Worker 		break;
1379*d83cc019SAndroid Build Coastguard Worker 	case S_IFREG:
1380*d83cc019SAndroid Build Coastguard Worker 		type = "file";
1381*d83cc019SAndroid Build Coastguard Worker 		break;
1382*d83cc019SAndroid Build Coastguard Worker 	case S_IFSOCK:
1383*d83cc019SAndroid Build Coastguard Worker 		type = "socket";
1384*d83cc019SAndroid Build Coastguard Worker 		break;
1385*d83cc019SAndroid Build Coastguard Worker 	default:
1386*d83cc019SAndroid Build Coastguard Worker 		type = "unknown?";
1387*d83cc019SAndroid Build Coastguard Worker 		break;
1388*d83cc019SAndroid Build Coastguard Worker 	}
1389*d83cc019SAndroid Build Coastguard Worker 	igt_info("%20.20s ", type);
1390*d83cc019SAndroid Build Coastguard Worker 
1391*d83cc019SAndroid Build Coastguard Worker 	igt_info("%10ld%10ld ", (long) st.st_uid, (long) st.st_gid);
1392*d83cc019SAndroid Build Coastguard Worker 
1393*d83cc019SAndroid Build Coastguard Worker 	igt_info("%15lld bytes ", (long long) st.st_size);
1394*d83cc019SAndroid Build Coastguard Worker 	igt_info("%30.30s", fn);
1395*d83cc019SAndroid Build Coastguard Worker 	igt_info("\n");
1396*d83cc019SAndroid Build Coastguard Worker }
1397*d83cc019SAndroid Build Coastguard Worker 
1398*d83cc019SAndroid Build Coastguard Worker static void
igt_show_stat_header(void)1399*d83cc019SAndroid Build Coastguard Worker igt_show_stat_header(void)
1400*d83cc019SAndroid Build Coastguard Worker {
1401*d83cc019SAndroid Build Coastguard Worker 	igt_info("%20.20s%11.11s%21.21s%11.11s%10.10s%22.22s%31.31s\n",
1402*d83cc019SAndroid Build Coastguard Worker 		"COMM", "PID", "Type", "UID", "GID", "Size", "Filename");
1403*d83cc019SAndroid Build Coastguard Worker }
1404*d83cc019SAndroid Build Coastguard Worker 
1405*d83cc019SAndroid Build Coastguard Worker static void
igt_show_stat(proc_t * info,int * state,const char * fn)1406*d83cc019SAndroid Build Coastguard Worker igt_show_stat(proc_t *info, int *state, const char *fn)
1407*d83cc019SAndroid Build Coastguard Worker {
1408*d83cc019SAndroid Build Coastguard Worker 	struct pinfo p = { .pid = info->tid, .comm = info->cmd, .fn = fn };
1409*d83cc019SAndroid Build Coastguard Worker 
1410*d83cc019SAndroid Build Coastguard Worker 	if (!*state)
1411*d83cc019SAndroid Build Coastguard Worker 		igt_show_stat_header();
1412*d83cc019SAndroid Build Coastguard Worker 
1413*d83cc019SAndroid Build Coastguard Worker 	__igt_show_stat(&p);
1414*d83cc019SAndroid Build Coastguard Worker 	++*state;
1415*d83cc019SAndroid Build Coastguard Worker }
1416*d83cc019SAndroid Build Coastguard Worker 
1417*d83cc019SAndroid Build Coastguard Worker static void
__igt_lsof_fds(proc_t * proc_info,int * state,char * proc_path,const char * dir)1418*d83cc019SAndroid Build Coastguard Worker __igt_lsof_fds(proc_t *proc_info, int *state, char *proc_path, const char *dir)
1419*d83cc019SAndroid Build Coastguard Worker {
1420*d83cc019SAndroid Build Coastguard Worker 	struct dirent *d;
1421*d83cc019SAndroid Build Coastguard Worker 	struct stat st;
1422*d83cc019SAndroid Build Coastguard Worker 	char path[PATH_MAX];
1423*d83cc019SAndroid Build Coastguard Worker 	char *fd_lnk;
1424*d83cc019SAndroid Build Coastguard Worker 
1425*d83cc019SAndroid Build Coastguard Worker 	/* default fds or kernel threads */
1426*d83cc019SAndroid Build Coastguard Worker 	const char *default_fds[] = { "/dev/pts", "/dev/null" };
1427*d83cc019SAndroid Build Coastguard Worker 
1428*d83cc019SAndroid Build Coastguard Worker 	DIR *dp = opendir(proc_path);
1429*d83cc019SAndroid Build Coastguard Worker 	igt_assert(dp);
1430*d83cc019SAndroid Build Coastguard Worker again:
1431*d83cc019SAndroid Build Coastguard Worker 	while ((d = readdir(dp))) {
1432*d83cc019SAndroid Build Coastguard Worker 		char *copy_fd_lnk;
1433*d83cc019SAndroid Build Coastguard Worker 		char *dirn;
1434*d83cc019SAndroid Build Coastguard Worker 
1435*d83cc019SAndroid Build Coastguard Worker 		unsigned int i;
1436*d83cc019SAndroid Build Coastguard Worker 		ssize_t read;
1437*d83cc019SAndroid Build Coastguard Worker 
1438*d83cc019SAndroid Build Coastguard Worker 		if (*d->d_name == '.')
1439*d83cc019SAndroid Build Coastguard Worker 			continue;
1440*d83cc019SAndroid Build Coastguard Worker 
1441*d83cc019SAndroid Build Coastguard Worker 		memset(path, 0, sizeof(path));
1442*d83cc019SAndroid Build Coastguard Worker 		snprintf(path, sizeof(path), "%s/%s", proc_path, d->d_name);
1443*d83cc019SAndroid Build Coastguard Worker 
1444*d83cc019SAndroid Build Coastguard Worker 		if (lstat(path, &st) == -1)
1445*d83cc019SAndroid Build Coastguard Worker 			continue;
1446*d83cc019SAndroid Build Coastguard Worker 
1447*d83cc019SAndroid Build Coastguard Worker 		fd_lnk = malloc(st.st_size + 1);
1448*d83cc019SAndroid Build Coastguard Worker 
1449*d83cc019SAndroid Build Coastguard Worker 		igt_assert((read = readlink(path, fd_lnk, st.st_size + 1)));
1450*d83cc019SAndroid Build Coastguard Worker 		fd_lnk[read] = '\0';
1451*d83cc019SAndroid Build Coastguard Worker 
1452*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < ARRAY_SIZE(default_fds); ++i) {
1453*d83cc019SAndroid Build Coastguard Worker 			if (!strncmp(default_fds[i],
1454*d83cc019SAndroid Build Coastguard Worker 				     fd_lnk,
1455*d83cc019SAndroid Build Coastguard Worker 				     strlen(default_fds[i]))) {
1456*d83cc019SAndroid Build Coastguard Worker 				free(fd_lnk);
1457*d83cc019SAndroid Build Coastguard Worker 				goto again;
1458*d83cc019SAndroid Build Coastguard Worker 			}
1459*d83cc019SAndroid Build Coastguard Worker 		}
1460*d83cc019SAndroid Build Coastguard Worker 
1461*d83cc019SAndroid Build Coastguard Worker 		copy_fd_lnk = strdup(fd_lnk);
1462*d83cc019SAndroid Build Coastguard Worker 		dirn = dirname(copy_fd_lnk);
1463*d83cc019SAndroid Build Coastguard Worker 
1464*d83cc019SAndroid Build Coastguard Worker 		if (!strncmp(dir, dirn, strlen(dir)))
1465*d83cc019SAndroid Build Coastguard Worker 			igt_show_stat(proc_info, state, fd_lnk);
1466*d83cc019SAndroid Build Coastguard Worker 
1467*d83cc019SAndroid Build Coastguard Worker 		free(copy_fd_lnk);
1468*d83cc019SAndroid Build Coastguard Worker 		free(fd_lnk);
1469*d83cc019SAndroid Build Coastguard Worker 	}
1470*d83cc019SAndroid Build Coastguard Worker 
1471*d83cc019SAndroid Build Coastguard Worker 	closedir(dp);
1472*d83cc019SAndroid Build Coastguard Worker }
1473*d83cc019SAndroid Build Coastguard Worker 
1474*d83cc019SAndroid Build Coastguard Worker /*
1475*d83cc019SAndroid Build Coastguard Worker  * This functions verifies, for each process running on the machine, if the
1476*d83cc019SAndroid Build Coastguard Worker  * current working directory or the fds matches the one supplied in dir.
1477*d83cc019SAndroid Build Coastguard Worker  */
1478*d83cc019SAndroid Build Coastguard Worker static void
__igt_lsof(const char * dir)1479*d83cc019SAndroid Build Coastguard Worker __igt_lsof(const char *dir)
1480*d83cc019SAndroid Build Coastguard Worker {
1481*d83cc019SAndroid Build Coastguard Worker 	PROCTAB *proc;
1482*d83cc019SAndroid Build Coastguard Worker 	proc_t *proc_info;
1483*d83cc019SAndroid Build Coastguard Worker 
1484*d83cc019SAndroid Build Coastguard Worker 	char path[30];
1485*d83cc019SAndroid Build Coastguard Worker 	char *name_lnk;
1486*d83cc019SAndroid Build Coastguard Worker 	struct stat st;
1487*d83cc019SAndroid Build Coastguard Worker 	int state = 0;
1488*d83cc019SAndroid Build Coastguard Worker 
1489*d83cc019SAndroid Build Coastguard Worker 	proc = openproc(PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLARG);
1490*d83cc019SAndroid Build Coastguard Worker 	igt_assert(proc != NULL);
1491*d83cc019SAndroid Build Coastguard Worker 
1492*d83cc019SAndroid Build Coastguard Worker 	while ((proc_info = readproc(proc, NULL))) {
1493*d83cc019SAndroid Build Coastguard Worker 		ssize_t read;
1494*d83cc019SAndroid Build Coastguard Worker 
1495*d83cc019SAndroid Build Coastguard Worker 		/* check current working directory */
1496*d83cc019SAndroid Build Coastguard Worker 		memset(path, 0, sizeof(path));
1497*d83cc019SAndroid Build Coastguard Worker 		snprintf(path, sizeof(path), "/proc/%d/cwd", proc_info->tid);
1498*d83cc019SAndroid Build Coastguard Worker 
1499*d83cc019SAndroid Build Coastguard Worker 		if (stat(path, &st) == -1)
1500*d83cc019SAndroid Build Coastguard Worker 			continue;
1501*d83cc019SAndroid Build Coastguard Worker 
1502*d83cc019SAndroid Build Coastguard Worker 		name_lnk = malloc(st.st_size + 1);
1503*d83cc019SAndroid Build Coastguard Worker 
1504*d83cc019SAndroid Build Coastguard Worker 		igt_assert((read = readlink(path, name_lnk, st.st_size + 1)));
1505*d83cc019SAndroid Build Coastguard Worker 		name_lnk[read] = '\0';
1506*d83cc019SAndroid Build Coastguard Worker 
1507*d83cc019SAndroid Build Coastguard Worker 		if (!strncmp(dir, name_lnk, strlen(dir)))
1508*d83cc019SAndroid Build Coastguard Worker 			igt_show_stat(proc_info, &state, name_lnk);
1509*d83cc019SAndroid Build Coastguard Worker 
1510*d83cc019SAndroid Build Coastguard Worker 		/* check also fd, seems that lsof(8) doesn't look here */
1511*d83cc019SAndroid Build Coastguard Worker 		memset(path, 0, sizeof(path));
1512*d83cc019SAndroid Build Coastguard Worker 		snprintf(path, sizeof(path), "/proc/%d/fd", proc_info->tid);
1513*d83cc019SAndroid Build Coastguard Worker 
1514*d83cc019SAndroid Build Coastguard Worker 		__igt_lsof_fds(proc_info, &state, path, dir);
1515*d83cc019SAndroid Build Coastguard Worker 
1516*d83cc019SAndroid Build Coastguard Worker 		free(name_lnk);
1517*d83cc019SAndroid Build Coastguard Worker 		freeproc(proc_info);
1518*d83cc019SAndroid Build Coastguard Worker 	}
1519*d83cc019SAndroid Build Coastguard Worker 
1520*d83cc019SAndroid Build Coastguard Worker 	closeproc(proc);
1521*d83cc019SAndroid Build Coastguard Worker }
1522*d83cc019SAndroid Build Coastguard Worker 
1523*d83cc019SAndroid Build Coastguard Worker /**
1524*d83cc019SAndroid Build Coastguard Worker  * igt_lsof: Lists information about files opened by processes.
1525*d83cc019SAndroid Build Coastguard Worker  * @dpath: Path to look under. A valid directory is required.
1526*d83cc019SAndroid Build Coastguard Worker  *
1527*d83cc019SAndroid Build Coastguard Worker  * This function mimics (a restrictive form of) lsof(8), but also shows
1528*d83cc019SAndroid Build Coastguard Worker  * information about opened fds.
1529*d83cc019SAndroid Build Coastguard Worker  */
1530*d83cc019SAndroid Build Coastguard Worker void
igt_lsof(const char * dpath)1531*d83cc019SAndroid Build Coastguard Worker igt_lsof(const char *dpath)
1532*d83cc019SAndroid Build Coastguard Worker {
1533*d83cc019SAndroid Build Coastguard Worker 	struct stat st;
1534*d83cc019SAndroid Build Coastguard Worker 	size_t len = strlen(dpath);
1535*d83cc019SAndroid Build Coastguard Worker 	char *sanitized;
1536*d83cc019SAndroid Build Coastguard Worker 
1537*d83cc019SAndroid Build Coastguard Worker 	if (stat(dpath, &st) == -1)
1538*d83cc019SAndroid Build Coastguard Worker 		return;
1539*d83cc019SAndroid Build Coastguard Worker 
1540*d83cc019SAndroid Build Coastguard Worker 	if (!S_ISDIR(st.st_mode)) {
1541*d83cc019SAndroid Build Coastguard Worker 		igt_warn("%s not a directory!\n", dpath);
1542*d83cc019SAndroid Build Coastguard Worker 		return;
1543*d83cc019SAndroid Build Coastguard Worker 	}
1544*d83cc019SAndroid Build Coastguard Worker 
1545*d83cc019SAndroid Build Coastguard Worker 	sanitized = strdup(dpath);
1546*d83cc019SAndroid Build Coastguard Worker 	/* remove last '/' so matching is easier */
1547*d83cc019SAndroid Build Coastguard Worker 	if (len > 1 && dpath[len - 1] == '/')
1548*d83cc019SAndroid Build Coastguard Worker 		sanitized[len - 1] = '\0';
1549*d83cc019SAndroid Build Coastguard Worker 
1550*d83cc019SAndroid Build Coastguard Worker 	__igt_lsof(sanitized);
1551*d83cc019SAndroid Build Coastguard Worker 
1552*d83cc019SAndroid Build Coastguard Worker 	free(sanitized);
1553*d83cc019SAndroid Build Coastguard Worker }
1554*d83cc019SAndroid Build Coastguard Worker #endif
1555*d83cc019SAndroid Build Coastguard Worker 
1556*d83cc019SAndroid Build Coastguard Worker static struct igt_siglatency {
1557*d83cc019SAndroid Build Coastguard Worker 	timer_t timer;
1558*d83cc019SAndroid Build Coastguard Worker 	struct timespec target;
1559*d83cc019SAndroid Build Coastguard Worker 	struct sigaction oldact;
1560*d83cc019SAndroid Build Coastguard Worker 	struct igt_mean mean;
1561*d83cc019SAndroid Build Coastguard Worker 
1562*d83cc019SAndroid Build Coastguard Worker 	int sig;
1563*d83cc019SAndroid Build Coastguard Worker } igt_siglatency;
1564*d83cc019SAndroid Build Coastguard Worker 
delay(void)1565*d83cc019SAndroid Build Coastguard Worker static long delay(void)
1566*d83cc019SAndroid Build Coastguard Worker {
1567*d83cc019SAndroid Build Coastguard Worker 	return hars_petruska_f54_1_random_unsafe() % (NSEC_PER_SEC / 1000);
1568*d83cc019SAndroid Build Coastguard Worker }
1569*d83cc019SAndroid Build Coastguard Worker 
elapsed(const struct timespec * now,const struct timespec * last)1570*d83cc019SAndroid Build Coastguard Worker static double elapsed(const struct timespec *now, const struct timespec *last)
1571*d83cc019SAndroid Build Coastguard Worker {
1572*d83cc019SAndroid Build Coastguard Worker 	double nsecs;
1573*d83cc019SAndroid Build Coastguard Worker 
1574*d83cc019SAndroid Build Coastguard Worker 	nsecs = now->tv_nsec - last ->tv_nsec;
1575*d83cc019SAndroid Build Coastguard Worker 	nsecs += 1e9*(now->tv_sec - last->tv_sec);
1576*d83cc019SAndroid Build Coastguard Worker 
1577*d83cc019SAndroid Build Coastguard Worker 	return nsecs;
1578*d83cc019SAndroid Build Coastguard Worker }
1579*d83cc019SAndroid Build Coastguard Worker 
siglatency(int sig,siginfo_t * info,void * arg)1580*d83cc019SAndroid Build Coastguard Worker static void siglatency(int sig, siginfo_t *info, void *arg)
1581*d83cc019SAndroid Build Coastguard Worker {
1582*d83cc019SAndroid Build Coastguard Worker 	struct itimerspec its;
1583*d83cc019SAndroid Build Coastguard Worker 
1584*d83cc019SAndroid Build Coastguard Worker 	clock_gettime(CLOCK_MONOTONIC, &its.it_value);
1585*d83cc019SAndroid Build Coastguard Worker 	if (info)
1586*d83cc019SAndroid Build Coastguard Worker 		igt_mean_add(&igt_siglatency.mean,
1587*d83cc019SAndroid Build Coastguard Worker 			     elapsed(&its.it_value, &igt_siglatency.target));
1588*d83cc019SAndroid Build Coastguard Worker 	igt_siglatency.target = its.it_value;
1589*d83cc019SAndroid Build Coastguard Worker 
1590*d83cc019SAndroid Build Coastguard Worker 	its.it_value.tv_nsec += 100 * 1000;
1591*d83cc019SAndroid Build Coastguard Worker 	its.it_value.tv_nsec += delay();
1592*d83cc019SAndroid Build Coastguard Worker 	if (its.it_value.tv_nsec >= NSEC_PER_SEC) {
1593*d83cc019SAndroid Build Coastguard Worker 		its.it_value.tv_nsec -= NSEC_PER_SEC;
1594*d83cc019SAndroid Build Coastguard Worker 		its.it_value.tv_sec += 1;
1595*d83cc019SAndroid Build Coastguard Worker 	}
1596*d83cc019SAndroid Build Coastguard Worker 	its.it_interval.tv_sec = its.it_interval.tv_nsec = 0;
1597*d83cc019SAndroid Build Coastguard Worker 	timer_settime(igt_siglatency.timer, TIMER_ABSTIME, &its, NULL);
1598*d83cc019SAndroid Build Coastguard Worker }
1599*d83cc019SAndroid Build Coastguard Worker 
igt_start_siglatency(int sig)1600*d83cc019SAndroid Build Coastguard Worker void igt_start_siglatency(int sig)
1601*d83cc019SAndroid Build Coastguard Worker {
1602*d83cc019SAndroid Build Coastguard Worker 	struct sigevent sev;
1603*d83cc019SAndroid Build Coastguard Worker 	struct sigaction act;
1604*d83cc019SAndroid Build Coastguard Worker 
1605*d83cc019SAndroid Build Coastguard Worker 	if (sig <= 0)
1606*d83cc019SAndroid Build Coastguard Worker 		sig = SIGRTMIN;
1607*d83cc019SAndroid Build Coastguard Worker 
1608*d83cc019SAndroid Build Coastguard Worker 	if (igt_siglatency.sig)
1609*d83cc019SAndroid Build Coastguard Worker 		(void)igt_stop_siglatency(NULL);
1610*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_siglatency.sig == 0);
1611*d83cc019SAndroid Build Coastguard Worker 	igt_siglatency.sig = sig;
1612*d83cc019SAndroid Build Coastguard Worker 
1613*d83cc019SAndroid Build Coastguard Worker 	memset(&sev, 0, sizeof(sev));
1614*d83cc019SAndroid Build Coastguard Worker 	sev.sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID;
1615*d83cc019SAndroid Build Coastguard Worker 	sev.sigev_notify_thread_id = gettid();
1616*d83cc019SAndroid Build Coastguard Worker 	sev.sigev_signo = sig;
1617*d83cc019SAndroid Build Coastguard Worker 	timer_create(CLOCK_MONOTONIC, &sev, &igt_siglatency.timer);
1618*d83cc019SAndroid Build Coastguard Worker 
1619*d83cc019SAndroid Build Coastguard Worker 	memset(&act, 0, sizeof(act));
1620*d83cc019SAndroid Build Coastguard Worker 	act.sa_sigaction = siglatency;
1621*d83cc019SAndroid Build Coastguard Worker 	sigaction(sig, &act, &igt_siglatency.oldact);
1622*d83cc019SAndroid Build Coastguard Worker 
1623*d83cc019SAndroid Build Coastguard Worker 	siglatency(sig, NULL, NULL);
1624*d83cc019SAndroid Build Coastguard Worker }
1625*d83cc019SAndroid Build Coastguard Worker 
igt_stop_siglatency(struct igt_mean * result)1626*d83cc019SAndroid Build Coastguard Worker double igt_stop_siglatency(struct igt_mean *result)
1627*d83cc019SAndroid Build Coastguard Worker {
1628*d83cc019SAndroid Build Coastguard Worker 	double mean = igt_mean_get(&igt_siglatency.mean);
1629*d83cc019SAndroid Build Coastguard Worker 
1630*d83cc019SAndroid Build Coastguard Worker 	if (result)
1631*d83cc019SAndroid Build Coastguard Worker 		*result = igt_siglatency.mean;
1632*d83cc019SAndroid Build Coastguard Worker 
1633*d83cc019SAndroid Build Coastguard Worker 	sigaction(igt_siglatency.sig, &igt_siglatency.oldact, NULL);
1634*d83cc019SAndroid Build Coastguard Worker 	timer_delete(igt_siglatency.timer);
1635*d83cc019SAndroid Build Coastguard Worker 	memset(&igt_siglatency, 0, sizeof(igt_siglatency));
1636*d83cc019SAndroid Build Coastguard Worker 
1637*d83cc019SAndroid Build Coastguard Worker 	return mean;
1638*d83cc019SAndroid Build Coastguard Worker }
1639*d83cc019SAndroid Build Coastguard Worker 
igt_allow_unlimited_files(void)1640*d83cc019SAndroid Build Coastguard Worker bool igt_allow_unlimited_files(void)
1641*d83cc019SAndroid Build Coastguard Worker {
1642*d83cc019SAndroid Build Coastguard Worker 	struct rlimit rlim;
1643*d83cc019SAndroid Build Coastguard Worker 	unsigned nofile_rlim = 1024*1024;
1644*d83cc019SAndroid Build Coastguard Worker 
1645*d83cc019SAndroid Build Coastguard Worker 	FILE *file = fopen("/proc/sys/fs/nr_open", "r");
1646*d83cc019SAndroid Build Coastguard Worker 	if (file) {
1647*d83cc019SAndroid Build Coastguard Worker 		igt_assert(fscanf(file, "%u", &nofile_rlim) == 1);
1648*d83cc019SAndroid Build Coastguard Worker 		igt_info("System limit for open files is %u\n", nofile_rlim);
1649*d83cc019SAndroid Build Coastguard Worker 		fclose(file);
1650*d83cc019SAndroid Build Coastguard Worker 	}
1651*d83cc019SAndroid Build Coastguard Worker 
1652*d83cc019SAndroid Build Coastguard Worker 	if (getrlimit(RLIMIT_NOFILE, &rlim))
1653*d83cc019SAndroid Build Coastguard Worker 		return false;
1654*d83cc019SAndroid Build Coastguard Worker 
1655*d83cc019SAndroid Build Coastguard Worker 	rlim.rlim_cur = nofile_rlim;
1656*d83cc019SAndroid Build Coastguard Worker 	rlim.rlim_max = nofile_rlim;
1657*d83cc019SAndroid Build Coastguard Worker 	return setrlimit(RLIMIT_NOFILE, &rlim) == 0;
1658*d83cc019SAndroid Build Coastguard Worker }
1659*d83cc019SAndroid Build Coastguard Worker 
1660*d83cc019SAndroid Build Coastguard Worker /**
1661*d83cc019SAndroid Build Coastguard Worker  * vfs_file_max: report maximum number of files
1662*d83cc019SAndroid Build Coastguard Worker  *
1663*d83cc019SAndroid Build Coastguard Worker  * Get the global system-wide maximum of open files the kernel allows,
1664*d83cc019SAndroid Build Coastguard Worker  * by reading /proc/sys/fs/file-max. Fails the current subtest if
1665*d83cc019SAndroid Build Coastguard Worker  * reading the file fails, and returns a suitable best guess if it
1666*d83cc019SAndroid Build Coastguard Worker  * cannot be opened.
1667*d83cc019SAndroid Build Coastguard Worker  *
1668*d83cc019SAndroid Build Coastguard Worker  * Returns: System-wide maximum of open files, or a best effort guess.
1669*d83cc019SAndroid Build Coastguard Worker  */
vfs_file_max(void)1670*d83cc019SAndroid Build Coastguard Worker uint64_t vfs_file_max(void)
1671*d83cc019SAndroid Build Coastguard Worker {
1672*d83cc019SAndroid Build Coastguard Worker 	static long long unsigned max;
1673*d83cc019SAndroid Build Coastguard Worker 	if (max == 0) {
1674*d83cc019SAndroid Build Coastguard Worker 		FILE *file = fopen("/proc/sys/fs/file-max", "r");
1675*d83cc019SAndroid Build Coastguard Worker 		max = 80000;
1676*d83cc019SAndroid Build Coastguard Worker 		if (file) {
1677*d83cc019SAndroid Build Coastguard Worker 			igt_assert(fscanf(file, "%llu", &max) == 1);
1678*d83cc019SAndroid Build Coastguard Worker 			fclose(file);
1679*d83cc019SAndroid Build Coastguard Worker 		}
1680*d83cc019SAndroid Build Coastguard Worker 	}
1681*d83cc019SAndroid Build Coastguard Worker 	return max;
1682*d83cc019SAndroid Build Coastguard Worker }
1683