All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error
@ 2018-11-06 14:26 Petri Latvala
  2018-11-06 14:45 ` Martin Peres
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Petri Latvala @ 2018-11-06 14:26 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, Martin Peres, Tomi Sarvela

Deviating a bit from the piglit command line flag, igt_runner takes an
optional comma-separated list as an argument to
--abort-on-monitored-error for the list of conditions to abort
on. Without a list all possible conditions will be checked.

Two conditions implemented:
 - "taint" checks the kernel taint level for TAINT_PAGE, TAINT_DIE and
 TAINT_OOPS
 - "lockdep" checks the kernel lockdep status

Checking is done after every test binary execution, and if an abort
condition is met, the reason is printed to stderr (unless log level is
quiet) and the runner doesn't execute any further tests. Aborting
between subtests (when running in --multiple-mode) is not done.

A TODO item for the future is having aborting appear in the test
results.

v2:
 - Remember to fclose
 - Taints are unsigned long (Chris)
 - Use getline instead of fgets (Chris)
v3:
 - Fix brainfart with lockdep
v4:
 - Rebase
 - Refactor the abort condition checking to pass down strings
 - Present the abort result in results.json as a pseudo test result
 - Unit tests for the pseudo result

Signed-off-by: Petri Latvala <petri.latvala@intel.com>
Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Cc: Tomi Sarvela <tomi.p.sarvela@intel.com>
Cc: Martin Peres <martin.peres@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 runner/executor.c                             | 189 ++++++++++++++++--
 runner/executor.h                             |   1 +
 .../aborted-after-a-test/0/dmesg.txt          |   5 +
 .../aborted-after-a-test/0/err.txt            |   2 +
 .../aborted-after-a-test/0/journal.txt        |   2 +
 .../aborted-after-a-test/0/out.txt            |   3 +
 .../aborted-after-a-test/README.txt           |   1 +
 .../aborted-after-a-test/aborted.txt          |   3 +
 .../aborted-after-a-test/endtime.txt          |   1 +
 .../aborted-after-a-test/joblist.txt          |   5 +
 .../aborted-after-a-test/metadata.txt         |  12 ++
 .../aborted-after-a-test/reference.json       |  90 +++++++++
 .../aborted-after-a-test/starttime.txt        |   1 +
 .../aborted-after-a-test/uname.txt            |   1 +
 .../aborted-on-boot/README.txt                |   1 +
 .../aborted-on-boot/aborted.txt               |   3 +
 .../aborted-on-boot/endtime.txt               |   1 +
 .../aborted-on-boot/joblist.txt               |   5 +
 .../aborted-on-boot/metadata.txt              |  12 ++
 .../aborted-on-boot/reference.json            |  59 ++++++
 .../aborted-on-boot/starttime.txt             |   1 +
 .../json_tests_data/aborted-on-boot/uname.txt |   1 +
 .../dmesg-results/metadata.txt                |   2 +-
 .../metadata.txt                              |   2 +-
 .../json_tests_data/normal-run/metadata.txt   |   2 +-
 .../piglit-style-dmesg/metadata.txt           |   2 +-
 .../warnings-with-dmesg-warns/metadata.txt    |   2 +-
 runner/json_tests_data/warnings/metadata.txt  |   2 +-
 runner/resultgen.c                            |  48 ++++-
 runner/runner_json_tests.c                    |   2 +
 runner/runner_tests.c                         |  49 ++++-
 runner/settings.c                             |  79 +++++++-
 runner/settings.h                             |   8 +-
 33 files changed, 556 insertions(+), 41 deletions(-)
 create mode 100644 runner/json_tests_data/aborted-after-a-test/0/dmesg.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/0/err.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/0/journal.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/0/out.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/README.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/aborted.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/endtime.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/joblist.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/metadata.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/reference.json
 create mode 100644 runner/json_tests_data/aborted-after-a-test/starttime.txt
 create mode 100644 runner/json_tests_data/aborted-after-a-test/uname.txt
 create mode 100644 runner/json_tests_data/aborted-on-boot/README.txt
 create mode 100644 runner/json_tests_data/aborted-on-boot/aborted.txt
 create mode 100644 runner/json_tests_data/aborted-on-boot/endtime.txt
 create mode 100644 runner/json_tests_data/aborted-on-boot/joblist.txt
 create mode 100644 runner/json_tests_data/aborted-on-boot/metadata.txt
 create mode 100644 runner/json_tests_data/aborted-on-boot/reference.json
 create mode 100644 runner/json_tests_data/aborted-on-boot/starttime.txt
 create mode 100644 runner/json_tests_data/aborted-on-boot/uname.txt

diff --git a/runner/executor.c b/runner/executor.c
index 007b72ce..ed444a9a 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -108,6 +108,90 @@ static void ping_watchdogs(void)
 	}
 }
 
+static char *handle_lockdep(void)
+{
+	FILE *f = fopen("/proc/lockdep_stats", "r");
+	const char *debug_locks_line = " debug_locks:";
+	char *buf = NULL;
+	size_t bufsize = 0;
+	int val;
+	char *reason = NULL;
+
+	if (!f)
+		return reason;
+
+	while (getline(&buf, &bufsize, f) > 0) {
+		if (!strncmp(buf, debug_locks_line, strlen(debug_locks_line))) {
+			char *p = buf + strlen(debug_locks_line);
+			if (sscanf(p, "%d", &val) == 1 &&
+			    val != 1)
+				asprintf(&reason, "Lockdep triggered\n");
+
+			break;
+		}
+	}
+
+	fclose(f);
+	free(buf);
+	return reason;
+}
+
+static char *handle_taint(void)
+{
+	FILE *f = fopen("/proc/sys/kernel/tainted", "r");
+	int s;
+	unsigned long taint;
+	unsigned long bad_taints =
+		0x20  | /* TAINT_PAGE */
+		0x80  | /* TAINT_DIE */
+		0x200; /* TAINT_OOPS */
+
+	if (!f)
+		return NULL;
+
+	s = fscanf(f, "%lu", &taint);
+	fclose(f);
+
+	if (s != 1)
+		return NULL;
+
+	if (taint & bad_taints) {
+		char *reason;
+
+		asprintf(&reason, "Kernel tainted (0x%lx)\n", taint);
+
+		return reason;
+	}
+
+	return NULL;
+}
+
+static struct {
+	int condition;
+	char *(*handler)(void);
+} abort_handlers[] = {
+	{ ABORT_LOCKDEP, handle_lockdep },
+	{ ABORT_TAINT, handle_taint },
+	{ 0, 0 },
+};
+
+static char *need_to_abort(struct settings* settings)
+{
+	typeof(*abort_handlers) *it;
+	char *ret = NULL;
+
+	for (it = abort_handlers; it->condition; it++) {
+		if (settings->abort_mask & it->condition &&
+		    (ret = it->handler()) != NULL) {
+			if (settings->log_level >= LOG_LEVEL_NORMAL)
+				fprintf(stderr, "%s", ret);
+		}
+		break;
+	}
+
+	return ret;
+}
+
 static void prune_subtest(struct job_list_entry *entry, char *subtest)
 {
 	char *excl;
@@ -714,6 +798,37 @@ static void print_time_left(struct execute_state *state,
 	printf("(%*.0fs left) ", width, state->time_left);
 }
 
+static char *entry_display_name(struct job_list_entry *entry)
+{
+	size_t size = strlen(entry->binary) + 1;
+	char *ret = malloc(size);
+
+	sprintf(ret, "%s", entry->binary);
+
+	if (entry->subtest_count > 0) {
+		size_t i;
+		const char *delim = "";
+
+		size += 3; /* strlen(" (") + strlen(")") */
+		ret = realloc(ret, size);
+		strcat(ret, " (");
+
+		for (i = 0; i < entry->subtest_count; i++) {
+			size += strlen(delim) + strlen(entry->subtests[i]);
+			ret = realloc(ret, size);
+
+			strcat(ret, delim);
+			strcat(ret, entry->subtests[i]);
+
+			delim = ", ";
+		}
+		/* There's already room for this */
+		strcat(ret, ")");
+	}
+
+	return ret;
+}
+
 /*
  * Returns:
  *  =0 - Success
@@ -797,24 +912,15 @@ static int execute_next_entry(struct execute_state *state,
 	}
 
 	if (settings->log_level >= LOG_LEVEL_NORMAL) {
+		char *displayname;
 		int width = digits(total);
 		printf("[%0*zd/%0*zd] ", width, idx + 1, width, total);
 
 		print_time_left(state, settings);
 
-		printf("%s", entry->binary);
-
-		if (entry->subtest_count > 0) {
-			size_t i;
-			const char *delim = "";
-
-			printf(" (");
-			for (i = 0; i < entry->subtest_count; i++) {
-				printf("%s%s", delim, entry->subtests[i]);
-				delim = ", ";
-			}
-			printf(")");
-		}
+		displayname = entry_display_name(entry);
+		printf("%s", displayname);
+		free(displayname);
 
 		printf("\n");
 	}
@@ -896,7 +1002,8 @@ static bool clear_old_results(char *path)
 
 	if (remove_file(dirfd, "uname.txt") ||
 	    remove_file(dirfd, "starttime.txt") ||
-	    remove_file(dirfd, "endtime.txt")) {
+	    remove_file(dirfd, "endtime.txt") ||
+	    remove_file(dirfd, "aborted.txt")) {
 		close(dirfd);
 		fprintf(stderr, "Error clearing old results: %s\n", strerror(errno));
 		return false;
@@ -957,6 +1064,7 @@ bool initialize_execute_state_from_resume(int dirfd,
 	free_settings(settings);
 	free_job_list(list);
 	memset(state, 0, sizeof(*state));
+	state->resuming = true;
 
 	if (!read_settings(settings, dirfd) ||
 	    !read_job_list(list, dirfd)) {
@@ -1044,6 +1152,22 @@ static bool overall_timeout_exceeded(struct execute_state *state)
 	return state->time_left == 0.0;
 }
 
+static void write_abort_file(int resdirfd, const char *reason, const char *testname)
+{
+	int abortfd;
+
+	if ((abortfd = openat(resdirfd, "aborted.txt", O_CREAT | O_WRONLY | O_EXCL, 0666)) >= 0) {
+		/*
+		 * Ignore failure to open, there's
+		 * already an abort probably (if this
+		 * is a resume)
+		 */
+		dprintf(abortfd, "Aborted after: %s\n\n", testname);
+		write(abortfd, reason, strlen(reason));
+		close(abortfd);
+	}
+}
+
 bool execute(struct execute_state *state,
 	     struct settings *settings,
 	     struct job_list *job_list)
@@ -1100,14 +1224,29 @@ bool execute(struct execute_state *state,
 	}
 	close(unamefd);
 
+	/* Check if we're already in abort-state at bootup */
+	if (!state->resuming) {
+		char *reason;
+
+		if ((reason = need_to_abort(settings)) != NULL) {
+			write_abort_file(resdirfd, reason, "startup");
+			free(reason);
+
+			goto end;
+		}
+	}
+
 	for (; state->next < job_list->size;
 	     state->next++) {
-		int result = execute_next_entry(state,
-						job_list->size,
-						&time_spent,
-						settings,
-						&job_list->entries[state->next],
-						testdirfd, resdirfd);
+		char *reason;
+		int result;
+
+		result = execute_next_entry(state,
+					    job_list->size,
+					    &time_spent,
+					    settings,
+					    &job_list->entries[state->next],
+					    testdirfd, resdirfd);
 
 		if (result < 0) {
 			status = false;
@@ -1124,6 +1263,15 @@ bool execute(struct execute_state *state,
 			break;
 		}
 
+		if ((reason = need_to_abort(settings)) != NULL) {
+			char *displayname = entry_display_name(&job_list->entries[state->next]);
+			write_abort_file(resdirfd, reason, displayname);
+			free(displayname);
+			free(reason);
+			status = false;
+			break;
+		}
+
 		if (result > 0) {
 			double time_left = state->time_left;
 
@@ -1140,6 +1288,7 @@ bool execute(struct execute_state *state,
 		close(timefd);
 	}
 
+ end:
 	close(testdirfd);
 	close(resdirfd);
 	close_watchdogs(settings);
diff --git a/runner/executor.h b/runner/executor.h
index 252339ab..12883f15 100644
--- a/runner/executor.h
+++ b/runner/executor.h
@@ -13,6 +13,7 @@ struct execute_state
 	 * > 0 : Timeout in use, time left.
 	 */
 	double time_left;
+	double resuming;
 };
 
 enum {
diff --git a/runner/json_tests_data/aborted-after-a-test/0/dmesg.txt b/runner/json_tests_data/aborted-after-a-test/0/dmesg.txt
new file mode 100644
index 00000000..a189e704
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/0/dmesg.txt
@@ -0,0 +1,5 @@
+6,951,3216186095083,-;Console: switching to colour dummy device 80x25
+14,952,3216186095097,-;[IGT] successtest: executing
+14,953,3216186101115,-;[IGT] successtest: starting subtest first-subtest
+14,954,3216186101160,-;[IGT] successtest: exiting, ret=0
+6,955,3216186101299,-;Console: switching to colour frame buffer device 240x75
diff --git a/runner/json_tests_data/aborted-after-a-test/0/err.txt b/runner/json_tests_data/aborted-after-a-test/0/err.txt
new file mode 100644
index 00000000..5dc78057
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/0/err.txt
@@ -0,0 +1,2 @@
+Starting subtest: first-subtest
+Subtest first-subtest: SUCCESS (0.000s)
diff --git a/runner/json_tests_data/aborted-after-a-test/0/journal.txt b/runner/json_tests_data/aborted-after-a-test/0/journal.txt
new file mode 100644
index 00000000..86a30e07
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/0/journal.txt
@@ -0,0 +1,2 @@
+first-subtest
+exit:0 (0.014s)
diff --git a/runner/json_tests_data/aborted-after-a-test/0/out.txt b/runner/json_tests_data/aborted-after-a-test/0/out.txt
new file mode 100644
index 00000000..5946bf31
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/0/out.txt
@@ -0,0 +1,3 @@
+IGT-Version: 1.23-g0c763bfd (x86_64) (Linux: 4.18.0-1-amd64 x86_64)
+Starting subtest: first-subtest
+Subtest first-subtest: SUCCESS (0.000s)
diff --git a/runner/json_tests_data/aborted-after-a-test/README.txt b/runner/json_tests_data/aborted-after-a-test/README.txt
new file mode 100644
index 00000000..1ad89053
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/README.txt
@@ -0,0 +1 @@
+A run that aborted after running the first test.
diff --git a/runner/json_tests_data/aborted-after-a-test/aborted.txt b/runner/json_tests_data/aborted-after-a-test/aborted.txt
new file mode 100644
index 00000000..3c8f2707
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/aborted.txt
@@ -0,0 +1,3 @@
+Aborted after: successtest (first-subtest)
+
+Kernel tainted (0x200)
diff --git a/runner/json_tests_data/aborted-after-a-test/endtime.txt b/runner/json_tests_data/aborted-after-a-test/endtime.txt
new file mode 100644
index 00000000..635f6ae9
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/endtime.txt
@@ -0,0 +1 @@
+1539953735.172373
diff --git a/runner/json_tests_data/aborted-after-a-test/joblist.txt b/runner/json_tests_data/aborted-after-a-test/joblist.txt
new file mode 100644
index 00000000..31ef8413
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/joblist.txt
@@ -0,0 +1,5 @@
+successtest first-subtest
+successtest second-subtest
+no-subtests
+skippers skip-one
+skippers skip-two
diff --git a/runner/json_tests_data/aborted-after-a-test/metadata.txt b/runner/json_tests_data/aborted-after-a-test/metadata.txt
new file mode 100644
index 00000000..785076e9
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/metadata.txt
@@ -0,0 +1,12 @@
+abort_mask : 3
+name : normal-run
+dry_run : 0
+sync : 0
+log_level : 0
+overwrite : 0
+multiple_mode : 0
+inactivity_timeout : 0
+use_watchdog : 0
+piglit_style_dmesg : 0
+test_root : /path/does/not/exist
+results_path : /path/does/not/exist
diff --git a/runner/json_tests_data/aborted-after-a-test/reference.json b/runner/json_tests_data/aborted-after-a-test/reference.json
new file mode 100644
index 00000000..37f7922c
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/reference.json
@@ -0,0 +1,90 @@
+{
+  "__type__":"TestrunResult",
+  "results_version":9,
+  "name":"normal-run",
+  "uname":"Linux hostname 4.18.0-1-amd64 #1 SMP Debian 4.18.6-1 (2018-09-06) x86_64",
+  "time_elapsed":{
+    "__type__":"TimeAttribute",
+    "start":1539953735.1110389,
+    "end":1539953735.1723731
+  },
+  "tests":{
+    "igt@successtest@first-subtest":{
+      "out":"Starting subtest: first-subtest\nSubtest first-subtest: SUCCESS (0.000s)\n",
+      "igt-version":"IGT-Version: 1.23-g0c763bfd (x86_64) (Linux: 4.18.0-1-amd64 x86_64)",
+      "result":"pass",
+      "time":{
+        "__type__":"TimeAttribute",
+        "start":0,
+        "end":0
+      },
+      "err":"Starting subtest: first-subtest\nSubtest first-subtest: SUCCESS (0.000s)\n",
+      "dmesg":"<6> [3216186.095083] Console: switching to colour dummy device 80x25\n<6> [3216186.095097] [IGT] successtest: executing\n<6> [3216186.101115] [IGT] successtest: starting subtest first-subtest\n<6> [3216186.101160] [IGT] successtest: exiting, ret=0\n<6> [3216186.101299] Console: switching to colour frame buffer device 240x75\n"
+    },
+    "igt@pseudoresult@aborted":{
+	"out":"Aborted after: successtest (first-subtest)\n\nKernel tainted (0x200)\n",
+	"result":"fail",
+	"err":"",
+	"dmesg":"",
+    }
+  },
+  "totals":{
+    "":{
+      "crash":0,
+      "pass":1,
+      "dmesg-fail":0,
+      "dmesg-warn":0,
+      "skip":0,
+      "incomplete":0,
+      "timeout":0,
+      "notrun":0,
+      "fail":1,
+      "warn":0
+    },
+    "root":{
+      "crash":0,
+      "pass":1,
+      "dmesg-fail":0,
+      "dmesg-warn":0,
+      "skip":0,
+      "incomplete":0,
+      "timeout":0,
+      "notrun":0,
+      "fail":1,
+      "warn":0
+    },
+    "igt@successtest":{
+      "crash":0,
+      "pass":1,
+      "dmesg-fail":0,
+      "dmesg-warn":0,
+      "skip":0,
+      "incomplete":0,
+      "timeout":0,
+      "notrun":0,
+      "fail":0,
+      "warn":0
+    },
+    "igt@pseudoresult":{
+      "crash":0,
+      "pass":0,
+      "dmesg-fail":0,
+      "dmesg-warn":0,
+      "skip":0,
+      "incomplete":0,
+      "timeout":0,
+      "notrun":0,
+      "fail":1,
+      "warn":0
+    },
+  },
+  "runtimes":{
+    "igt@successtest":{
+      "time":{
+        "__type__":"TimeAttribute",
+        "start":0,
+        "end":0.014
+      }
+    },
+  }
+}
diff --git a/runner/json_tests_data/aborted-after-a-test/starttime.txt b/runner/json_tests_data/aborted-after-a-test/starttime.txt
new file mode 100644
index 00000000..ae038f18
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/starttime.txt
@@ -0,0 +1 @@
+1539953735.111039
diff --git a/runner/json_tests_data/aborted-after-a-test/uname.txt b/runner/json_tests_data/aborted-after-a-test/uname.txt
new file mode 100644
index 00000000..a7aef6f7
--- /dev/null
+++ b/runner/json_tests_data/aborted-after-a-test/uname.txt
@@ -0,0 +1 @@
+Linux hostname 4.18.0-1-amd64 #1 SMP Debian 4.18.6-1 (2018-09-06) x86_64
diff --git a/runner/json_tests_data/aborted-on-boot/README.txt b/runner/json_tests_data/aborted-on-boot/README.txt
new file mode 100644
index 00000000..e957c40f
--- /dev/null
+++ b/runner/json_tests_data/aborted-on-boot/README.txt
@@ -0,0 +1 @@
+A run that aborted before running any tests.
diff --git a/runner/json_tests_data/aborted-on-boot/aborted.txt b/runner/json_tests_data/aborted-on-boot/aborted.txt
new file mode 100644
index 00000000..4a1c1a32
--- /dev/null
+++ b/runner/json_tests_data/aborted-on-boot/aborted.txt
@@ -0,0 +1,3 @@
+Aborted after: startup
+
+Kernel tainted (0x200)
diff --git a/runner/json_tests_data/aborted-on-boot/endtime.txt b/runner/json_tests_data/aborted-on-boot/endtime.txt
new file mode 100644
index 00000000..635f6ae9
--- /dev/null
+++ b/runner/json_tests_data/aborted-on-boot/endtime.txt
@@ -0,0 +1 @@
+1539953735.172373
diff --git a/runner/json_tests_data/aborted-on-boot/joblist.txt b/runner/json_tests_data/aborted-on-boot/joblist.txt
new file mode 100644
index 00000000..31ef8413
--- /dev/null
+++ b/runner/json_tests_data/aborted-on-boot/joblist.txt
@@ -0,0 +1,5 @@
+successtest first-subtest
+successtest second-subtest
+no-subtests
+skippers skip-one
+skippers skip-two
diff --git a/runner/json_tests_data/aborted-on-boot/metadata.txt b/runner/json_tests_data/aborted-on-boot/metadata.txt
new file mode 100644
index 00000000..785076e9
--- /dev/null
+++ b/runner/json_tests_data/aborted-on-boot/metadata.txt
@@ -0,0 +1,12 @@
+abort_mask : 3
+name : normal-run
+dry_run : 0
+sync : 0
+log_level : 0
+overwrite : 0
+multiple_mode : 0
+inactivity_timeout : 0
+use_watchdog : 0
+piglit_style_dmesg : 0
+test_root : /path/does/not/exist
+results_path : /path/does/not/exist
diff --git a/runner/json_tests_data/aborted-on-boot/reference.json b/runner/json_tests_data/aborted-on-boot/reference.json
new file mode 100644
index 00000000..44f26664
--- /dev/null
+++ b/runner/json_tests_data/aborted-on-boot/reference.json
@@ -0,0 +1,59 @@
+{
+  "__type__":"TestrunResult",
+  "results_version":9,
+  "name":"normal-run",
+  "uname":"Linux hostname 4.18.0-1-amd64 #1 SMP Debian 4.18.6-1 (2018-09-06) x86_64",
+  "time_elapsed":{
+    "__type__":"TimeAttribute",
+    "start":1539953735.1110389,
+    "end":1539953735.1723731
+  },
+  "tests":{
+    "igt@pseudoresult@aborted":{
+	"out":"Aborted after: startup\n\nKernel tainted (0x200)\n",
+	"result":"fail",
+	"err":"",
+	"dmesg":"",
+    }
+  },
+  "totals":{
+    "":{
+      "crash":0,
+      "pass":0,
+      "dmesg-fail":0,
+      "dmesg-warn":0,
+      "skip":0,
+      "incomplete":0,
+      "timeout":0,
+      "notrun":0,
+      "fail":1,
+      "warn":0
+    },
+    "root":{
+      "crash":0,
+      "pass":0,
+      "dmesg-fail":0,
+      "dmesg-warn":0,
+      "skip":0,
+      "incomplete":0,
+      "timeout":0,
+      "notrun":0,
+      "fail":1,
+      "warn":0
+    },
+    "igt@pseudoresult":{
+      "crash":0,
+      "pass":0,
+      "dmesg-fail":0,
+      "dmesg-warn":0,
+      "skip":0,
+      "incomplete":0,
+      "timeout":0,
+      "notrun":0,
+      "fail":1,
+      "warn":0
+    },
+  },
+  "runtimes":{
+  }
+}
diff --git a/runner/json_tests_data/aborted-on-boot/starttime.txt b/runner/json_tests_data/aborted-on-boot/starttime.txt
new file mode 100644
index 00000000..ae038f18
--- /dev/null
+++ b/runner/json_tests_data/aborted-on-boot/starttime.txt
@@ -0,0 +1 @@
+1539953735.111039
diff --git a/runner/json_tests_data/aborted-on-boot/uname.txt b/runner/json_tests_data/aborted-on-boot/uname.txt
new file mode 100644
index 00000000..a7aef6f7
--- /dev/null
+++ b/runner/json_tests_data/aborted-on-boot/uname.txt
@@ -0,0 +1 @@
+Linux hostname 4.18.0-1-amd64 #1 SMP Debian 4.18.6-1 (2018-09-06) x86_64
diff --git a/runner/json_tests_data/dmesg-results/metadata.txt b/runner/json_tests_data/dmesg-results/metadata.txt
index 1316560d..c501ae0e 100644
--- a/runner/json_tests_data/dmesg-results/metadata.txt
+++ b/runner/json_tests_data/dmesg-results/metadata.txt
@@ -1,4 +1,4 @@
-abort_on_error : 0
+abort_mask : 0
 name : normal-run
 dry_run : 0
 sync : 0
diff --git a/runner/json_tests_data/incomplete-before-any-subtests/metadata.txt b/runner/json_tests_data/incomplete-before-any-subtests/metadata.txt
index 1316560d..c501ae0e 100644
--- a/runner/json_tests_data/incomplete-before-any-subtests/metadata.txt
+++ b/runner/json_tests_data/incomplete-before-any-subtests/metadata.txt
@@ -1,4 +1,4 @@
-abort_on_error : 0
+abort_mask : 0
 name : normal-run
 dry_run : 0
 sync : 0
diff --git a/runner/json_tests_data/normal-run/metadata.txt b/runner/json_tests_data/normal-run/metadata.txt
index 1316560d..c501ae0e 100644
--- a/runner/json_tests_data/normal-run/metadata.txt
+++ b/runner/json_tests_data/normal-run/metadata.txt
@@ -1,4 +1,4 @@
-abort_on_error : 0
+abort_mask : 0
 name : normal-run
 dry_run : 0
 sync : 0
diff --git a/runner/json_tests_data/piglit-style-dmesg/metadata.txt b/runner/json_tests_data/piglit-style-dmesg/metadata.txt
index 7f1372c1..3eca78cd 100644
--- a/runner/json_tests_data/piglit-style-dmesg/metadata.txt
+++ b/runner/json_tests_data/piglit-style-dmesg/metadata.txt
@@ -1,4 +1,4 @@
-abort_on_error : 0
+abort_mask : 0
 name : normal-run
 dry_run : 0
 sync : 0
diff --git a/runner/json_tests_data/warnings-with-dmesg-warns/metadata.txt b/runner/json_tests_data/warnings-with-dmesg-warns/metadata.txt
index 1316560d..c501ae0e 100644
--- a/runner/json_tests_data/warnings-with-dmesg-warns/metadata.txt
+++ b/runner/json_tests_data/warnings-with-dmesg-warns/metadata.txt
@@ -1,4 +1,4 @@
-abort_on_error : 0
+abort_mask : 0
 name : normal-run
 dry_run : 0
 sync : 0
diff --git a/runner/json_tests_data/warnings/metadata.txt b/runner/json_tests_data/warnings/metadata.txt
index 1316560d..c501ae0e 100644
--- a/runner/json_tests_data/warnings/metadata.txt
+++ b/runner/json_tests_data/warnings/metadata.txt
@@ -1,4 +1,4 @@
-abort_on_error : 0
+abort_mask : 0
 name : normal-run
 dry_run : 0
 sync : 0
diff --git a/runner/resultgen.c b/runner/resultgen.c
index a62e400e..2863ab3b 100644
--- a/runner/resultgen.c
+++ b/runner/resultgen.c
@@ -649,6 +649,7 @@ static bool fill_from_dmesg(int fd,
 		append_line(&dmesg, &dmesglen, formatted);
 		free(formatted);
 	}
+	free(line);
 
 	if (current_test != NULL) {
 		add_dmesg(current_test, dmesg, dmesglen, warnings, warningslen);
@@ -717,6 +718,15 @@ static void add_subtest(struct subtests *subtests, char *subtest)
 	subtests->names[subtests->size - 1] = subtest;
 }
 
+static void free_subtests(struct subtests *subtests)
+{
+	size_t i;
+
+	for (i = 0; i < subtests->size; i++)
+		free(subtests->names[i]);
+	free(subtests->names);
+}
+
 static void fill_from_journal(int fd,
 			      struct job_list_entry *entry,
 			      struct subtests *subtests,
@@ -902,7 +912,7 @@ static void add_result_to_totals(struct json_object *totals,
 	json_object_object_add(totals, result, json_object_new_int(old + 1));
 }
 
-static void add_to_totals(char *binary,
+static void add_to_totals(const char *binary,
 			  struct subtests *subtests,
 			  struct results *results)
 {
@@ -950,6 +960,7 @@ static bool parse_test_directory(int dirfd,
 {
 	int fds[_F_LAST];
 	struct subtests subtests = {};
+	bool status = true;
 
 	if (!open_output_files(dirfd, fds, false)) {
 		fprintf(stderr, "Error opening output files\n");
@@ -966,15 +977,18 @@ static bool parse_test_directory(int dirfd,
 	    !fill_from_output(fds[_F_ERR], entry->binary, "err", &subtests, results->tests) ||
 	    !fill_from_dmesg(fds[_F_DMESG], settings, entry->binary, &subtests, results->tests)) {
 		fprintf(stderr, "Error parsing output files\n");
-		return false;
+		status = false;
+		goto parse_output_end;
 	}
 
 	override_results(entry->binary, &subtests, results->tests);
 	add_to_totals(entry->binary, &subtests, results);
 
+ parse_output_end:
 	close_outputs(fds);
+	free_subtests(&subtests);
 
-	return true;
+	return status;
 }
 
 static void create_result_root_nodes(struct json_object *root,
@@ -1077,6 +1091,34 @@ struct json_object *generate_results_json(int dirfd)
 		close(testdirfd);
 	}
 
+	if ((fd = openat(dirfd, "aborted.txt", O_RDONLY)) >= 0) {
+		char buf[4096];
+		char piglit_name[] = "igt@pseudoresult@aborted";
+		struct subtests abortsub = {};
+		struct json_object *aborttest = get_or_create_json_object(results.tests, piglit_name);
+		ssize_t s;
+
+		add_subtest(&abortsub, strdup("aborted"));
+
+		s = read(fd, buf, sizeof(buf));
+
+		json_object_object_add(aborttest, "out",
+				       json_object_new_string_len(buf, s));
+		json_object_object_add(aborttest, "err",
+				       json_object_new_string(""));
+		json_object_object_add(aborttest, "dmesg",
+				       json_object_new_string(""));
+		json_object_object_add(aborttest, "result",
+				       json_object_new_string("fail"));
+
+		add_to_totals("pseudoresult", &abortsub, &results);
+
+		free_subtests(&abortsub);
+	}
+
+	free_settings(&settings);
+	free_job_list(&job_list);
+
 	return obj;
 }
 
diff --git a/runner/runner_json_tests.c b/runner/runner_json_tests.c
index 758700d4..75d6237f 100644
--- a/runner/runner_json_tests.c
+++ b/runner/runner_json_tests.c
@@ -154,6 +154,8 @@ static const char *dirnames[] = {
 	"piglit-style-dmesg",
 	"incomplete-before-any-subtests",
 	"dmesg-results",
+	"aborted-on-boot",
+	"aborted-after-a-test",
 };
 
 igt_main
diff --git a/runner/runner_tests.c b/runner/runner_tests.c
index d07e6f37..6213b8e7 100644
--- a/runner/runner_tests.c
+++ b/runner/runner_tests.c
@@ -142,7 +142,7 @@ static void assert_settings_equal(struct settings *one, struct settings *two)
 	 * Regex lists are not serialized, and thus won't be compared
 	 * here.
 	 */
-	igt_assert_eq(one->abort_on_error, two->abort_on_error);
+	igt_assert_eq(one->abort_mask, two->abort_mask);
 	igt_assert_eqstr(one->test_list, two->test_list);
 	igt_assert_eqstr(one->name, two->name);
 	igt_assert_eq(one->dry_run, two->dry_run);
@@ -208,7 +208,7 @@ igt_main
 
 		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
 
-		igt_assert(!settings.abort_on_error);
+		igt_assert_eq(settings.abort_mask, 0);
 		igt_assert(!settings.test_list);
 		igt_assert_eqstr(settings.name, "path-to-results");
 		igt_assert(!settings.dry_run);
@@ -323,7 +323,7 @@ igt_main
 		setenv("IGT_TEST_ROOT", testdatadir, 1);
 		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
 
-		igt_assert(!settings.abort_on_error);
+		igt_assert_eq(settings.abort_mask, 0);
 		igt_assert(!settings.test_list);
 		igt_assert_eqstr(settings.name, "path-to-results");
 		igt_assert(!settings.dry_run);
@@ -348,7 +348,7 @@ igt_main
 	igt_subtest("parse-all-settings") {
 		const char *argv[] = { "runner",
 				       "-n", "foo",
-				       "--abort-on-monitored-error",
+				       "--abort-on-monitored-error=taint,lockdep",
 				       "--test-list", "path-to-test-list",
 				       "--ignore-missing",
 				       "--dry-run",
@@ -370,7 +370,7 @@ igt_main
 
 		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
 
-		igt_assert(settings.abort_on_error);
+		igt_assert_eq(settings.abort_mask, ABORT_TAINT | ABORT_LOCKDEP);
 		igt_assert(strstr(settings.test_list, "path-to-test-list") != NULL);
 		igt_assert_eqstr(settings.name, "foo");
 		igt_assert(settings.dry_run);
@@ -428,6 +428,45 @@ igt_main
 		igt_assert_eq(settings.log_level, LOG_LEVEL_VERBOSE);
 	}
 
+	igt_subtest("abort-conditions") {
+		const char *argv[] = { "runner",
+				       "--abort-on-monitored-error=taint",
+				       "test-root-dir",
+				       "results-path",
+		};
+
+		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
+		igt_assert_eq(settings.abort_mask, ABORT_TAINT);
+
+		argv[1] = "--abort-on-monitored-error=lockdep";
+		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
+		igt_assert_eq(settings.abort_mask, ABORT_LOCKDEP);
+
+		argv[1] = "--abort-on-monitored-error=taint";
+		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
+		igt_assert_eq(settings.abort_mask, ABORT_TAINT);
+
+		argv[1] = "--abort-on-monitored-error=lockdep,taint";
+		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
+		igt_assert_eq(settings.abort_mask, ABORT_TAINT | ABORT_LOCKDEP);
+
+		argv[1] = "--abort-on-monitored-error=taint,lockdep";
+		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
+		igt_assert_eq(settings.abort_mask, ABORT_TAINT | ABORT_LOCKDEP);
+
+		argv[1] = "--abort-on-monitored-error=all";
+		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
+		igt_assert_eq(settings.abort_mask, ABORT_ALL);
+
+		argv[1] = "--abort-on-monitored-error=";
+		igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
+		igt_assert_eq(settings.abort_mask, 0);
+
+		argv[1] = "--abort-on-monitored-error=doesnotexist";
+		igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, &settings));
+
+	}
+
 	igt_subtest("parse-clears-old-data") {
 		const char *argv[] = { "runner",
 				       "-n", "foo",
diff --git a/runner/settings.c b/runner/settings.c
index e2401455..e64244e6 100644
--- a/runner/settings.c
+++ b/runner/settings.c
@@ -41,6 +41,16 @@ static struct {
 	{ 0, 0 },
 };
 
+static struct {
+	int value;
+	const char *name;
+} abort_conditions[] = {
+	{ ABORT_TAINT, "taint" },
+	{ ABORT_LOCKDEP, "lockdep" },
+	{ ABORT_ALL, "all" },
+	{ 0, 0 },
+};
+
 static bool set_log_level(struct settings* settings, const char *level)
 {
 	typeof(*log_levels) *it;
@@ -55,6 +65,56 @@ static bool set_log_level(struct settings* settings, const char *level)
 	return false;
 }
 
+static bool set_abort_condition(struct settings* settings, const char *cond)
+{
+	typeof(*abort_conditions) *it;
+
+	if (!cond) {
+		settings->abort_mask = ABORT_ALL;
+		return true;
+	}
+
+	if (strlen(cond) == 0) {
+		settings->abort_mask = 0;
+		return true;
+	}
+
+	for (it = abort_conditions; it->name; it++) {
+		if (!strcmp(cond, it->name)) {
+			settings->abort_mask |= it->value;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static bool parse_abort_conditions(struct settings *settings, const char *optarg)
+{
+	char *dup, *origdup, *p;
+	if (!optarg)
+		return set_abort_condition(settings, NULL);
+
+	origdup = dup = strdup(optarg);
+	while (dup) {
+		if ((p = strchr(dup, ',')) != NULL) {
+			*p = '\0';
+			p++;
+		}
+
+		if (!set_abort_condition(settings, dup)) {
+			free(origdup);
+			return false;
+		}
+
+		dup = p;
+	}
+
+	free(origdup);
+
+	return true;
+}
+
 static const char *usage_str =
 	"usage: runner [options] [test_root] results-path\n\n"
 	"Options:\n"
@@ -67,9 +127,15 @@ static const char *usage_str =
 	"                        Run only matching tests (can be used more than once)\n"
 	"  -x <regex>, --exclude-tests <regex>\n"
 	"                        Exclude matching tests (can be used more than once)\n"
-	"  --abort-on-monitored-error\n"
+	"  --abort-on-monitored-error[=list]\n"
 	"                        Abort execution when a fatal condition is detected.\n"
-	"                        <TODO>\n"
+	"                        A comma-separated list of conditions to check can be\n"
+	"                        given. If not given, all conditions are checked. An\n"
+	"                        empty string as a condition disables aborting\n"
+	"                        Possible conditions:\n"
+	"                         lockdep - abort when kernel lockdep has been angered.\n"
+	"                         taint   - abort when kernel becomes fatally tainted.\n"
+	"                         all     - abort for all of the above.\n"
 	"  -s, --sync            Sync results to disk after every test\n"
 	"  -l {quiet,verbose,dummy}, --log-level {quiet,verbose,dummy}\n"
 	"                        Set the logger verbosity level\n"
@@ -193,7 +259,7 @@ bool parse_options(int argc, char **argv,
 		{"dry-run", no_argument, NULL, OPT_DRY_RUN},
 		{"include-tests", required_argument, NULL, OPT_INCLUDE},
 		{"exclude-tests", required_argument, NULL, OPT_EXCLUDE},
-		{"abort-on-monitored-error", no_argument, NULL, OPT_ABORT_ON_ERROR},
+		{"abort-on-monitored-error", optional_argument, NULL, OPT_ABORT_ON_ERROR},
 		{"sync", no_argument, NULL, OPT_SYNC},
 		{"log-level", required_argument, NULL, OPT_LOG_LEVEL},
 		{"test-list", required_argument, NULL, OPT_TEST_LIST},
@@ -231,7 +297,8 @@ bool parse_options(int argc, char **argv,
 				goto error;
 			break;
 		case OPT_ABORT_ON_ERROR:
-			settings->abort_on_error = true;
+			if (!parse_abort_conditions(settings, optarg))
+				goto error;
 			break;
 		case OPT_SYNC:
 			settings->sync = true;
@@ -444,7 +511,7 @@ bool serialize_settings(struct settings *settings)
 		return false;
 	}
 
-	SERIALIZE_LINE(f, settings, abort_on_error, "%d");
+	SERIALIZE_LINE(f, settings, abort_mask, "%d");
 	if (settings->test_list)
 		SERIALIZE_LINE(f, settings, test_list, "%s");
 	if (settings->name)
@@ -501,7 +568,7 @@ bool read_settings(struct settings *settings, int dirfd)
 
 	while (fscanf(f, "%ms : %ms", &name, &val) == 2) {
 		int numval = atoi(val);
-		PARSE_LINE(settings, name, val, abort_on_error, numval);
+		PARSE_LINE(settings, name, val, abort_mask, numval);
 		PARSE_LINE(settings, name, val, test_list, val ? strdup(val) : NULL);
 		PARSE_LINE(settings, name, val, name, val ? strdup(val) : NULL);
 		PARSE_LINE(settings, name, val, dry_run, numval);
diff --git a/runner/settings.h b/runner/settings.h
index b489abc5..267d72cf 100644
--- a/runner/settings.h
+++ b/runner/settings.h
@@ -12,6 +12,12 @@ enum {
 	LOG_LEVEL_VERBOSE = 1,
 };
 
+#define ABORT_TAINT   (1 << 0)
+#define ABORT_LOCKDEP (1 << 1)
+#define ABORT_ALL     (ABORT_TAINT | ABORT_LOCKDEP)
+
+_Static_assert(ABORT_ALL == (ABORT_TAINT | ABORT_LOCKDEP), "ABORT_ALL must be all conditions bitwise or'd");
+
 struct regex_list {
 	char **regex_strings;
 	regex_t** regexes;
@@ -19,7 +25,7 @@ struct regex_list {
 };
 
 struct settings {
-	bool abort_on_error;
+	int abort_mask;
 	char *test_list;
 	char *name;
 	bool dry_run;
-- 
2.18.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error
  2018-11-06 14:26 [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error Petri Latvala
@ 2018-11-06 14:45 ` Martin Peres
  2018-11-06 16:53 ` Chris Wilson
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Martin Peres @ 2018-11-06 14:45 UTC (permalink / raw)
  To: Petri Latvala, igt-dev; +Cc: Tomi Sarvela

On 06/11/2018 16:26, Petri Latvala wrote:
> [...]
> diff --git a/runner/resultgen.c b/runner/resultgen.c
> index a62e400e..2863ab3b 100644
> --- a/runner/resultgen.c
> +++ b/runner/resultgen.c
> @@ -649,6 +649,7 @@ static bool fill_from_dmesg(int fd,
>  		append_line(&dmesg, &dmesglen, formatted);
>  		free(formatted);
>  	}
> +	free(line);
>  
>  	if (current_test != NULL) {
>  		add_dmesg(current_test, dmesg, dmesglen, warnings, warningslen);
> @@ -717,6 +718,15 @@ static void add_subtest(struct subtests *subtests, char *subtest)
>  	subtests->names[subtests->size - 1] = subtest;
>  }
>  
> +static void free_subtests(struct subtests *subtests)
> +{
> +	size_t i;
> +
> +	for (i = 0; i < subtests->size; i++)
> +		free(subtests->names[i]);
> +	free(subtests->names);
> +}
> +
>  static void fill_from_journal(int fd,
>  			      struct job_list_entry *entry,
>  			      struct subtests *subtests,
> @@ -902,7 +912,7 @@ static void add_result_to_totals(struct json_object *totals,
>  	json_object_object_add(totals, result, json_object_new_int(old + 1));
>  }
>  
> -static void add_to_totals(char *binary,
> +static void add_to_totals(const char *binary,
>  			  struct subtests *subtests,
>  			  struct results *results)
>  {
> @@ -950,6 +960,7 @@ static bool parse_test_directory(int dirfd,
>  {
>  	int fds[_F_LAST];
>  	struct subtests subtests = {};
> +	bool status = true;
>  
>  	if (!open_output_files(dirfd, fds, false)) {
>  		fprintf(stderr, "Error opening output files\n");
> @@ -966,15 +977,18 @@ static bool parse_test_directory(int dirfd,
>  	    !fill_from_output(fds[_F_ERR], entry->binary, "err", &subtests, results->tests) ||
>  	    !fill_from_dmesg(fds[_F_DMESG], settings, entry->binary, &subtests, results->tests)) {
>  		fprintf(stderr, "Error parsing output files\n");
> -		return false;
> +		status = false;
> +		goto parse_output_end;
>  	}
>  
>  	override_results(entry->binary, &subtests, results->tests);
>  	add_to_totals(entry->binary, &subtests, results);
>  
> + parse_output_end:
>  	close_outputs(fds);
> +	free_subtests(&subtests);
>  
> -	return true;
> +	return status;
>  }
>  
>  static void create_result_root_nodes(struct json_object *root,
> @@ -1077,6 +1091,34 @@ struct json_object *generate_results_json(int dirfd)
>  		close(testdirfd);
>  	}
>  
> +	if ((fd = openat(dirfd, "aborted.txt", O_RDONLY)) >= 0) {
> +		char buf[4096];
> +		char piglit_name[] = "igt@pseudoresult@aborted";

I think naming it igt@runner@aborted would make it a little easier to
know which "test" generated this output.

Also, bonus point for printing the full list of tests that led to the
abort (this could be done in a separate patch).

With the first one changed, this is:

Acked-by: Martin Peres <martin.peres@linux.intel.com>

> +		struct subtests abortsub = {};
> +		struct json_object *aborttest = get_or_create_json_object(results.tests, piglit_name);
> +		ssize_t s;
> +
> +		add_subtest(&abortsub, strdup("aborted"));
> +
> +		s = read(fd, buf, sizeof(buf));
> +
> +		json_object_object_add(aborttest, "out",
> +				       json_object_new_string_len(buf, s));
> +		json_object_object_add(aborttest, "err",
> +				       json_object_new_string(""));
> +		json_object_object_add(aborttest, "dmesg",
> +				       json_object_new_string(""));
> +		json_object_object_add(aborttest, "result",
> +				       json_object_new_string("fail"));
> +
> +		add_to_totals("pseudoresult", &abortsub, &results);
> +
> +		free_subtests(&abortsub);
> +	}
> +
> +	free_settings(&settings);
> +	free_job_list(&job_list);
> +
>  	return obj;
>  }
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error
  2018-11-06 14:26 [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error Petri Latvala
  2018-11-06 14:45 ` Martin Peres
