diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 57 |
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 | ||
1090 | static int | 1090 | static int |
1091 | i915_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 | |||
1103 | static int | ||
1091 | i915_gem_object_get_page_list(struct drm_gem_object *obj) | 1104 | i915_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 */ |