aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2013-11-12 03:09:54 -0500
committerThomas Hellstrom <thellstrom@vmware.com>2013-11-13 02:46:12 -0500
commitea029c28deadc33d2af4baf26810dd5fc44d4926 (patch)
tree415244428f83a555c2f519100e93dfe8279be86a /drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
parentd92d985177c495aab53c7167f310a7efb1853918 (diff)
drm/vmwgfx: Resource evict fixes
Fix an error message that was incorrectly blaming device resource id shortage. Also make sure we correctly catch resource eviction errors, that could otherwise lead to evictable resources temporarily not being on the LRU list. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecrantz <jakob@vmware.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_resource.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 0e67cf41065d..941e5ffd1c72 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -32,6 +32,8 @@
32#include <drm/drmP.h> 32#include <drm/drmP.h>
33#include "vmwgfx_resource_priv.h" 33#include "vmwgfx_resource_priv.h"
34 34
35#define VMW_RES_EVICT_ERR_COUNT 10
36
35struct vmw_user_dma_buffer { 37struct vmw_user_dma_buffer {
36 struct ttm_base_object base; 38 struct ttm_base_object base;
37 struct vmw_dma_buffer dma; 39 struct vmw_dma_buffer dma;
@@ -1091,8 +1093,9 @@ vmw_resource_backoff_reservation(struct ww_acquire_ctx *ticket,
1091 * to a backup buffer. 1093 * to a backup buffer.
1092 * 1094 *
1093 * @res: The resource to evict. 1095 * @res: The resource to evict.
1096 * @interruptible: Whether to wait interruptible.
1094 */ 1097 */
1095int vmw_resource_do_evict(struct vmw_resource *res) 1098int vmw_resource_do_evict(struct vmw_resource *res, bool interruptible)
1096{ 1099{
1097 struct ttm_validate_buffer val_buf; 1100 struct ttm_validate_buffer val_buf;
1098 const struct vmw_res_func *func = res->func; 1101 const struct vmw_res_func *func = res->func;
@@ -1102,7 +1105,8 @@ int vmw_resource_do_evict(struct vmw_resource *res)
1102 BUG_ON(!func->may_evict); 1105 BUG_ON(!func->may_evict);
1103 1106
1104 val_buf.bo = NULL; 1107 val_buf.bo = NULL;
1105 ret = vmw_resource_check_buffer(res, &ticket, true, &val_buf); 1108 ret = vmw_resource_check_buffer(res, &ticket, interruptible,
1109 &val_buf);
1106 if (unlikely(ret != 0)) 1110 if (unlikely(ret != 0))
1107 return ret; 1111 return ret;
1108 1112
@@ -1141,6 +1145,7 @@ int vmw_resource_validate(struct vmw_resource *res)
1141 struct vmw_private *dev_priv = res->dev_priv; 1145 struct vmw_private *dev_priv = res->dev_priv;
1142 struct list_head *lru_list = &dev_priv->res_lru[res->func->res_type]; 1146 struct list_head *lru_list = &dev_priv->res_lru[res->func->res_type];
1143 struct ttm_validate_buffer val_buf; 1147 struct ttm_validate_buffer val_buf;
1148 unsigned err_count = 0;
1144 1149
1145 if (likely(!res->func->may_evict)) 1150 if (likely(!res->func->may_evict))
1146 return 0; 1151 return 0;
@@ -1155,7 +1160,7 @@ int vmw_resource_validate(struct vmw_resource *res)
1155 1160
1156 write_lock(&dev_priv->resource_lock); 1161 write_lock(&dev_priv->resource_lock);
1157 if (list_empty(lru_list) || !res->func->may_evict) { 1162 if (list_empty(lru_list) || !res->func->may_evict) {
1158 DRM_ERROR("Out of device device id entries " 1163 DRM_ERROR("Out of device device resources "
1159 "for %s.\n", res->func->type_name); 1164 "for %s.\n", res->func->type_name);
1160 ret = -EBUSY; 1165 ret = -EBUSY;
1161 write_unlock(&dev_priv->resource_lock); 1166 write_unlock(&dev_priv->resource_lock);
@@ -1168,7 +1173,19 @@ int vmw_resource_validate(struct vmw_resource *res)
1168 list_del_init(&evict_res->lru_head); 1173 list_del_init(&evict_res->lru_head);
1169 1174
1170 write_unlock(&dev_priv->resource_lock); 1175 write_unlock(&dev_priv->resource_lock);
1171 vmw_resource_do_evict(evict_res); 1176
1177 ret = vmw_resource_do_evict(evict_res, true);
1178 if (unlikely(ret != 0)) {
1179 write_lock(&dev_priv->resource_lock);
1180 list_add_tail(&evict_res->lru_head, lru_list);
1181 write_unlock(&dev_priv->resource_lock);
1182 if (ret == -ERESTARTSYS ||
1183 ++err_count > VMW_RES_EVICT_ERR_COUNT) {
1184 vmw_resource_unreference(&evict_res);
1185 goto out_no_validate;
1186 }
1187 }
1188
1172 vmw_resource_unreference(&evict_res); 1189 vmw_resource_unreference(&evict_res);
1173 } while (1); 1190 } while (1);
1174 1191
@@ -1253,13 +1270,15 @@ bool vmw_resource_needs_backup(const struct vmw_resource *res)
1253 * @type: The resource type to evict 1270 * @type: The resource type to evict
1254 * 1271 *
1255 * To avoid thrashing starvation or as part of the hibernation sequence, 1272 * To avoid thrashing starvation or as part of the hibernation sequence,
1256 * evict all evictable resources of a specific type. 1273 * try to evict all evictable resources of a specific type.
1257 */ 1274 */
1258static void vmw_resource_evict_type(struct vmw_private *dev_priv, 1275static void vmw_resource_evict_type(struct vmw_private *dev_priv,
1259 enum vmw_res_type type) 1276 enum vmw_res_type type)
1260{ 1277{
1261 struct list_head *lru_list = &dev_priv->res_lru[type]; 1278 struct list_head *lru_list = &dev_priv->res_lru[type];
1262 struct vmw_resource *evict_res; 1279 struct vmw_resource *evict_res;
1280 unsigned err_count = 0;
1281 int ret;
1263 1282
1264 do { 1283 do {
1265 write_lock(&dev_priv->resource_lock); 1284 write_lock(&dev_priv->resource_lock);
@@ -1272,7 +1291,18 @@ static void vmw_resource_evict_type(struct vmw_private *dev_priv,
1272 lru_head)); 1291 lru_head));
1273 list_del_init(&evict_res->lru_head); 1292 list_del_init(&evict_res->lru_head);
1274 write_unlock(&dev_priv->resource_lock); 1293 write_unlock(&dev_priv->resource_lock);
1275 vmw_resource_do_evict(evict_res); 1294
1295 ret = vmw_resource_do_evict(evict_res, false);
1296 if (unlikely(ret != 0)) {
1297 write_lock(&dev_priv->resource_lock);
1298 list_add_tail(&evict_res->lru_head, lru_list);
1299 write_unlock(&dev_priv->resource_lock);
1300 if (++err_count > VMW_RES_EVICT_ERR_COUNT) {
1301 vmw_resource_unreference(&evict_res);
1302 return;
1303 }
1304 }
1305
1276 vmw_resource_unreference(&evict_res); 1306 vmw_resource_unreference(&evict_res);
1277 } while (1); 1307 } while (1);
1278 1308