diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-02-22 18:22:38 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-02-23 07:52:02 +0000 |
commit | b0b6c043c997732559a971a788c24a5a73812df4 (patch) | |
tree | dd3b9fd15cee1d5dbf30b73eadbcadb2d8b7ac4f /src/sna/kgem.c | |
parent | bfef9916124973b5e08f9b32eb1fcfb400ee4e8b (diff) |
sna: Cleanup caches if execbuf fails
One of the failure modes for execbuf is running out of memory - often
this is reported as a false ENOSPC (thanks shmemfs!). Because of this,
we should try to resubmit after we purge our caches.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/kgem.c')
-rw-r--r-- | src/sna/kgem.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 8e469607..7fa9334b 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -3008,6 +3008,25 @@ static void dump_fence_regs(struct kgem *kgem) } #endif +static int do_execbuf(struct kgem *kgem, struct drm_i915_gem_execbuffer2 *execbuf) +{ + int ret; + +retry: + ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf); + if (ret == 0) + return 0; + + (void)__kgem_throttle_retire(kgem, 0); + if (kgem_expire_cache(kgem)) + goto retry; + + if (kgem_cleanup_cache(kgem)) + goto retry; + + return ret; +} + void _kgem_submit(struct kgem *kgem) { struct kgem_request *rq; @@ -3073,7 +3092,7 @@ void _kgem_submit(struct kgem *kgem) if (kgem_batch_write(kgem, handle, size) == 0) { struct drm_i915_gem_execbuffer2 execbuf; - int ret, retry = 3; + int ret; memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffers_ptr = (uintptr_t)kgem->exec; @@ -3091,15 +3110,7 @@ void _kgem_submit(struct kgem *kgem) } } - ret = do_ioctl(kgem->fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - while (ret == -EBUSY && retry--) { - __kgem_throttle(kgem); - ret = do_ioctl(kgem->fd, - DRM_IOCTL_I915_GEM_EXECBUFFER2, - &execbuf); - } + ret = do_execbuf(kgem, &execbuf); if (DEBUG_SYNC && ret == 0) { struct drm_i915_gem_set_domain set_domain; |