[Intel-gfx] [PATCH] [intel] Dump out memory usage information when the kernel fails to pin

Eric Anholt eric at anholt.net
Sun Dec 14 01:42:37 CET 2008


On Fri, 2008-12-12 at 10:42 -0800, Keith Packard wrote:
> The execbuffer ioctl returns ENOMEM when it fails to pin all of the buffers
> in the GTT. This is usually caused by the DRM client attempting to use too
> much memory in a single request. Dumping out the requested and available
> memory values should help point out failures in the DRM code to catch over
> commitments of this form.

looks good to me.

> Signed-off-by: Keith Packard <keithp at keithp.com>
> ---
>  libdrm/intel/intel_bufmgr_gem.c |   70 ++++++++++++++++++++++++++++++--------
>  1 files changed, 55 insertions(+), 15 deletions(-)
> 
> diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c
> index be41474..3958f43 100644
> --- a/libdrm/intel/intel_bufmgr_gem.c
> +++ b/libdrm/intel/intel_bufmgr_gem.c
> @@ -164,6 +164,12 @@ struct _drm_intel_bo_gem {
>  
>  static void drm_intel_gem_bo_reference_locked(drm_intel_bo *bo);
>  
> +static unsigned int
> +drm_intel_gem_estimate_batch_space(drm_intel_bo **bo_array, int count);
> +
> +static unsigned int
> +drm_intel_gem_compute_batch_space(drm_intel_bo **bo_array, int count);
> +
>  static int
>  logbase2(int n)
>  {
> @@ -913,6 +919,14 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
>  	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER, &execbuf);
>      } while (ret != 0 && errno == EAGAIN);
>  
> +    if (ret != 0 && errno == ENOMEM) {
> +	fprintf(stderr, "Execbuffer fails to pin. Estimate: %u. Actual: %u. Available: %u\n",
> +		drm_intel_gem_estimate_batch_space(bufmgr_gem->exec_bos,
> +						   bufmgr_gem->exec_count),
> +		drm_intel_gem_compute_batch_space(bufmgr_gem->exec_bos,
> +						  bufmgr_gem->exec_count),
> +		bufmgr_gem->gtt_size);
> +    }
>      drm_intel_update_buffer_offsets (bufmgr_gem);
>  
>      if (bufmgr_gem->bufmgr.debug)
> @@ -1100,6 +1114,43 @@ drm_intel_gem_bo_clear_aperture_space_flag(drm_intel_bo *bo)
>  }
>  
>  /**
> + * Return a conservative estimate for the amount of aperture required
> + * for a collection of buffers. This may double-count some buffers.
> + */
> +static unsigned int
> +drm_intel_gem_estimate_batch_space(drm_intel_bo **bo_array, int count)
> +{
> +    int i;
> +    unsigned int total = 0;
> +
> +    for (i = 0; i < count; i++) {
> +	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo_array[i];
> +	if (bo_gem != NULL)
> +		total += bo_gem->reloc_tree_size;
> +    }
> +    return total;
> +}
> +
> +/**
> + * Return the amount of aperture needed for a collection of buffers.
> + * This avoids double counting any buffers, at the cost of looking
> + * at every buffer in the set.
> + */
> +static unsigned int
> +drm_intel_gem_compute_batch_space(drm_intel_bo **bo_array, int count)
> +{
> +    int i;
> +    unsigned int total = 0;
> +
> +    for (i = 0; i < count; i++)
> +	total += drm_intel_gem_bo_get_aperture_space(bo_array[i]);
> +
> +    for (i = 0; i < count; i++)
> +	drm_intel_gem_bo_clear_aperture_space_flag(bo_array[i]);
> +    return total;
> +}
> +
> +/**
>   * Return -1 if the batchbuffer should be flushed before attempting to
>   * emit rendering referencing the buffers pointed to by bo_array.
>   *
> @@ -1121,24 +1172,13 @@ drm_intel_gem_check_aperture_space(drm_intel_bo **bo_array, int count)
>      drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo_array[0]->bufmgr;
>      unsigned int total = 0;
>      unsigned int threshold = bufmgr_gem->gtt_size * 3 / 4;
> -    int i;
>  
> -    for (i = 0; i < count; i++) {
> -	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo_array[i];
> -	if (bo_gem != NULL)
> -		total += bo_gem->reloc_tree_size;
> -    }
> +    total = drm_intel_gem_estimate_batch_space(bo_array, count);
> +    
> +    if (total > threshold)
> +	total = drm_intel_gem_compute_batch_space(bo_array, count);
>  
>      if (total > threshold) {
> -	total = 0;
> -	for (i = 0; i < count; i++)
> -	    total += drm_intel_gem_bo_get_aperture_space(bo_array[i]);
> -
> -	for (i = 0; i < count; i++)
> -	    drm_intel_gem_bo_clear_aperture_space_flag(bo_array[i]);
> -    }
> -
> -    if (total > bufmgr_gem->gtt_size * 3 / 4) {
>  	DBG("check_space: overflowed available aperture, %dkb vs %dkb\n",
>  	    total / 1024, (int)bufmgr_gem->gtt_size / 1024);
>  	return -1;
> -- 
> 1.5.6.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
-- 
Eric Anholt
eric at anholt.net                         eric.anholt at intel.com


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20081213/253fc662/attachment.sig>


More information about the Intel-gfx mailing list