summaryrefslogtreecommitdiff
path: root/runner
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2021-01-07 10:37:03 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2021-01-08 13:59:02 +0000
commit532d6e84ab7fab9568dabc63a4620a257ea2fdff (patch)
tree46bb04a1c1fe58340f9c53c504d66fcb2c8014c7 /runner
parent39768c976b920dcf0f159284bce882088aa65c50 (diff)
lib: Process kernel taints
A small library routine to read '/proc/sys/kernel/taints' and check for a fatal condition. This is currently used by the runner, but is also useful for some tests. v2,3: function docs Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Petri Latvala <petri.latvala@intel.com> Reviewed-by: Petri Latvala <petri.latvala@intel.com>
Diffstat (limited to 'runner')
-rw-r--r--runner/executor.c73
1 files changed, 14 insertions, 59 deletions
diff --git a/runner/executor.c b/runner/executor.c
index faf272d8..93db8bb3 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -24,6 +24,7 @@
#include "igt_aux.h"
#include "igt_core.h"
+#include "igt_taints.h"
#include "executor.h"
#include "output_strings.h"
@@ -307,70 +308,23 @@ static char *handle_lockdep(void)
return NULL;
}
-/* see Linux's include/linux/kernel.h */
-static const struct {
- unsigned long bit;
- const char *explanation;
-} abort_taints[] = {
- {(1 << 5), "TAINT_BAD_PAGE: Bad page reference or an unexpected page flags."},
- {(1 << 7), "TAINT_DIE: Kernel has died - BUG/OOPS."},
- {(1 << 9), "TAINT_WARN: WARN_ON has happened."},
- {0, 0}};
-
-static unsigned long bad_taints(void)
-{
- static unsigned long __bad_taints;
-
- if (!__bad_taints) {
- for (typeof(*abort_taints) *taint = abort_taints;
- taint->bit;
- taint++)
- __bad_taints |= taint->bit;
- }
-
- return __bad_taints;
-}
-
-static unsigned long is_tainted(unsigned long taints)
-{
- return taints & bad_taints();
-}
-
-static unsigned long tainted(unsigned long *taints)
-{
- FILE *f;
-
- *taints = 0;
-
- f = fopen("/proc/sys/kernel/tainted", "r");
- if (f) {
- fscanf(f, "%lu", taints);
- fclose(f);
- }
-
- return is_tainted(*taints);
-}
-
static char *handle_taint(void)
{
- unsigned long taints;
+ unsigned long taints, bad;
+ char *explain;
char *reason;
- if (!tainted(&taints))
+ bad = igt_kernel_tainted(&taints);
+ if (!bad)
return NULL;
- asprintf(&reason, "Kernel badly tainted (%#lx) (check dmesg for details):\n",
- taints);
-
- for (typeof(*abort_taints) *taint = abort_taints; taint->bit; taint++) {
- if (taint->bit & taints) {
- char *old_reason = reason;
- asprintf(&reason, "%s\t(%#lx) %s\n",
- old_reason,
- taint->bit,
- taint->explanation);
- free(old_reason);
- }
+ asprintf(&reason, "Kernel badly tainted (%#lx, %#lx) (check dmesg for details):\n",
+ taints, bad);
+
+ while ((explain = igt_explain_taints(&bad))) {
+ char *old_reason = reason;
+ asprintf(&reason, "%s\t%s\n", old_reason, explain);
+ free(old_reason);
}
return reason;
@@ -1142,7 +1096,8 @@ static int monitor_output(pid_t child,
sigfd = -1; /* we are dying, no signal handling for now */
}
- timeout_reason = need_to_timeout(settings, killed, tainted(&taints),
+ timeout_reason = need_to_timeout(settings, killed,
+ igt_kernel_tainted(&taints),
igt_time_elapsed(&time_last_activity, &time_now),
igt_time_elapsed(&time_last_subtest, &time_now),
igt_time_elapsed(&time_killed, &time_now),