aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-11-21 02:30:27 -0500
committerDave Airlie <airlied@redhat.com>2008-12-03 20:22:06 -0500
commitac94a962b24a88ea5d00f4697550d9982f300751 (patch)
tree9dacd94c107aafc3eb33241f1aef0c8fa2dec923 /drivers/gpu
parent646f0f6e43bf6628b1f0f8ca6c0227ce72e8ef3c (diff)
drm/i915: Retry execbuffer pinning after clearing the GTT
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@keithp.com> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c171a2d93bb6..174c0c3ba0b0 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1088,6 +1088,19 @@ i915_gem_evict_something(struct drm_device *dev)
1088} 1088}
1089 1089
1090static int 1090static int
1091i915_gem_evict_everything(struct drm_device *dev)
1092{
1093 int ret;
1094
1095 for (;;) {
1096 ret = i915_gem_evict_something(dev);
1097 if (ret != 0)
1098 break;
1099 }
1100 return ret;
1101}
1102
1103static int
1091i915_gem_object_get_page_list(struct drm_gem_object *obj) 1104i915_gem_object_get_page_list(struct drm_gem_object *obj)
1092{ 1105{
1093 struct drm_i915_gem_object *obj_priv = obj->driver_private; 1106 struct drm_i915_gem_object *obj_priv = obj->driver_private;
@@ -1173,7 +1186,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
1173 1186
1174 ret = i915_gem_evict_something(dev); 1187 ret = i915_gem_evict_something(dev);
1175 if (ret != 0) { 1188 if (ret != 0) {
1176 DRM_ERROR("Failed to evict a buffer %d\n", ret); 1189 if (ret != -ERESTARTSYS)
1190 DRM_ERROR("Failed to evict a buffer %d\n", ret);
1177 return ret; 1191 return ret;
1178 } 1192 }
1179 goto search_free; 1193 goto search_free;
@@ -1922,6 +1936,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
1922 int ret, i, pinned = 0; 1936 int ret, i, pinned = 0;
1923 uint64_t exec_offset; 1937 uint64_t exec_offset;
1924 uint32_t seqno, flush_domains; 1938 uint32_t seqno, flush_domains;
1939 int pin_tries;
1925 1940
1926#if WATCH_EXEC 1941#if WATCH_EXEC
1927 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", 1942 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
@@ -1970,7 +1985,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
1970 return -EBUSY; 1985 return -EBUSY;
1971 } 1986 }
1972 1987
1973 /* Look up object handles and perform the relocations */ 1988 /* Look up object handles */
1974 for (i = 0; i < args->buffer_count; i++) { 1989 for (i = 0; i < args->buffer_count; i++) {
1975 object_list[i] = drm_gem_object_lookup(dev, file_priv, 1990 object_list[i] = drm_gem_object_lookup(dev, file_priv,
1976 exec_list[i].handle); 1991 exec_list[i].handle);
@@ -1980,17 +1995,39 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
1980 ret = -EBADF; 1995 ret = -EBADF;
1981 goto err; 1996 goto err;
1982 } 1997 }
1998 }
1983 1999
1984 object_list[i]->pending_read_domains = 0; 2000 /* Pin and relocate */
1985 object_list[i]->pending_write_domain = 0; 2001 for (pin_tries = 0; ; pin_tries++) {
1986 ret = i915_gem_object_pin_and_relocate(object_list[i], 2002 ret = 0;
1987 file_priv, 2003 for (i = 0; i < args->buffer_count; i++) {
1988 &exec_list[i]); 2004 object_list[i]->pending_read_domains = 0;
1989 if (ret) { 2005 object_list[i]->pending_write_domain = 0;
1990 DRM_ERROR("object bind and relocate failed %d\n", ret); 2006 ret = i915_gem_object_pin_and_relocate(object_list[i],
2007 file_priv,
2008 &exec_list[i]);
2009 if (ret)
2010 break;
2011 pinned = i + 1;
2012 }
2013 /* success */
2014 if (ret == 0)
2015 break;
2016
2017 /* error other than GTT full, or we've already tried again */
2018 if (ret != -ENOMEM || pin_tries >= 1) {
2019 DRM_ERROR("Failed to pin buffers %d\n", ret);
1991 goto err; 2020 goto err;
1992 } 2021 }
1993 pinned = i + 1; 2022
2023 /* unpin all of our buffers */
2024 for (i = 0; i < pinned; i++)
2025 i915_gem_object_unpin(object_list[i]);
2026
2027 /* evict everyone we can from the aperture */
2028 ret = i915_gem_evict_everything(dev);
2029 if (ret)
2030 goto err;
1994 } 2031 }
1995 2032
1996 /* Set the pending read domains for the batch buffer to COMMAND */ 2033 /* Set the pending read domains for the batch buffer to COMMAND */