[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