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