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 <[EMAIL PROTECTED]> > --- > 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 [EMAIL PROTECTED] [EMAIL PROTECTED]
signature.asc
Description: This is a digitally signed message part
------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/
-- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel