aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-11-13 18:51:43 -0500
committerDave Airlie <airlied@redhat.com>2013-11-13 18:51:43 -0500
commitca9efa17413320694760f70805f0bee7d70224df (patch)
treed5db74b8ec850045401836fdf08f09611960dd53
parentcf0613d242805797f252535fcf7bb019512beb46 (diff)
parente14cd9536bd11b174a849da91c7a26bbc980330d (diff)
Merge branch 'vmwgfx-next-3.13' of git://people.freedesktop.org/~thomash/linux into drm-next
A resource eviction fix, and a fix for compilation / sparse problems from the previous pull. * 'vmwgfx-next-3.13' of git://people.freedesktop.org/~thomash/linux: drm/vmwgfx: Fix a couple of compile / sparse warnings and errors drm/vmwgfx: Resource evict fixes
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c7
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c7
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c42
3 files changed, 47 insertions, 9 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 814665b7a117..20d5485eaf98 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -453,12 +453,13 @@ static void vmw_get_initial_size(struct vmw_private *dev_priv)
453 */ 453 */
454static int vmw_dma_select_mode(struct vmw_private *dev_priv) 454static int vmw_dma_select_mode(struct vmw_private *dev_priv)
455{ 455{
456 const struct dma_map_ops *dma_ops = get_dma_ops(dev_priv->dev->dev);
457 static const char *names[vmw_dma_map_max] = { 456 static const char *names[vmw_dma_map_max] = {
458 [vmw_dma_phys] = "Using physical TTM page addresses.", 457 [vmw_dma_phys] = "Using physical TTM page addresses.",
459 [vmw_dma_alloc_coherent] = "Using coherent TTM pages.", 458 [vmw_dma_alloc_coherent] = "Using coherent TTM pages.",
460 [vmw_dma_map_populate] = "Keeping DMA mappings.", 459 [vmw_dma_map_populate] = "Keeping DMA mappings.",
461 [vmw_dma_map_bind] = "Giving up DMA mappings early."}; 460 [vmw_dma_map_bind] = "Giving up DMA mappings early."};
461#ifdef CONFIG_X86
462 const struct dma_map_ops *dma_ops = get_dma_ops(dev_priv->dev->dev);
462 463
463#ifdef CONFIG_INTEL_IOMMU 464#ifdef CONFIG_INTEL_IOMMU
464 if (intel_iommu_enabled) { 465 if (intel_iommu_enabled) {
@@ -500,6 +501,10 @@ out_fixup:
500 return -EINVAL; 501 return -EINVAL;
501#endif 502#endif
502 503
504#else /* CONFIG_X86 */
505 dev_priv->map_mode = vmw_dma_map_populate;
506#endif /* CONFIG_X86 */
507
503 DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]); 508 DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]);
504 509
505 return 0; 510 return 0;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
index 6d0952366f91..6ef0b035becb 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
@@ -145,7 +145,9 @@ static void vmw_gmr_free_descriptors(struct device *dev, dma_addr_t desc_dma,
145 } 145 }
146 146
147 page_virtual = kmap_atomic(page); 147 page_virtual = kmap_atomic(page);
148 desc_dma = page_virtual[desc_per_page].ppn << PAGE_SHIFT; 148 desc_dma = (dma_addr_t)
149 le32_to_cpu(page_virtual[desc_per_page].ppn) <<
150 PAGE_SHIFT;
149 kunmap_atomic(page_virtual); 151 kunmap_atomic(page_virtual);
150 152
151 __free_page(page); 153 __free_page(page);
@@ -217,7 +219,8 @@ static int vmw_gmr_build_descriptors(struct device *dev,
217 desc_dma = 0; 219 desc_dma = 0;
218 list_for_each_entry_reverse(page, desc_pages, lru) { 220 list_for_each_entry_reverse(page, desc_pages, lru) {
219 page_virtual = kmap_atomic(page); 221 page_virtual = kmap_atomic(page);
220 page_virtual[desc_per_page].ppn = desc_dma >> PAGE_SHIFT; 222 page_virtual[desc_per_page].ppn = cpu_to_le32
223 (desc_dma >> PAGE_SHIFT);
221 kunmap_atomic(page_virtual); 224 kunmap_atomic(page_virtual);
222 desc_dma = dma_map_page(dev, page, 0, PAGE_SIZE, 225 desc_dma = dma_map_page(dev, page, 0, PAGE_SIZE,
223 DMA_TO_DEVICE); 226 DMA_TO_DEVICE);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 37fb4befec82..252501a54def 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