summaryrefslogtreecommitdiff
path: root/lib/drmtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/drmtest.c')
-rw-r--r--lib/drmtest.c830
1 files changed, 2 insertions, 828 deletions
diff --git a/lib/drmtest.c b/lib/drmtest.c
index b518b811..a5aac4dc 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -167,16 +167,6 @@ int drm_get_card(void)
return -1;
}
-static void oom_adjust_for_doom(void)
-{
- int fd;
- const char always_kill[] = "1000";
-
- fd = open("/proc/self/oom_score_adj", O_WRONLY);
- igt_assert(fd != -1);
- igt_assert(write(fd, always_kill, sizeof(always_kill)) == sizeof(always_kill));
-}
-
/** Open the first DRM device we can find, searching up to 16 device nodes */
static int __drm_open_any(void)
{
@@ -195,8 +185,6 @@ static int __drm_open_any(void)
fd = -1;
}
- oom_adjust_for_doom();
-
return fd;
}
@@ -226,8 +214,6 @@ static int __drm_open_any_render(void)
return fd;
}
- oom_adjust_for_doom();
-
return fd;
}
@@ -291,10 +277,6 @@ int drm_open_any_render(void)
}
/* signal interrupt helpers */
-static bool igt_only_list_subtests(void);
-
-static unsigned int exit_handler_count;
-
static struct igt_helper_process signal_helper;
long long int sig_stat;
static void __attribute__((noreturn)) signal_helper_process(pid_t pid)
@@ -334,609 +316,7 @@ void igt_stop_signal_helper(void)
sig_stat = 0;
}
-/* subtests helpers */
-static bool list_subtests = false;
-static char *run_single_subtest = NULL;
-static const char *in_subtest = NULL;
-static bool in_fixture = false;
-static bool test_with_subtests = false;
-static enum {
- CONT = 0, SKIP, FAIL
-} skip_subtests_henceforth = CONT;
-
-/* fork support state */
-pid_t *test_children;
-int num_test_children;
-int test_children_sz;
-bool test_child;
-
-bool __igt_fixture(void)
-{
- assert(!in_fixture);
-
- if (igt_only_list_subtests())
- return false;
-
- if (skip_subtests_henceforth)
- return false;
-
- in_fixture = true;
- return true;
-}
-
-void __igt_fixture_complete(void)
-{
- assert(in_fixture);
-
- in_fixture = false;
-}
-
-void __igt_fixture_end(void)
-{
- assert(in_fixture);
-
- in_fixture = false;
- longjmp(igt_subtest_jmpbuf, 1);
-}
-
-bool igt_exit_called;
-static void check_igt_exit(int sig)
-{
- /* When not killed by a signal check that igt_exit() has been properly
- * called. */
- assert(sig != 0 || igt_exit_called);
-}
-
-
-static void print_version(void)
-{
- struct utsname uts;
-
- if (list_subtests)
- return;
-
- uname(&uts);
-
- fprintf(stdout, "IGT-Version: %s-%s (%s) (%s: %s %s)\n", PACKAGE_VERSION,
- IGT_GIT_SHA1, TARGET_CPU_PLATFORM,
- uts.sysname, uts.release, uts.machine);
-}
-
-static void print_usage(const char *command_str, const char *help_str,
- bool output_on_stderr)
-{
- FILE *f = output_on_stderr ? stderr : stdout;
-
- fprintf(f, "Usage: %s [OPTIONS]\n"
- " --list-subtests\n"
- " --run-subtest <pattern>\n", command_str);
- if (help_str)
- fprintf(f, "%s\n", help_str);
-}
-
-int igt_subtest_init_parse_opts(int argc, char **argv,
- const char *extra_short_opts,
- struct option *extra_long_opts,
- const char *help_str,
- igt_opt_handler_t extra_opt_handler)
-{
- int c, option_index = 0;
- static struct option long_options[] = {
- {"list-subtests", 0, 0, 'l'},
- {"run-subtest", 1, 0, 'r'},
- {"help", 0, 0, 'h'},
- };
- const char *command_str;
- char *short_opts;
- struct option *combined_opts;
- int extra_opt_count;
- int all_opt_count;
- int ret = 0;
-
- test_with_subtests = true;
-
- command_str = argv[0];
- if (strrchr(command_str, '/'))
- command_str = strrchr(command_str, '/') + 1;
-
- /* First calculate space for all passed-in extra long options */
- all_opt_count = 0;
- while (extra_long_opts && extra_long_opts[all_opt_count].name)
- all_opt_count++;
- extra_opt_count = all_opt_count;
-
- all_opt_count += ARRAY_SIZE(long_options);
-
- combined_opts = malloc(all_opt_count * sizeof(*combined_opts));
- memcpy(combined_opts, extra_long_opts,
- extra_opt_count * sizeof(*combined_opts));
-
- /* Copy the subtest long options (and the final NULL entry) */
- memcpy(&combined_opts[extra_opt_count], long_options,
- ARRAY_SIZE(long_options) * sizeof(*combined_opts));
-
- ret = asprintf(&short_opts, "%sh",
- extra_short_opts ? extra_short_opts : "");
- assert(ret >= 0);
-
- while ((c = getopt_long(argc, argv, short_opts, combined_opts,
- &option_index)) != -1) {
- switch(c) {
- case 'l':
- if (!run_single_subtest)
- list_subtests = true;
- break;
- case 'r':
- if (!list_subtests)
- run_single_subtest = strdup(optarg);
- break;
- case 'h':
- print_usage(command_str, help_str, false);
- ret = -1;
- goto out;
- case '?':
- if (opterr) {
- print_usage(command_str, help_str, true);
- ret = -2;
- goto out;
- }
- /*
- * Just ignore the error, since the unknown argument
- * can be something the caller understands and will
- * parse by doing a second getopt scanning.
- */
- break;
- default:
- ret = extra_opt_handler(c, option_index);
- if (ret)
- goto out;
- }
- }
-
- igt_install_exit_handler(check_igt_exit);
- oom_adjust_for_doom();
-
-out:
- free(short_opts);
- free(combined_opts);
- print_version();
-
- return ret;
-}
-
-enum igt_log_level igt_log_level = IGT_LOG_INFO;
-
-static void common_init(void)
-{
- char *env = getenv("IGT_LOG_LEVEL");
-
- if (!env)
- return;
-
- if (strcmp(env, "debug") == 0)
- igt_log_level = IGT_LOG_DEBUG;
- else if (strcmp(env, "info") == 0)
- igt_log_level = IGT_LOG_INFO;
- else if (strcmp(env, "warn") == 0)
- igt_log_level = IGT_LOG_WARN;
- else if (strcmp(env, "none") == 0)
- igt_log_level = IGT_LOG_NONE;
-}
-
-void igt_subtest_init(int argc, char **argv)
-{
- int ret;
-
- /* supress getopt errors about unknown options */
- opterr = 0;
-
- ret = igt_subtest_init_parse_opts(argc, argv, NULL, NULL, NULL, NULL);
- if (ret < 0)
- /* exit with no error for -h/--help */
- exit(ret == -1 ? 0 : ret);
-
- /* reset opt parsing */
- optind = 1;
-
- common_init();
-}
-
-void igt_simple_init(void)
-{
- print_version();
-
- common_init();
-}
-
-/*
- * Note: Testcases which use these helpers MUST NOT output anything to stdout
- * outside of places protected by igt_run_subtest checks - the piglit
- * runner adds every line to the subtest list.
- */
-bool __igt_run_subtest(const char *subtest_name)
-{
- assert(!in_subtest);
- assert(!in_fixture);
-
- if (list_subtests) {
- printf("%s\n", subtest_name);
- return false;
- }
-
- if (run_single_subtest &&
- strcmp(subtest_name, run_single_subtest) != 0)
- return false;
-
- if (skip_subtests_henceforth) {
- printf("Subtest %s: %s\n", subtest_name,
- skip_subtests_henceforth == SKIP ?
- "SKIP" : "FAIL");
- return false;
- }
-
- return (in_subtest = subtest_name);
-}
-
-const char *igt_subtest_name(void)
-{
- return in_subtest;
-}
-
-static bool igt_only_list_subtests(void)
-{
- return list_subtests;
-}
-
-static bool skipped_one = false;
-static bool succeeded_one = false;
-static bool failed_one = false;
-static int igt_exitcode;
-
-static void exit_subtest(const char *) __attribute__((noreturn));
-static void exit_subtest(const char *result)
-{
- printf("Subtest %s: %s\n", in_subtest, result);
- in_subtest = NULL;
- longjmp(igt_subtest_jmpbuf, 1);
-}
-
-void igt_skip(const char *f, ...)
-{
- va_list args;
- skipped_one = true;
-
- assert(!test_child);
-
- if (!igt_only_list_subtests()) {
- va_start(args, f);
- vprintf(f, args);
- va_end(args);
- }
-
- if (in_subtest) {
- exit_subtest("SKIP");
- } else if (test_with_subtests) {
- skip_subtests_henceforth = SKIP;
- assert(in_fixture);
- __igt_fixture_end();
- } else {
- exit(77);
- }
-}
-
-void __igt_skip_check(const char *file, const int line,
- const char *func, const char *check,
- const char *f, ...)
-{
- va_list args;
- int err = errno;
-
- if (f) {
- static char *buf;
-
- /* igt_skip never returns, so try to not leak too badly. */
- if (buf)
- free(buf);
-
- va_start(args, f);
- vasprintf(&buf, f, args);
- va_end(args);
-
- igt_skip("Test requirement not met in function %s, file %s:%i:\n"
- "Last errno: %i, %s\n"
- "Test requirement: (%s)\n%s",
- func, file, line, err, strerror(err), check, buf);
- } else {
- igt_skip("Test requirement not met in function %s, file %s:%i:\n"
- "Last errno: %i, %s\n"
- "Test requirement: (%s)\n",
- func, file, line, err, strerror(err), check);
- }
-}
-
-void igt_success(void)
-{
- succeeded_one = true;
- if (in_subtest)
- exit_subtest("SUCCESS");
-}
-
-void igt_fail(int exitcode)
-{
- assert(exitcode != 0 && exitcode != 77);
-
- if (!failed_one)
- igt_exitcode = exitcode;
-
- failed_one = true;
-
- /* Silent exit, parent will do the yelling. */
- if (test_child)
- exit(exitcode);
-
- if (in_subtest)
- exit_subtest("FAIL");
- else {
- assert(!test_with_subtests || in_fixture);
-
- if (in_fixture) {
- skip_subtests_henceforth = FAIL;
- __igt_fixture_end();
- }
-
- exit(exitcode);
- }
-}
-
-static bool run_under_gdb(void)
-{
- char buf[1024];
-
- sprintf(buf, "/proc/%d/exe", getppid());
- return (readlink (buf, buf, sizeof (buf)) != -1 &&
- strncmp(basename(buf), "gdb", 3) == 0);
-}
-
-void __igt_fail_assert(int exitcode, const char *file,
- const int line, const char *func, const char *assertion,
- const char *f, ...)
-{
- va_list args;
- int err = errno;
-
- printf("Test assertion failure function %s, file %s:%i:\n"
- "Last errno: %i, %s\n"
- "Failed assertion: %s\n",
- func, file, line, err, strerror(err), assertion);
-
- if (f) {
- va_start(args, f);
- vprintf(f, args);
- va_end(args);
- }
-
- if (run_under_gdb())
- abort();
- igt_fail(exitcode);
-}
-
-void igt_exit(void)
-{
- igt_exit_called = true;
-
- if (igt_only_list_subtests())
- exit(0);
-
- if (!test_with_subtests)
- exit(0);
-
- /* Calling this without calling one of the above is a failure */
- assert(skipped_one || succeeded_one || failed_one);
-
- if (failed_one)
- exit(igt_exitcode);
- else if (succeeded_one)
- exit(0);
- else
- exit(77);
-}
-
-static int helper_process_count;
-static pid_t helper_process_pids[] =
-{ -1, -1, -1, -1};
-
-static void reset_helper_process_list(void)
-{
- for (int i = 0; i < ARRAY_SIZE(helper_process_pids); i++)
- helper_process_pids[i] = -1;
- helper_process_count = 0;
-}
-
-static void fork_helper_exit_handler(int sig)
-{
- for (int i = 0; i < ARRAY_SIZE(helper_process_pids); i++) {
- pid_t pid = helper_process_pids[i];
- int status, ret;
-
- if (pid != -1) {
- /* Someone forgot to fill up the array? */
- assert(pid != 0);
-
- ret = kill(pid, SIGQUIT);
- assert(ret == 0);
- while (waitpid(pid, &status, 0) == -1 &&
- errno == EINTR)
- ;
- helper_process_count--;
- }
- }
-
- assert(helper_process_count == 0);
-}
-
-bool __igt_fork_helper(struct igt_helper_process *proc)
-{
- pid_t pid;
- int id;
-
- assert(!proc->running);
- assert(helper_process_count < ARRAY_SIZE(helper_process_pids));
-
- for (id = 0; helper_process_pids[id] != -1; id++)
- ;
-
- igt_install_exit_handler(fork_helper_exit_handler);
-
- switch (pid = fork()) {
- case -1:
- igt_assert(0);
- case 0:
- exit_handler_count = 0;
- reset_helper_process_list();
- oom_adjust_for_doom();
-
- return true;
- default:
- proc->running = true;
- proc->pid = pid;
- proc->id = id;
- helper_process_pids[id] = pid;
- helper_process_count++;
-
- return false;
- }
-
-}
-
-void igt_stop_helper(struct igt_helper_process *proc)
-{
- int status, ret;
-
- assert(proc->running);
-
- ret = kill(proc->pid,
- proc->use_SIGKILL ? SIGKILL : SIGQUIT);
- assert(ret == 0);
- while (waitpid(proc->pid, &status, 0) == -1 &&
- errno == EINTR)
- ;
- igt_assert(WIFSIGNALED(status) &&
- WTERMSIG(status) == (proc->use_SIGKILL ? SIGKILL : SIGQUIT));
-
- proc->running = false;
-
- helper_process_pids[proc->id] = -1;
- helper_process_count--;
-}
-
-void igt_wait_helper(struct igt_helper_process *proc)
-{
- int status;
-
- assert(proc->running);
-
- while (waitpid(proc->pid, &status, 0) == -1 &&
- errno == EINTR)
- ;
- igt_assert(WIFEXITED(status) && WEXITSTATUS(status) == 0);
-
- proc->running = false;
-
- helper_process_pids[proc->id] = -1;
- helper_process_count--;
-}
-
-static void children_exit_handler(int sig)
-{
- int ret;
-
- assert(!test_child);
-
- for (int nc = 0; nc < num_test_children; nc++) {
- int status = -1;
- ret = kill(test_children[nc], SIGQUIT);
- assert(ret == 0);
-
- while (waitpid(test_children[nc], &status, 0) == -1 &&
- errno == EINTR)
- ;
- }
-
- num_test_children = 0;
-}
-
-bool __igt_fork(void)
-{
- assert(!test_with_subtests || in_subtest);
- assert(!test_child);
-
- igt_install_exit_handler(children_exit_handler);
-
- if (num_test_children >= test_children_sz) {
- if (!test_children_sz)
- test_children_sz = 4;
- else
- test_children_sz *= 2;
-
- test_children = realloc(test_children,
- sizeof(pid_t)*test_children_sz);
- igt_assert(test_children);
- }
-
- switch (test_children[num_test_children++] = fork()) {
- case -1:
- igt_assert(0);
- case 0:
- test_child = true;
- exit_handler_count = 0;
- reset_helper_process_list();
- oom_adjust_for_doom();
-
- return true;
- default:
- return false;
- }
-
-}
-
-/**
- * igt_waitchildren:
- *
- * Wait for all children forked with igt_fork
- *
- * The magic here is that exit codes from children will be correctly propagated
- */
-void igt_waitchildren(void)
-{
- assert(!test_child);
-
- for (int nc = 0; nc < num_test_children; nc++) {
- int status = -1;
- while (waitpid(test_children[nc], &status, 0) == -1 &&
- errno == EINTR)
- ;
-
- if (status != 0) {
- if (WIFEXITED(status)) {
- printf("child %i failed with exit status %i\n",
- nc, WEXITSTATUS(status));
- igt_fail(WEXITSTATUS(status));
- } else if (WIFSIGNALED(status)) {
- printf("child %i died with signal %i, %s\n",
- nc, WTERMSIG(status),
- strsignal(WTERMSIG(status)));
- igt_fail(99);
- } else {
- printf("Unhandled failure in child %i\n", nc);
- abort();
- }
- }
- }
-
- num_test_children = 0;
-}
-
-static bool env_set(const char *env_var, bool default_value)
+bool igt_env_set(const char *env_var, bool default_value)
{
char *val;
@@ -947,59 +327,12 @@ static bool env_set(const char *env_var, bool default_value)
return atoi(val) != 0;
}
-bool igt_run_in_simulation(void)
-{
- static int simulation = -1;
-
- if (simulation == -1)
- simulation = env_set("INTEL_SIMULATION", false);
-
- return simulation;
-}
-
-/**
- * igt_skip_on_simulation:
- *
- * Skip tests when INTEL_SIMULATION env war is set
- *
- * Skip the test when running on simulation (and that's relevant only when
- * we're not in the mode where we list the subtests).
- *
- * This function is subtest aware (since it uses igt_skip) and so can be used to
- * skip specific subtests or all subsequent subtests.
- */
-void igt_skip_on_simulation(void)
-{
- if (igt_only_list_subtests())
- return;
-
- igt_require(!igt_run_in_simulation());
-}
-
-void igt_log(enum igt_log_level level, const char *format, ...)
-{
- va_list args;
-
- assert(format);
-
- if (igt_log_level > level)
- return;
-
- va_start(args, format);
- if (level == IGT_LOG_WARN) {
- fflush(stdout);
- vfprintf(stderr, format, args);
- } else
- vprintf(format, args);
- va_end(args);
-}
-
bool drmtest_dump_aub(void)
{
static int dump_aub = -1;
if (dump_aub == -1)
- dump_aub = env_set("IGT_DUMP_AUB", false);
+ dump_aub = igt_env_set("IGT_DUMP_AUB", false);
return dump_aub;
}
@@ -1092,165 +425,6 @@ void igt_cleanup_aperture_trashers(void)
free(trash_bos);
}
-#define MAX_SIGNALS 32
-#define MAX_EXIT_HANDLERS 5
-
-static struct {
- sighandler_t handler;
- bool installed;
-} orig_sig[MAX_SIGNALS];
-
-static igt_exit_handler_t exit_handler_fn[MAX_EXIT_HANDLERS];
-static bool exit_handler_disabled;
-static sigset_t saved_sig_mask;
-static const int handled_signals[] =
- { SIGINT, SIGHUP, SIGTERM, SIGQUIT, SIGPIPE, SIGABRT, SIGSEGV, SIGBUS };
-
-static int install_sig_handler(int sig_num, sighandler_t handler)
-{
- orig_sig[sig_num].handler = signal(sig_num, handler);
-
- if (orig_sig[sig_num].handler == SIG_ERR)
- return -1;
-
- orig_sig[sig_num].installed = true;
-
- return 0;
-}
-
-static void restore_sig_handler(int sig_num)
-{
- /* Just restore the default so that we properly fall over. */
- signal(sig_num, SIG_DFL);
-}
-
-static void restore_all_sig_handler(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(orig_sig); i++)
- restore_sig_handler(i);
-}
-
-static void call_exit_handlers(int sig)
-{
- int i;
-
- if (!exit_handler_count) {
- return;
- }
-
- for (i = exit_handler_count - 1; i >= 0; i--)
- exit_handler_fn[i](sig);
-
- /* ensure we don't get called twice */
- exit_handler_count = 0;
-}
-
-static void igt_atexit_handler(void)
-{
- restore_all_sig_handler();
-
- if (!exit_handler_disabled)
- call_exit_handlers(0);
-}
-
-static void fatal_sig_handler(int sig)
-{
- pid_t pid, tid;
-
- restore_all_sig_handler();
-
- /*
- * exit_handler_disabled is always false here, since when we set it
- * we also block signals.
- */
- call_exit_handlers(sig);
-
- /* Workaround cached PID and TID races on glibc and Bionic libc. */
- pid = syscall(SYS_getpid);
- tid = syscall(SYS_gettid);
-
- syscall(SYS_tgkill, pid, tid, sig);
-}
-
-/*
- * Set a handler that will be called either when the process calls exit() or
- * returns from the main function, or one of the signals in 'handled_signals'
- * is raised. MAX_EXIT_HANDLERS handlers can be installed, each of which will
- * be called only once, even if a subsequent signal is raised. If the exit
- * handlers are called due to a signal, the signal will be re-raised with the
- * original signal disposition after all handlers returned.
- *
- * The handler will be passed the signal number if called due to a signal, or
- * 0 otherwise.
- */
-void igt_install_exit_handler(igt_exit_handler_t fn)
-{
- int i;
-
- for (i = 0; i < exit_handler_count; i++)
- if (exit_handler_fn[i] == fn)
- return;
-
- igt_assert(exit_handler_count < MAX_EXIT_HANDLERS);
-
- exit_handler_fn[exit_handler_count] = fn;
- exit_handler_count++;
-
- if (exit_handler_count > 1)
- return;
-
- for (i = 0; i < ARRAY_SIZE(handled_signals); i++) {
- if (install_sig_handler(handled_signals[i],
- fatal_sig_handler))
- goto err;
- }
-
- if (atexit(igt_atexit_handler))
- goto err;
-
- return;
-err:
- restore_all_sig_handler();
- exit_handler_count--;
-
- igt_assert_f(0, "failed to install the signal handler\n");
-}
-
-void igt_disable_exit_handler(void)
-{
- sigset_t set;
- int i;
-
- if (exit_handler_disabled)
- return;
-
- sigemptyset(&set);
- for (i = 0; i < ARRAY_SIZE(handled_signals); i++)
- sigaddset(&set, handled_signals[i]);
-
- if (sigprocmask(SIG_BLOCK, &set, &saved_sig_mask)) {
- perror("sigprocmask");
- return;
- }
-
- exit_handler_disabled = true;
-}
-
-void igt_enable_exit_handler(void)
-{
- if (!exit_handler_disabled)
- return;
-
- if (sigprocmask(SIG_SETMASK, &saved_sig_mask, NULL)) {
- perror("sigprocmask");
- return;
- }
-
- exit_handler_disabled = false;
-}
-
#define PREFAULT_DEBUGFS "/sys/module/i915/parameters/prefault_disable"
static void igt_prefault_control(bool enable)
{