drm/ttm: cleanup ttm_bo_mem_space
authorChristian König <christian.koenig@amd.com>
Mon, 13 May 2019 15:34:29 +0000 (17:34 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 31 May 2019 15:39:34 +0000 (10:39 -0500)
We tried this once before, but that turned out to be more
complicated than thought. With all the right prerequisites
it looks like we can do this now.

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Chunming Zhou <david1.zhou@amd.com>
Tested-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/ttm/ttm_bo.c

index 702cd89adbf9ff5b771858c0bbd530c20ae97cae..0dbb23b0deddab197ec84514d6aab0b4d925a05a 100644 (file)
@@ -893,13 +893,12 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,
  * space, or we've evicted everything and there isn't enough space.
  */
 static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
-                                       uint32_t mem_type,
-                                       const struct ttm_place *place,
-                                       struct ttm_mem_reg *mem,
-                                       struct ttm_operation_ctx *ctx)
+                                 const struct ttm_place *place,
+                                 struct ttm_mem_reg *mem,
+                                 struct ttm_operation_ctx *ctx)
 {
        struct ttm_bo_device *bdev = bo->bdev;
-       struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+       struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
        int ret;
 
        do {
@@ -908,11 +907,11 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
                        return ret;
                if (mem->mm_node)
                        break;
-               ret = ttm_mem_evict_first(bdev, mem_type, place, ctx);
+               ret = ttm_mem_evict_first(bdev, mem->mem_type, place, ctx);
                if (unlikely(ret != 0))
                        return ret;
        } while (1);
-       mem->mem_type = mem_type;
+
        return ttm_bo_add_move_fence(bo, man, mem);
 }
 
@@ -960,6 +959,51 @@ static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
        return true;
 }
 
+/**
+ * ttm_bo_mem_placement - check if placement is compatible
+ * @bo: BO to find memory for
+ * @place: where to search
+ * @mem: the memory object to fill in
+ * @ctx: operation context
+ *
+ * Check if placement is compatible and fill in mem structure.
+ * Returns -EBUSY if placement won't work or negative error code.
+ * 0 when placement can be used.
+ */
+static int ttm_bo_mem_placement(struct ttm_buffer_object *bo,
+                               const struct ttm_place *place,
+                               struct ttm_mem_reg *mem,
+                               struct ttm_operation_ctx *ctx)
+{
+       struct ttm_bo_device *bdev = bo->bdev;
+       uint32_t mem_type = TTM_PL_SYSTEM;
+       struct ttm_mem_type_manager *man;
+       uint32_t cur_flags = 0;
+       int ret;
+
+       ret = ttm_mem_type_from_place(place, &mem_type);
+       if (ret)
+               return ret;
+
+       man = &bdev->man[mem_type];
+       if (!man->has_type || !man->use_type)
+               return -EBUSY;
+
+       if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
+               return -EBUSY;
+
+       cur_flags = ttm_bo_select_caching(man, bo->mem.placement, cur_flags);
+       /*
+        * Use the access and other non-mapping-related flag bits from
+        * the memory placement flags to the current flags
+        */
+       ttm_flag_masked(&cur_flags, place->flags, ~TTM_PL_MASK_MEMTYPE);
+
+       mem->mem_type = mem_type;
+       mem->placement = cur_flags;
+       return 0;
+}
+
 /**
  * Creates space for memory region @mem according to its type.
  *
@@ -974,11 +1018,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
                        struct ttm_operation_ctx *ctx)
 {
        struct ttm_bo_device *bdev = bo->bdev;
-       struct ttm_mem_type_manager *man;
-       uint32_t mem_type = TTM_PL_SYSTEM;
-       uint32_t cur_flags = 0;
        bool type_found = false;
-       bool type_ok = false;
        int i, ret;
 
        ret = reservation_object_reserve_shared(bo->resv, 1);
@@ -988,37 +1028,20 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
        mem->mm_node = NULL;
        for (i = 0; i < placement->num_placement; ++i) {
                const struct ttm_place *place = &placement->placement[i];
+               struct ttm_mem_type_manager *man;
 
-               ret = ttm_mem_type_from_place(place, &mem_type);
+               ret = ttm_bo_mem_placement(bo, place, mem, ctx);
+               if (ret == -EBUSY)
+                       continue;
                if (ret)
                        return ret;
-               man = &bdev->man[mem_type];
-               if (!man->has_type || !man->use_type)
-                       continue;
-
-               type_ok = ttm_bo_mt_compatible(man, mem_type, place,
-                                               &cur_flags);
-
-               if (!type_ok)
-                       continue;
 
                type_found = true;
-               cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
-                                                 cur_flags);
-               /*
-                * Use the access and other non-mapping-related flag bits from
-                * the memory placement flags to the current flags
-                */
-               ttm_flag_masked(&cur_flags, place->flags,
-                               ~TTM_PL_MASK_MEMTYPE);
-
-               if (mem_type == TTM_PL_SYSTEM) {
-                       mem->mem_type = mem_type;
-                       mem->placement = cur_flags;
-                       mem->mm_node = NULL;
+               mem->mm_node = NULL;
+               if (mem->mem_type == TTM_PL_SYSTEM)
                        return 0;
-               }
 
+               man = &bdev->man[mem->mem_type];
                ret = (*man->func->get_node)(man, bo, place, mem);
                if (unlikely(ret))
                        return ret;
@@ -1029,8 +1052,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
                                (*man->func->put_node)(man, mem);
                                return ret;
                        }
-                       mem->mem_type = mem_type;
-                       mem->placement = cur_flags;
                        return 0;
                }
        }
@@ -1038,37 +1059,21 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
        for (i = 0; i < placement->num_busy_placement; ++i) {
                const struct ttm_place *place = &placement->busy_placement[i];
 
-               ret = ttm_mem_type_from_place(place, &mem_type);
+               ret = ttm_bo_mem_placement(bo, place, mem, ctx);
+               if (ret == -EBUSY)
+                       continue;
                if (ret)
                        return ret;
-               man = &bdev->man[mem_type];
-               if (!man->has_type || !man->use_type)
-                       continue;
-               if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
-                       continue;
 
                type_found = true;
-               cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
-                                                 cur_flags);
-               /*
-                * Use the access and other non-mapping-related flag bits from
-                * the memory placement flags to the current flags
-                */
-               ttm_flag_masked(&cur_flags, place->flags,
-                               ~TTM_PL_MASK_MEMTYPE);
-
-               if (mem_type == TTM_PL_SYSTEM) {
-                       mem->mem_type = mem_type;
-                       mem->placement = cur_flags;
-                       mem->mm_node = NULL;
+               mem->mm_node = NULL;
+               if (mem->mem_type == TTM_PL_SYSTEM)
                        return 0;
-               }
 
-               ret = ttm_bo_mem_force_space(bo, mem_type, place, mem, ctx);
-               if (ret == 0 && mem->mm_node) {
-                       mem->placement = cur_flags;
+               ret = ttm_bo_mem_force_space(bo, place, mem, ctx);
+               if (ret == 0 && mem->mm_node)
                        return 0;
-               }
+
                if (ret && ret != -EBUSY)
                        return ret;
        }