@ 2018-11-06 16:53 ` Chris Wilson
  2018-11-08 12:39   ` Petri Latvala
  2018-11-07 18:37 ` [igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,v4,1/1] " Patchwork
  2018-11-08  6:09 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  3 siblings, 1 reply; 6+ messages in thread
From: Chris Wilson @ 2018-11-06 16:53 UTC (permalink / raw)
  To: Petri Latvala, igt-dev; +Cc: Tomi Sarvela, Petri Latvala, Martin Peres

Quoting Petri Latvala (2018-11-06 14:26:29)
> Deviating a bit from the piglit command line flag, igt_runner takes an
> optional comma-separated list as an argument to
> --abort-on-monitored-error for the list of conditions to abort
> on. Without a list all possible conditions will be checked.
> 
> Two conditions implemented:
>  - "taint" checks the kernel taint level for TAINT_PAGE, TAINT_DIE and
>  TAINT_OOPS
>  - "lockdep" checks the kernel lockdep status
> 
> Checking is done after every test binary execution, and if an abort
> condition is met, the reason is printed to stderr (unless log level is
> quiet) and the runner doesn't execute any further tests. Aborting
> between subtests (when running in --multiple-mode) is not done.
> 
> A TODO item for the future is having aborting appear in the test
> results.
> 
> v2:
>  - Remember to fclose
>  - Taints are unsigned long (Chris)
>  - Use getline instead of fgets (Chris)
> v3:
>  - Fix brainfart with lockdep
> v4:
>  - Rebase
>  - Refactor the abort condition checking to pass down strings
>  - Present the abort result in results.json as a pseudo test result
>  - Unit tests for the pseudo result
> 
> Signed-off-by: Petri Latvala <petri.latvala@intel.com>
> Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
> Cc: Tomi Sarvela <tomi.p.sarvela@intel.com>
> Cc: Martin Peres <martin.peres@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  runner/executor.c                             | 189 ++++++++++++++++--
>  runner/executor.h                             |   1 +
>  .../aborted-after-a-test/0/dmesg.txt          |   5 +
>  .../aborted-after-a-test/0/err.txt            |   2 +
>  .../aborted-after-a-test/0/journal.txt        |   2 +
>  .../aborted-after-a-test/0/out.txt            |   3 +
>  .../aborted-after-a-test/README.txt           |   1 +
>  .../aborted-after-a-test/aborted.txt          |   3 +
>  .../aborted-after-a-test/endtime.txt          |   1 +
>  .../aborted-after-a-test/joblist.txt          |   5 +
>  .../aborted-after-a-test/metadata.txt         |  12 ++
>  .../aborted-after-a-test/reference.json       |  90 +++++++++
>  .../aborted-after-a-test/starttime.txt        |   1 +
>  .../aborted-after-a-test/uname.txt            |   1 +
>  .../aborted-on-boot/README.txt                |   1 +
>  .../aborted-on-boot/aborted.txt               |   3 +
>  .../aborted-on-boot/endtime.txt               |   1 +
>  .../aborted-on-boot/joblist.txt               |   5 +
>  .../aborted-on-boot/metadata.txt              |  12 ++
>  .../aborted-on-boot/reference.json            |  59 ++++++
>  .../aborted-on-boot/starttime.txt             |   1 +
>  .../json_tests_data/aborted-on-boot/uname.txt |   1 +
>  .../dmesg-results/metadata.txt                |   2 +-
>  .../metadata.txt                              |   2 +-
>  .../json_tests_data/normal-run/metadata.txt   |   2 +-
>  .../piglit-style-dmesg/metadata.txt           |   2 +-
>  .../warnings-with-dmesg-warns/metadata.txt    |   2 +-
>  runner/json_tests_data/warnings/metadata.txt  |   2 +-
>  runner/resultgen.c                            |  48 ++++-
>  runner/runner_json_tests.c                    |   2 +
>  runner/runner_tests.c                         |  49 ++++-
>  runner/settings.c                             |  79 +++++++-
>  runner/settings.h                             |   8 +-
>  33 files changed, 556 insertions(+), 41 deletions(-)
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/0/dmesg.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/0/err.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/0/journal.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/0/out.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/README.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/aborted.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/endtime.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/joblist.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/metadata.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/reference.json
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/starttime.txt
>  create mode 100644 runner/json_tests_data/aborted-after-a-test/uname.txt
>  create mode 100644 runner/json_tests_data/aborted-on-boot/README.txt
>  create mode 100644 runner/json_tests_data/aborted-on-boot/aborted.txt
>  create mode 100644 runner/json_tests_data/aborted-on-boot/endtime.txt
>  create mode 100644 runner/json_tests_data/aborted-on-boot/joblist.txt
>  create mode 100644 runner/json_tests_data/aborted-on-boot/metadata.txt
>  create mode 100644 runner/json_tests_data/aborted-on-boot/reference.json
>  create mode 100644 runner/json_tests_data/aborted-on-boot/starttime.txt
>  create mode 100644 runner/json_tests_data/aborted-on-boot/uname.txt
> 
> diff --git a/runner/executor.c b/runner/executor.c
> index 007b72ce..ed444a9a 100644
> --- a/runner/executor.c
> +++ b/runner/executor.c
> @@ -108,6 +108,90 @@ static void ping_watchdogs(void)
>         }
>  }
>  
> +static char *handle_lockdep(void)
> +{
> +       FILE *f = fopen("/proc/lockdep_stats", "r");
> +       const char *debug_locks_line = " debug_locks:";
> +       char *buf = NULL;
> +       size_t bufsize = 0;
> +       int val;
> +       char *reason = NULL;
> +
> +       if (!f)
> +               return reason;
> +
> +       while (getline(&buf, &bufsize, f) > 0) {
> +               if (!strncmp(buf, debug_locks_line, strlen(debug_locks_line))) {
> +                       char *p = buf + strlen(debug_locks_line);
> +                       if (sscanf(p, "%d", &val) == 1 &&
> +                           val != 1)
> +                               asprintf(&reason, "Lockdep triggered\n");
> +
> +                       break;
> +               }
> +       }
> +
> +       fclose(f);
> +       free(buf);
> +       return reason;
> +}
> +
> +static char *handle_taint(void)
> +{
> +       FILE *f = fopen("/proc/sys/kernel/tainted", "r");
> +       int s;
> +       unsigned long taint;
> +       unsigned long bad_taints =
> +               0x20  | /* TAINT_PAGE */
> +               0x80  | /* TAINT_DIE */
> +               0x200; /* TAINT_OOPS */

Please be considerate to the reader.
> +
> +       if (!f)
> +               return NULL;
> +
> +       s = fscanf(f, "%lu", &taint);
> +       fclose(f);
> +
> +       if (s != 1)
> +               return NULL;
> +
> +       if (taint & bad_taints) {
> +               char *reason;
> +
> +               asprintf(&reason, "Kernel tainted (0x%lx)\n", taint);
> +
> +               return reason;
> +       }
> +
> +       return NULL;

const unsigned long bad_taints =
	0x20  | /* TAINT_PAGE */
	0x80  | /* TAINT_DIE */
	0x200; /* TAINT_OOPS */
unsigned long taints = 0;
char *reason = NULL;
FILE *f;

f = fopen();
if (f) {
	fscanf(f, "%lu", &taints);
	fclose(f);
}

if (taints & bad_taints)
	asprintf(&reason,
		 "Kernel tainted (%#lx -- %lx)\n",
		 taints, taints & bad_taints);

return reason;

> +}
> +
> +static struct {

static const struct {

> +       int condition;
> +       char *(*handler)(void);
> +} abort_handlers[] = {
> +       { ABORT_LOCKDEP, handle_lockdep },
> +       { ABORT_TAINT, handle_taint },
> +       { 0, 0 },
> +};
> +
> +static char *need_to_abort(struct settings* settings)

const struct settings *settings

> +{
> +       typeof(*abort_handlers) *it;
> +       char *ret = NULL;
> +
> +       for (it = abort_handlers; it->condition; it++) {
> +               if (settings->abort_mask & it->condition &&
> +                   (ret = it->handler()) != NULL) {
> +                       if (settings->log_level >= LOG_LEVEL_NORMAL)
> +                               fprintf(stderr, "%s", ret);
> +               }
> +               break;

break? looks incongruous.

for (it = abort_handlers; it->condition; it++) {
	char *abort;

	if (!(settings->abort_mask & it->condition))
		continue;

	abort = it->handler();
	if (!abort)
		continue;

	if (settings->log_level >= ...)
		fprintf(stderr, "%s\n", abort);

	return abort;
}

I'd recommend not including the '\n' in the abort string itself but
append in the callers -- it should make it easier to include in any
error message.
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,v4,1/1] runner: Implement --abort-on-monitored-error
  2018-11-06 14:26 [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error Petri Latvala
  2018-11-06 14:45 ` Martin Peres
  2018-11-06 16:53 ` Chris Wilson
@ 2018-11-07 18:37 ` Patchwork
  2018-11-08  6:09 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  3 siblings, 0 replies; 6+ messages in thread
