On Wed, Oct 01, 2014 at 01:25:20PM +0100, tim.gore@xxxxxxxxx wrote: > From: Tim Gore <tim.gore@xxxxxxxxx> > > Several IGT tests cycle through a lot of GEM memory and > when running these tests on Android they tend to get > killed by the lowmemorykiller. The lowmemorykiller really > is not usefull in this context and is just preventing the > test from doing its job. This commit adds a function to > disable the lowmemorykiller by writing "9999" to its > oom adj parameter, which means it will never "select" > any process to kill. The normal linux oom killer is still > there to protect the kernel. > The low memory killer is disabled during the common > init function and then re-enabled by the exit handler. > To make this work for single tests the exit handler is now > installed in the common init function also so that it is > invoked for all tests. > This is just a hack to get round the fact that the i915 > driver uses the concept of purgeable memory which is not > understood by the lowmemorykiller. If this ever gets > fixed then this patch can be removed. > > Signed-off-by: Tim Gore <tim.gore@xxxxxxxxx> I applied a bit of polish and merge your patch, thanks. -Daniel > --- > lib/igt_core.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 81 insertions(+), 1 deletion(-) > > diff --git a/lib/igt_core.c b/lib/igt_core.c > index 0269462..f07ca3b 100644 > --- a/lib/igt_core.c > +++ b/lib/igt_core.c > @@ -292,6 +292,9 @@ void __igt_fixture_end(void) > bool igt_exit_called; > static void check_igt_exit(int sig) > { > + /* make sure the lowmemorykiller gets re-enabled if required */ > + low_mem_killer_disable(false); > + > /* When not killed by a signal check that igt_exit() has been properly > * called. */ > assert(sig != 0 || igt_exit_called); > @@ -326,6 +329,77 @@ 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. > + * This seems to be due to some incompatibility between the kswapd free memory > + * targets and the way the lowmemorykiller assesses free memory. > + * 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. > + * > + * In future, if we can get the lowmemorykiller to play nicely then we can > + * remove this hack. > + */ > +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 +408,11 @@ 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); > + > + /* disable the low memory killer (not oom) if present */ > + /* It can kill some tests that cycle through a lot of memory */ > + low_mem_killer_disable(true); > } > > static int common_init(int argc, char **argv, > @@ -484,6 +563,8 @@ out: > oom_adjust_for_doom(); > } > > + /* install exit handler, to ensure we clean up */ > + igt_install_exit_handler(check_igt_exit); > return ret; > } > > @@ -518,7 +599,6 @@ int igt_subtest_init_parse_opts(int argc, char **argv, > test_with_subtests = true; > ret = common_init(argc, argv, extra_short_opts, extra_long_opts, > help_str, extra_opt_handler); > - igt_install_exit_handler(check_igt_exit); > > return ret; > } > -- > 2.1.1 > -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx