aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-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 */