[igt-dev] [PATCH i-g-t] tests/gem_evict_everything fix for mlocked-* subtests
Chris Wilson
chris at chris-wilson.co.uk
Thu Jun 7 14:07:31 UTC 2018
Quoting Ewelina Musial (2018-06-07 14:21:41)
> Add check to avoid locking biggest mem size than is available.
> Trying to allocate size returned by intel_get_avail_ram_mb()
> triggers OOM killer. It looks like available RAM is not fully free
> so my idea is to decrease this size of 1024MB and before allocating
> increase mem size in loop till will be maximally big.
>
> Also, changed surface_count. Few thousands of iterations is not
> necessary and is taking a lot of time. This change should cover
> previous functionality.
>
> Using __igt_waitchildren() instead of igt_waitchildren() avoids
> failing test if OOM killer stops process run by igt_fork() (OOM killer
> is expected).
>
> __igt_waitchildren() is implemented by Chris in other patch so this will
> be failing now. I will update this patch after merging his code :)
>
> Signed-off-by: Ewelina Musial <ewelina.musial at intel.com>
> ---
> tests/eviction_common.c | 51 ++++++++++++++++++++++++++++++++++++++------
> tests/gem_evict_everything.c | 6 +++---
> 2 files changed, 48 insertions(+), 9 deletions(-)
>
> diff --git a/tests/eviction_common.c b/tests/eviction_common.c
> index 300eb03d..7ae48654 100644
> --- a/tests/eviction_common.c
> +++ b/tests/eviction_common.c
> @@ -134,14 +134,20 @@ static void mlocked_evictions(int fd, struct igt_eviction_test_ops *ops,
> uint64_t surface_count)
> {
> unsigned int *can_mlock;
> - uint64_t sz, pin;
> + uint64_t sz, pin, *update_pin = 0;
> + bool flag = false;
>
> intel_require_memory(surface_count, surface_size, CHECK_RAM);
>
> sz = surface_size*surface_count;
> - pin = intel_get_avail_ram_mb();
> + pin = intel_get_avail_ram_mb() - 1024;
> pin *= 1024 * 1024;
> igt_require(pin > sz);
> +
> + update_pin = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
> + igt_assert(update_pin != MAP_FAILED);
> + *update_pin = pin;
> +
> pin -= sz;
>
> igt_debug("Pinning [%'lld, %'lld] MiB\n",
> @@ -151,16 +157,48 @@ static void mlocked_evictions(int fd, struct igt_eviction_test_ops *ops,
> can_mlock = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
> igt_assert(can_mlock != MAP_FAILED);
>
> + igt_fork(child, 1)
> + {
> + void *lock;
> + uint64_t update_step = (5 << 22);
5 * 4 MiB
Any particular reason? Just curious.
We try to follow the kernel coding style (K&R braces, just the right
amount of brackets, and start multiline comments with
/*
* Hello World!
*/)
> +
> + do {
> + lock = malloc(*update_pin + update_step);
> + if (lock && !mlock(lock, *update_pin + update_step)) {
> + free(lock);
> + *update_pin += update_step;
> + } else {
> + /* If mlock() fails this fork will be killed
> + * and flag state will not be changed but to
> + * better understanding it is good to put it
> + * here.
> + */
> + flag = true;
> + }
> + } while (!flag);
> + }
flag is only used inside this loop; a separate process no less, so the
value set above doesn't reach here anyway.
You can kill flag entirely and make that a break; inside a
do { } while (1);
> +
> + __igt_waitchildren();
> + igt_require(*update_pin);
> +
> igt_fork(child, 1) {
> void *locked;
>
> - locked = malloc(pin + sz);
> - if (locked != NULL && !mlock(locked, pin + sz))
> + locked = malloc(*update_pin);
> + if (locked && !mlock(locked, *update_pin)) {
> *can_mlock = 1;
> + if (*update_pin >= pin + sz)
> + pin = *update_pin - sz;
> + else
> + exit(1);
> + }
> }
> +
> igt_waitchildren();
I typically place the igt_waitchildren() tight against the igt_fork()
loop unless the code is very, very busy.
Overall, looks to be the same approach as the discovery mechanism I
used. So it should work so long as the kernel's oomkiller doesn't kill
everything on the system other than our child.
-Chris
More information about the igt-dev
mailing list