[Intel-gfx] [PATCH] lib/igt_core.c: disable lowmemorykiller during tests
Daniel Vetter
daniel at ffwll.ch
Wed Oct 1 14:45:06 CEST 2014
On Wed, Oct 01, 2014 at 01:25:20PM +0100, tim.gore at intel.com wrote:
> From: Tim Gore <tim.gore at intel.com>
>
> 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 at intel.com>
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
More information about the Intel-gfx
mailing list