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 <kei...@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-...@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
-- 
Eric Anholt
e...@anholt.net                         eric.anh...@intel.com


Attachment: signature.asc
Description: This is a digitally signed message part

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to