[Intel-gfx] [PATCH] [drm/i915] Retry execbuffer pinning after clearing the GTT

Eric Anholt eric at anholt.net
Wed Nov 26 01:51:29 CET 2008


On Fri, 2008-11-21 at 01:00 -0800, Keith Packard wrote:
> If we fail to pin all of the buffers in an execbuffer request, go through
> and clear the GTT and try again to see if its just a matter of fragmentation
> 
> Signed-off-by: Keith Packard <keithp at keithp.com>
> ---
>  drivers/gpu/drm/i915/i915_gem.c |   51 ++++++++++++++++++++++++++++++++-------
>  1 files changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 7fd1b26..3e54e94 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1089,6 +1089,19 @@ i915_gem_evict_something(struct drm_device *dev)
>  }
>  
>  static int
> +i915_gem_evict_everything(struct drm_device *dev)
> +{
> +	int ret;
> +
> +	for (;;) {
> +		ret = i915_gem_evict_something(dev);
> +		if (ret != -ENOMEM)

I think this test should be != 0.  We want to stop if there's nothing
left to evict (-ENOMEM) and also if we get interrupted (-ERESTARTSYS).
Is there any error we want to actually ignore?

> +			break;
> +	}
> +	return ret;
> +}
> +
> +static int
>  i915_gem_object_get_page_list(struct drm_gem_object *obj)
>  {
>  	struct drm_i915_gem_object *obj_priv = obj->driver_private;
> @@ -1896,6 +1909,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
>  	int ret, i, pinned = 0;
>  	uint64_t exec_offset;
>  	uint32_t seqno, flush_domains;
> +	int pin_tries;
>  
>  #if WATCH_EXEC
>  	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
> @@ -1957,17 +1971,36 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
>  	}
>  
>  	/* Pin and relocate */
> -	for (i = 0; i < args->buffer_count; i++) {
> -		object_list[i]->pending_read_domains = 0;
> -		object_list[i]->pending_write_domain = 0;
> -		ret = i915_gem_object_pin_and_relocate(object_list[i],
> -						       file_priv,
> -						       &exec_list[i]);
> -		if (ret) {
> -			DRM_ERROR("object bind and relocate failed %d\n", ret);
> +	for (pin_tries = 0; ; pin_tries++) {
> +		ret = 0;
> +		for (i = 0; i < args->buffer_count; i++) {
> +			object_list[i]->pending_read_domains = 0;
> +			object_list[i]->pending_write_domain = 0;
> +			ret = i915_gem_object_pin_and_relocate(object_list[i],
> +							       file_priv,
> +							       &exec_list[i]);
> +			if (ret)
> +				break;
> +			pinned = i + 1;
> +		}
> +		/* success */
> +		if (ret == 0)
> +			break;
> +
> +		/* error other than GTT full, or we've already tried again */
> +		if (ret != -ENOMEM || pin_tries >= 1) {
> +			DRM_ERROR("Failed to pin buffers %d\n", ret);
>  			goto err;
>  		}

ret could be -EINTR, since pin_and_relocate could have waited on space
to evict someone, in which case we should quietly return to userland.

> -		pinned = i + 1;
> +
> +		/* unpin all of our buffers */
> +		for (i = 0; i < pinned; i++)
> +			i915_gem_object_unpin(object_list[i]);
> +
> +		/* evict everyone we can from the aperture */
> +		ret = i915_gem_evict_everything(dev);
> +		if (ret)
> +			goto err;
>  	}


-- 
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/20081125/f4447ea7/attachment.sig>


More information about the Intel-gfx mailing list