From: Patchwork @ 2018-11-07 18:37 UTC (permalink / raw)
  To: Petri Latvala; +Cc: igt-dev

== Series Details ==

Series: series starting with [i-g-t,v4,1/1] runner: Implement --abort-on-monitored-error
URL   : https://patchwork.freedesktop.org/series/52095/
State : success

== Summary ==

= CI Bug Log - changes from IGT_4712 -> IGTPW_2041 =

== Summary - SUCCESS ==

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/52095/revisions/1/mbox/

== Known issues ==

  Here are the changes found in IGTPW_2041 that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    igt@drv_module_reload@basic-reload:
      fi-blb-e6850:       PASS -> INCOMPLETE (fdo#107718)

    igt@drv_module_reload@basic-reload-inject:
      fi-byt-clapper:     PASS -> WARN (fdo#108688)

    igt@pm_rpm@module-reload:
      fi-byt-clapper:     PASS -> FAIL (fdo#108675)

    
    ==== Possible fixes ====

    igt@kms_pipe_crc_basic@read-crc-pipe-b:
      fi-byt-clapper:     FAIL (fdo#107362) -> PASS

    
    ==== Warnings ====

    igt@kms_chamelium@common-hpd-after-suspend:
      fi-skl-6700k2:      FAIL (fdo#103841) -> WARN (fdo#108680)

    
  fdo#103841 https://bugs.freedesktop.org/show_bug.cgi?id=103841
  fdo#107362 https://bugs.freedesktop.org/show_bug.cgi?id=107362
  fdo#107718 https://bugs.freedesktop.org/show_bug.cgi?id=107718
  fdo#108675 https://bugs.freedesktop.org/show_bug.cgi?id=108675
  fdo#108680 https://bugs.freedesktop.org/show_bug.cgi?id=108680
  fdo#108688 https://bugs.freedesktop.org/show_bug.cgi?id=108688


== Participating hosts (52 -> 46) ==

  Additional (1): fi-cnl-u 
  Missing    (7): fi-kbl-soraka fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-icl-u 


== Build changes ==

    * IGT: IGT_4712 -> IGTPW_2041

  CI_DRM_5097: c20dfc4f015dfd41246beb7d72338aa50543a5ef @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2041: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2041/
  IGT_4712: a3ede1b535ac8137f6949c468edd7054453d5dae @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2041/issues.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [igt-dev] ✓ Fi.CI.IGT: success for series starting with [i-g-t,v4,1/1] runner: Implement --abort-on-monitored-error
  2018-11-06 14:26 [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error Petri Latvala
                   ` (2 preceding siblings ...)
  2018-11-07 18:37 ` [igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,v4,1/1] " Patchwork
@ 2018-11-08  6:09 ` Patchwork
  3 siblings, 0 replies; 6+ messages in thread
From: Patchwork @ 2018-11-08  6:09 UTC (permalink / raw)
  To: Petri Latvala; +Cc: igt-dev

== Series Details ==

Series: series starting with [i-g-t,v4,1/1] runner: Implement --abort-on-monitored-error
URL   : https://patchwork.freedesktop.org/series/52095/
State : success

== Summary ==

= CI Bug Log - changes from IGT_4712_full -> IGTPW_2041_full =

== Summary - WARNING ==

  Minor unknown changes coming with IGTPW_2041_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_2041_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/52095/revisions/1/mbox/

== Possible new issues ==

  Here are the unknown changes that may have been introduced in IGTPW_2041_full:

  === IGT changes ===

    ==== Warnings ====

    igt@pm_rc6_residency@rc6-accuracy:
      shard-snb:          PASS -> SKIP

    
== Known issues ==

  Here are the changes found in IGTPW_2041_full that come from known issues:

  === IGT changes ===

    ==== Issues hit ====

    igt@gem_ppgtt@blt-vs-render-ctxn:
      shard-kbl:          PASS -> INCOMPLETE (fdo#106023, fdo#106887, fdo#103665) +1

    igt@kms_available_modes_crc@available_mode_test_crc:
      shard-apl:          PASS -> FAIL (fdo#106641)

    igt@kms_color@pipe-c-degamma:
      shard-apl:          PASS -> FAIL (fdo#104782)

    igt@kms_cursor_crc@cursor-128x42-sliding:
      shard-apl:          PASS -> FAIL (fdo#103232) +1

    igt@kms_cursor_crc@cursor-256x85-random:
      shard-glk:          PASS -> FAIL (fdo#103232) +1

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-blt:
      shard-kbl:          PASS -> FAIL (fdo#103167)

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-fullscreen:
      shard-apl:          PASS -> FAIL (fdo#103167) +1

    igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-cpu:
      shard-glk:          PASS -> FAIL (fdo#103167) +2

    igt@kms_plane_multiple@atomic-pipe-c-tiling-y:
      shard-glk:          PASS -> FAIL (fdo#103166)

    
    ==== Possible fixes ====

    igt@gem_exec_bad_domains@cpu-domain:
      shard-apl:          DMESG-WARN (fdo#103558, fdo#105602) -> PASS +5

    igt@gem_pwrite_pread@snooped-copy-correctness:
      shard-snb:          INCOMPLETE (fdo#105411) -> PASS

    igt@kms_color@pipe-b-legacy-gamma:
      shard-apl:          FAIL (fdo#104782) -> PASS

    igt@kms_cursor_crc@cursor-128x128-random:
      shard-apl:          FAIL (fdo#103232) -> PASS +6

    igt@kms_cursor_crc@cursor-256x256-suspend:
      shard-apl:          FAIL (fdo#103191, fdo#103232) -> PASS

    igt@kms_cursor_crc@cursor-64x64-dpms:
      shard-kbl:          FAIL (fdo#103232) -> PASS +3

    igt@kms_cursor_crc@cursor-64x64-random:
      shard-glk:          FAIL (fdo#103232) -> PASS +4

    igt@kms_cursor_legacy@cursor-vs-flip-toggle:
      shard-hsw:          FAIL (fdo#103355) -> PASS

    igt@kms_cursor_legacy@cursora-vs-flipa-toggle:
      shard-glk:          DMESG-WARN (fdo#106538, fdo#105763) -> PASS

    igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-move:
      shard-apl:          FAIL (fdo#103167) -> PASS

    igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-pwrite:
      shard-glk:          FAIL (fdo#103167) -> PASS +2

    igt@kms_plane_multiple@atomic-pipe-a-tiling-x:
      shard-apl:          FAIL (fdo#103166) -> PASS +4

    igt@kms_plane_multiple@atomic-pipe-b-tiling-y:
      shard-glk:          FAIL (fdo#103166) -> PASS +2
      shard-kbl:          FAIL (fdo#103166) -> PASS

    igt@kms_setmode@basic:
      shard-kbl:          FAIL (fdo#99912) -> PASS

    igt@kms_setmode@basic-clone-single-crtc:
      shard-snb:          DMESG-WARN (fdo#107469) -> PASS +2

    
  fdo#103166 https://bugs.freedesktop.org/show_bug.cgi?id=103166
  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#103191 https://bugs.freedesktop.org/show_bug.cgi?id=103191
  fdo#103232 https://bugs.freedesktop.org/show_bug.cgi?id=103232
  fdo#103355 https://bugs.freedesktop.org/show_bug.cgi?id=103355
  fdo#103558 https://bugs.freedesktop.org/show_bug.cgi?id=103558
  fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665
  fdo#104782 https://bugs.freedesktop.org/show_bug.cgi?id=104782
  fdo#105411 https://bugs.freedesktop.org/show_bug.cgi?id=105411
  fdo#105602 https://bugs.freedesktop.org/show_bug.cgi?id=105602
  fdo#105763 https://bugs.freedesktop.org/show_bug.cgi?id=105763
  fdo#106023 https://bugs.freedesktop.org/show_bug.cgi?id=106023
  fdo#106538 https://bugs.freedesktop.org/show_bug.cgi?id=106538
  fdo#106641 https://bugs.freedesktop.org/show_bug.cgi?id=106641
  fdo#106887 https://bugs.freedesktop.org/show_bug.cgi?id=106887
  fdo#107469 https://bugs.freedesktop.org/show_bug.cgi?id=107469
  fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912


== Participating hosts (6 -> 5) ==

  Missing    (1): shard-skl 


== Build changes ==

    * IGT: IGT_4712 -> IGTPW_2041

  CI_DRM_5097: c20dfc4f015dfd41246beb7d72338aa50543a5ef @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2041: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2041/
  IGT_4712: a3ede1b535ac8137f6949c468edd7054453d5dae @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2041/shards.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error
  2018-11-06 16:53 ` Chris Wilson
@ 2018-11-08 12:39   ` Petri Latvala
  0 siblings, 0 replies; 6+ messages in thread
From: Petri Latvala @ 2018-11-08 12:39 UTC (permalink / raw)
  To: Chris Wilson; +Cc: igt-dev, Tomi Sarvela, Martin Peres

On Tue, Nov 06, 2018 at 04:53:02PM +0000, Chris Wilson wrote:
> Quoting Petri Latvala (2018-11-06 14:26:29)
> > Deviating a bit from the piglit command line flag, igt_runner takes an
> > optional comma-separated list as an argument to
> > --abort-on-monitored-error for the list of conditions to abort
> > on. Without a list all possible conditions will be checked.
> > 
> > Two conditions implemented:
> >  - "taint" checks the kernel taint level for TAINT_PAGE, TAINT_DIE and
> >  TAINT_OOPS
> >  - "lockdep" checks the kernel lockdep status
> > 
> > Checking is done after every test binary execution, and if an abort
> > condition is met, the reason is printed to stderr (unless log level is
> > quiet) and the runner doesn't execute any further tests. Aborting
> > between subtests (when running in --multiple-mode) is not done.
> > 
> > A TODO item for the future is having aborting appear in the test
> > results.
> > 
> > v2:
> >  - Remember to fclose
> >  - Taints are unsigned long (Chris)
> >  - Use getline instead of fgets (Chris)
> > v3:
> >  - Fix brainfart with lockdep
> > v4:
> >  - Rebase
> >  - Refactor the abort condition checking to pass down strings
> >  - Present the abort result in results.json as a pseudo test result
> >  - Unit tests for the pseudo result
> > 
> > Signed-off-by: Petri Latvala <petri.latvala@intel.com>
> > Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
> > Cc: Tomi Sarvela <tomi.p.sarvela@intel.com>
> > Cc: Martin Peres <martin.peres@linux.intel.com>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > ---
> >  runner/executor.c                             | 189 ++++++++++++++++--
> >  runner/executor.h                             |   1 +
> >  .../aborted-after-a-test/0/dmesg.txt          |   5 +
> >  .../aborted-after-a-test/0/err.txt            |   2 +
> >  .../aborted-after-a-test/0/journal.txt        |   2 +
> >  .../aborted-after-a-test/0/out.txt            |   3 +
> >  .../aborted-after-a-test/README.txt           |   1 +
> >  .../aborted-after-a-test/aborted.txt          |   3 +
> >  .../aborted-after-a-test/endtime.txt          |   1 +
> >  .../aborted-after-a-test/joblist.txt          |   5 +
> >  .../aborted-after-a-test/metadata.txt         |  12 ++
> >  .../aborted-after-a-test/reference.json       |  90 +++++++++
> >  .../aborted-after-a-test/starttime.txt        |   1 +
> >  .../aborted-after-a-test/uname.txt            |   1 +
> >  .../aborted-on-boot/README.txt                |   1 +
> >  .../aborted-on-boot/aborted.txt               |   3 +
> >  .../aborted-on-boot/endtime.txt               |   1 +
> >  .../aborted-on-boot/joblist.txt               |   5 +
> >  .../aborted-on-boot/metadata.txt              |  12 ++
> >  .../aborted-on-boot/reference.json            |  59 ++++++
> >  .../aborted-on-boot/starttime.txt             |   1 +
> >  .../json_tests_data/aborted-on-boot/uname.txt |   1 +
> >  .../dmesg-results/metadata.txt                |   2 +-
> >  .../metadata.txt                              |   2 +-
> >  .../json_tests_data/normal-run/metadata.txt   |   2 +-
> >  .../piglit-style-dmesg/metadata.txt           |   2 +-
> >  .../warnings-with-dmesg-warns/metadata.txt    |   2 +-
> >  runner/json_tests_data/warnings/metadata.txt  |   2 +-
> >  runner/resultgen.c                            |  48 ++++-
> >  runner/runner_json_tests.c                    |   2 +
> >  runner/runner_tests.c                         |  49 ++++-
> >  runner/settings.c                             |  79 +++++++-
> >  runner/settings.h                             |   8 +-
> >  33 files changed, 556 insertions(+), 41 deletions(-)
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/0/dmesg.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/0/err.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/0/journal.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/0/out.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/README.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/aborted.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/endtime.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/joblist.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/metadata.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/reference.json
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/starttime.txt
> >  create mode 100644 runner/json_tests_data/aborted-after-a-test/uname.txt
> >  create mode 100644 runner/json_tests_data/aborted-on-boot/README.txt
> >  create mode 100644 runner/json_tests_data/aborted-on-boot/aborted.txt
> >  create mode 100644 runner/json_tests_data/aborted-on-boot/endtime.txt
> >  create mode 100644 runner/json_tests_data/aborted-on-boot/joblist.txt
> >  create mode 100644 runner/json_tests_data/aborted-on-boot/metadata.txt
> >  create mode 100644 runner/json_tests_data/aborted-on-boot/reference.json
> >  create mode 100644 runner/json_tests_data/aborted-on-boot/starttime.txt
> >  create mode 100644 runner/json_tests_data/aborted-on-boot/uname.txt
> > 
> > diff --git a/runner/executor.c b/runner/executor.c
> > index 007b72ce..ed444a9a 100644
> > --- a/runner/executor.c
> > +++ b/runner/executor.c
> > @@ -108,6 +108,90 @@ static void ping_watchdogs(void)
> >         }
> >  }
> >  
> > +static char *handle_lockdep(void)
> > +{
> > +       FILE *f = fopen("/proc/lockdep_stats", "r");
> > +       const char *debug_locks_line = " debug_locks:";
> > +       char *buf = NULL;
> > +       size_t bufsize = 0;
> > +       int val;
> > +       char *reason = NULL;
> > +
> > +       if (!f)
> > +               return reason;
> > +
> > +       while (getline(&buf, &bufsize, f) > 0) {
> > +               if (!strncmp(buf, debug_locks_line, strlen(debug_locks_line))) {
> > +                       char *p = buf + strlen(debug_locks_line);
> > +                       if (sscanf(p, "%d", &val) == 1 &&
> > +                           val != 1)
> > +                               asprintf(&reason, "Lockdep triggered\n");
> > +
> > +                       break;
> > +               }
> > +       }
> > +
> > +       fclose(f);
> > +       free(buf);
> > +       return reason;
> > +}
> > +
> > +static char *handle_taint(void)
> > +{
> > +       FILE *f = fopen("/proc/sys/kernel/tainted", "r");
> > +       int s;
> > +       unsigned long taint;
> > +       unsigned long bad_taints =
> > +               0x20  | /* TAINT_PAGE */
> > +               0x80  | /* TAINT_DIE */
> > +               0x200; /* TAINT_OOPS */
> 
> Please be considerate to the reader.
> > +
> > +       if (!f)
> > +               return NULL;
> > +
> > +       s = fscanf(f, "%lu", &taint);
> > +       fclose(f);
> > +
> > +       if (s != 1)
> > +               return NULL;
> > +
> > +       if (taint & bad_taints) {
> > +               char *reason;
> > +
> > +               asprintf(&reason, "Kernel tainted (0x%lx)\n", taint);
> > +
> > +               return reason;
> > +       }
> > +
> > +       return NULL;
> 
> const unsigned long bad_taints =
> 	0x20  | /* TAINT_PAGE */
> 	0x80  | /* TAINT_DIE */
> 	0x200; /* TAINT_OOPS */
> unsigned long taints = 0;
> char *reason = NULL;
> FILE *f;
> 
> f = fopen();
> if (f) {
> 	fscanf(f, "%lu", &taints);
> 	fclose(f);
> }
> 
> if (taints & bad_taints)
> 	asprintf(&reason,
> 		 "Kernel tainted (%#lx -- %lx)\n",
> 		 taints, taints & bad_taints);
> 
> return reason;
> 
> > +}
> > +
> > +static struct {
> 
> static const struct {
> 
> > +       int condition;
> > +       char *(*handler)(void);
> > +} abort_handlers[] = {
> > +       { ABORT_LOCKDEP, handle_lockdep },
> > +       { ABORT_TAINT, handle_taint },
> > +       { 0, 0 },
> > +};
> > +
> > +static char *need_to_abort(struct settings* settings)
> 
> const struct settings *settings
> 
> > +{
> > +       typeof(*abort_handlers) *it;
> > +       char *ret = NULL;
> > +
> > +       for (it = abort_handlers; it->condition; it++) {
> > +               if (settings->abort_mask & it->condition &&
> > +                   (ret = it->handler()) != NULL) {
> > +                       if (settings->log_level >= LOG_LEVEL_NORMAL)
> > +                               fprintf(stderr, "%s", ret);
> > +               }
> > +               break;
> 
> break? looks incongruous.


I don't know how that slipped there, it was supposed to be in the if...


-- 
Petri Latvala
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-11-08 12:39 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-06 14:26 [igt-dev] [PATCH i-g-t v4 1/1] runner: Implement --abort-on-monitored-error Petri Latvala
2018-11-06 14:45 ` Martin Peres
2018-11-06 16:53 ` Chris Wilson
2018-11-08 12:39   ` Petri Latvala
2018-11-07 18:37 ` [igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,v4,1/1] " Patchwork
2018-11-08  6:09 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.