@@ -326,6 +326,72 @@ static void print_usage(const char *help_str, bool output_on_stderr)
fprintf(f, "%s\n", help_str);
}
+
+/* Some of the IGT tests put quite a lot of pressure on memory and when
+ * running on Android they are sometimes killed by the Android low memory killer.
+ * The low memory killer really isn't usefull in this context and has no
+ * interaction with the gpu driver that we are testing, so the following
+ * function is used to disable it by modifying one of its module parameters.
+ * We still have the normal linux oom killer to protect the kernel.
+ * Apparently it is also possible for the lowmemorykiller to get included
+ * in some linux distributions; so rather than check for Android we directly
+ * check for the existence of the module parameter we want to adjust.
+ */
+void low_mem_killer_disable(bool disable)
+{
+ static const char* adj_fname="/sys/module/lowmemorykiller/parameters/adj";
+ static const char no_lowmem_killer[] = "9999";
+ int fd;
+ struct stat buf;
+ /* The following must persist across invocations */
+ static char prev_adj_scores[256];
+ static int adj_scores_len = 0;
+ static bool is_disabled = false;
+
+ /* check to see if there is something to do */
+ if (!(disable ^ is_disabled))
+ return;
+
+ /* capture the permissions bits for the lowmemkiller adj pseudo-file.
+ Bail out if the stat fails; it probably means that there is no
+ lowmemorykiller, but in any case we're doomed. */
+ if (stat (adj_fname, &buf))
+ {
+ igt_assert(errno == ENOENT);
+ return;
+ }
+ /* make sure the file can be read/written - by default it is write-only */
+ chmod (adj_fname, S_IRUSR | S_IWUSR);
+
+ if (disable)
+ {
+ /* read the current oom adj parameters for lowmemorykiller */
+ fd = open(adj_fname, O_RDWR);
+ igt_assert(fd != -1);
+ adj_scores_len = read(fd, (void*)prev_adj_scores, 255);
+ igt_assert(adj_scores_len > 0);
+
+ /* writing 9999 to this module parameter effectively diables the
+ * low memory killer. This is not a real file, so we dont need to
+ * seek to the start or truncate it */
+ write(fd, no_lowmem_killer, sizeof(no_lowmem_killer));
+ close(fd);
+ is_disabled = true;
+ }
+ else
+ {
+ /* just re-enstate the original settings */
+ fd = open(adj_fname, O_WRONLY);
+ igt_assert(fd != -1);
+ write(fd, prev_adj_scores, adj_scores_len);
+ close(fd);
+ is_disabled = false;
+ }
+
+ /* re-enstate the file permissions */
+ chmod (adj_fname, buf.st_mode);
+}
+
static void oom_adjust_for_doom(void)
{
int fd;
@@ -334,6 +400,7 @@ static void oom_adjust_for_doom(void)
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));
+ close(fd);
}
static int common_init(int argc, char **argv,
@@ -848,6 +915,9 @@ void igt_exit(void)
{
igt_exit_called = true;
+ /* re-enstate the low mem killer in case we disabled it */
+ low_mem_killer_disable(false);
+
if (run_single_subtest && !run_single_subtest_found) {
igt_warn("Unknown subtest: %s\n", run_single_subtest);
exit(IGT_EXIT_INVALID);