diff options
author | Dave Airlie <airlied@redhat.com> | 2013-11-13 18:51:43 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-11-13 18:51:43 -0500 |
commit | ca9efa17413320694760f70805f0bee7d70224df (patch) | |
tree | d5db74b8ec850045401836fdf08f09611960dd53 | |
parent | cf0613d242805797f252535fcf7bb019512beb46 (diff) | |
parent | e14cd9536bd11b174a849da91c7a26bbc980330d (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.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 42 |
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 | */ |
454 | static int vmw_dma_select_mode(struct vmw_private *dev_priv) | 454 | static 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 | |||
35 | struct vmw_user_dma_buffer { | 37 | struct 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 | */ |
1095 | int vmw_resource_do_evict(struct vmw_resource *res) | 1098 | int 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 | */ |
1258 | static void vmw_resource_evict_type(struct vmw_private *dev_priv, | 1275 | static 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 | ||