[igt-dev] [PATCH i-g-t v3 1/2] lib: Extract mlock probing

Ewelina Musial ewelina.musial at intel.com
Tue Jun 12 13:28:38 UTC 2018


On Tue, Jun 12, 2018 at 02:41:28PM +0200, Michał Winiarski wrote:
> We already have the routine we need in drv_suspend. Let's move it to lib
> and use it in the mlocking tests. We can also make it a bit faster if we
> tweak the initial step and initial amount.
> (I think it's safe to assume assume that we should be able to lock 3/4

s/assume assume/assume

Reviewed-by: Ewelina Musial <ewelina.musial at intel.com>
- Ewelina

> of RAM, this cuts the probe time on my 32G SKL - from ~530s to ~180s)
> 
> v2: Use available mem, amend step, also lock outside of fork,
>     early exit if the assumption is wrong (Chris)
>     Update the function name in doc (Ewelina)
> v3: Total for pin, available for initial lock (Chris)
> 
> Signed-off-by: Michał Winiarski <michal.winiarski at intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Ewelina Musial <ewelina.musial at intel.com>
> Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
>  lib/igt_aux.h       |  1 +
>  lib/intel_os.c      | 57 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/drv_suspend.c | 44 +++++++++-------------------------
>  3 files changed, 69 insertions(+), 33 deletions(-)
> 
> diff --git a/lib/igt_aux.h b/lib/igt_aux.h
> index 0eb96e44..9a962881 100644
> --- a/lib/igt_aux.h
> +++ b/lib/igt_aux.h
> @@ -209,6 +209,7 @@ void intel_purge_vm_caches(int fd);
>  uint64_t intel_get_avail_ram_mb(void);
>  uint64_t intel_get_total_ram_mb(void);
>  uint64_t intel_get_total_swap_mb(void);
> +size_t intel_get_total_pinnable_mem(void);
>  
>  int __intel_check_memory(uint64_t count, uint64_t size, unsigned mode,
>  			 uint64_t *out_required, uint64_t *out_total);
> diff --git a/lib/intel_os.c b/lib/intel_os.c
> index f7ad05ac..e82173b3 100644
> --- a/lib/intel_os.c
> +++ b/lib/intel_os.c
> @@ -183,6 +183,63 @@ intel_get_total_swap_mb(void)
>  	return retval / (1024*1024);
>  }
>  
> +/**
> + * intel_get_total_pinnable_mem:
> + *
> + * Compute the amount of memory that we're able to safely lock.
> + * Note that in order to achieve this, we're attempting to repeatedly lock more
> + * and more memory, which is a time consuming process.
> + *
> + * Returns: Amount of memory that can be safely pinned, in bytes.
> + */
> +size_t
> +intel_get_total_pinnable_mem(void)
> +{
> +	uint64_t *can_mlock, pin, avail;
> +	size_t ret;
> +
> +	pin = (intel_get_total_ram_mb() + 1) << 20;
> +	avail = (intel_get_avail_ram_mb() + 1) << 20;
> +
> +	can_mlock = mmap(NULL, pin, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
> +	igt_require(can_mlock != MAP_FAILED);
> +
> +	/*
> +	 * We can reasonably assume that we should be able to lock at
> +	 * least 3/4 of available RAM
> +	 */
> +	*can_mlock = (avail >> 1) + (avail >> 2);
> +	if (mlock(can_mlock, *can_mlock)) {
> +		*can_mlock = 0;
> +		goto out;
> +	}
> +
> +	for (uint64_t inc = 1024 << 20; inc >= 4 << 10; inc >>= 2) {
> +		igt_debug("Testing mlock %'"PRIu64" B (%'"PRIu64" MiB)\n",
> +			  *can_mlock, *can_mlock >> 20);
> +
> +		igt_fork(child, 1) {
> +			for (uint64_t bytes = *can_mlock;
> +			     bytes <= pin;
> +			     bytes += inc) {
> +				if (mlock(can_mlock, bytes))
> +					break;
> +
> +				*can_mlock = bytes;
> +				__sync_synchronize();
> +			}
> +		}
> +		__igt_waitchildren();
> +		igt_assert(!mlock(can_mlock, *can_mlock));
> +	}
> +
> +out:
> +	ret = *can_mlock;
> +	munmap(can_mlock, pin);
> +
> +	return ret;
> +}
> +
>  static uint64_t vfs_file_max(void)
>  {
>  	static long long unsigned max;
> diff --git a/tests/drv_suspend.c b/tests/drv_suspend.c
> index 9a9ff200..b4212dca 100644
> --- a/tests/drv_suspend.c
> +++ b/tests/drv_suspend.c
> @@ -163,52 +163,30 @@ test_sysfs_reader(bool hibernate)
>  static void
>  test_shrink(int fd, unsigned int mode)
>  {
> -	uint64_t *can_mlock, pin;
> +	void *mem;
> +	size_t size;
>  
>  	gem_quiescent_gpu(fd);
>  	intel_purge_vm_caches(fd);
>  
> -	pin = (intel_get_total_ram_mb() + 1) << 20;
> -
> -	igt_debug("Total memory %'"PRIu64" B (%'"PRIu64" MiB)\n",
> -		  pin, pin >> 20);
> -	can_mlock = mmap(NULL, pin, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
> -	igt_require(can_mlock != MAP_FAILED);
> -
> -	/* Lock all the system memory, forcing the driver into swap and OOM */
> -	for (uint64_t inc = 64 << 20; inc >= 4 << 10; inc >>= 1) {
> -		igt_debug("Testing+ %'"PRIu64" B (%'"PRIu64" MiB)\n",
> -			  *can_mlock, *can_mlock >> 20);
> -
> -		igt_fork(child, 1) {
> -			for (uint64_t bytes = *can_mlock;
> -			     bytes <= pin;
> -			     bytes += inc) {
> -				if (mlock(can_mlock, bytes))
> -					break;
> -
> -				*can_mlock = bytes;
> -				__sync_synchronize();
> -			}
> -		}
> -		__igt_waitchildren();
> -	}
> +	size = intel_get_total_pinnable_mem();
> +	igt_require(size > 64 << 20);
> +	size -= 64 << 20;
>  
> -	intel_purge_vm_caches(fd);
> +	mem = mmap(NULL, size, PROT_READ, MAP_SHARED | MAP_ANON, -1, 0);
>  
> -	igt_require(*can_mlock > 64 << 20);
> -	*can_mlock -= 64 << 20;
> +	intel_purge_vm_caches(fd);
>  
>  	igt_debug("Locking %'"PRIu64" B (%'"PRIu64" MiB)\n",
> -		  *can_mlock, *can_mlock >> 20);
> -	igt_assert(!mlock(can_mlock, *can_mlock));
> +		  size, size >> 20);
> +	igt_assert(!mlock(mem, size));
>  	igt_info("Locked %'"PRIu64" B (%'"PRIu64" MiB)\n",
> -		 *can_mlock, *can_mlock >> 20);
> +		 size, size >> 20);
>  
>  	intel_purge_vm_caches(fd);
>  	igt_system_suspend_autoresume(mode, SUSPEND_TEST_NONE);
>  
> -	munmap(can_mlock, pin);
> +	munmap(mem, size);
>  }
>  
>  static void
> -- 
> 2.17.1
> 


More information about the igt-dev mailing list