Keep track for which BO a resource was allocated.
This is necessary to move the LRU handling into the resources.

A bit problematic is i915 since it tries to use the resource
interface without a BO which is illegal from the conceptional
point of view.

v2: Document that this is a weak reference and add a workaround for i915
v3: further document that this is protected by ttm_device::lru_lock and
    clarify the i915 workaround

Signed-off-by: Christian König <christian.koe...@amd.com>
---
 drivers/gpu/drm/i915/intel_region_ttm.c | 22 ++++++++++++----------
 drivers/gpu/drm/ttm/ttm_bo_util.c       |  7 +++++--
 drivers/gpu/drm/ttm/ttm_resource.c      |  9 +++++++++
 include/drm/ttm/ttm_resource.h          |  4 ++++
 4 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_region_ttm.c 
b/drivers/gpu/drm/i915/intel_region_ttm.c
index 27fe0668d094..1b2a61b085f7 100644
--- a/drivers/gpu/drm/i915/intel_region_ttm.c
+++ b/drivers/gpu/drm/i915/intel_region_ttm.c
@@ -75,24 +75,26 @@ intel_region_ttm_node_reserve(struct intel_memory_region 
*mem,
        int ret;
 
        /*
-        * Having to use a mock_bo is unfortunate but stems from some
-        * drivers having private managers that insist to know what the
-        * allocate memory is intended for, using it to send private
-        * data to the manager. Also recently the bo has been used to send
-        * alignment info to the manager. Assume that apart from the latter,
-        * none of the managers we use will ever access the buffer object
-        * members, hoping we can pass the alignment info in the
-        * struct ttm_place in the future.
+        * This is essential an illegal use the of the TTM resource manager
+        * backend and should be fixed in the future. For now work around by
+        * using a mock_bo with at least the mandatory fields initialized.
+        *
+        * The resource should be ignored by TTM since it can't grab a
+        * reference to the BO during eviction.
         */
 
        place.fpfn = offset >> PAGE_SHIFT;
        place.lpfn = place.fpfn + (size >> PAGE_SHIFT);
        mock_bo.base.size = size;
+       mock_bo.bdev = &mem->i915->bdev;
        ret = man->func->alloc(man, &mock_bo, &place, &res);
        if (ret == -ENOSPC)
-               ret = -ENXIO;
+               return ERR_PTR(-ENXIO);
+       if (ret)
+               return ERR_PTR(ret);
 
-       return ret ? ERR_PTR(ret) : res;
+       res->bo = NULL;
+       return 0;
 }
 
 /**
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c 
b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 763fa6f4e07d..c5d02edaefc0 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -242,6 +242,11 @@ static int ttm_buffer_object_transfer(struct 
ttm_buffer_object *bo,
        if (bo->type != ttm_bo_type_sg)
                fbo->base.base.resv = &fbo->base.base._resv;
 
+       if (fbo->base.resource) {
+               ttm_resource_set_bo(fbo->base.resource, &fbo->base);
+               bo->resource = NULL;
+       }
+
        dma_resv_init(&fbo->base.base._resv);
        fbo->base.base.dev = NULL;
        ret = dma_resv_trylock(&fbo->base.base._resv);
@@ -510,7 +515,6 @@ static int ttm_bo_move_to_ghost(struct ttm_buffer_object 
*bo,
                ghost_obj->ttm = NULL;
        else
                bo->ttm = NULL;
-       bo->resource = NULL;
 
        dma_resv_unlock(&ghost_obj->base._resv);
        ttm_bo_put(ghost_obj);
@@ -638,7 +642,6 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo)
        dma_resv_unlock(&ghost->base._resv);
        ttm_bo_put(ghost);
        bo->ttm = ttm;
-       bo->resource = NULL;
        ttm_bo_assign_mem(bo, sys_res);
        return 0;
 
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c 
b/drivers/gpu/drm/ttm/ttm_resource.c
index 122f19e6968b..a4c495da0040 100644
--- a/drivers/gpu/drm/ttm/ttm_resource.c
+++ b/drivers/gpu/drm/ttm/ttm_resource.c
@@ -41,6 +41,7 @@ void ttm_resource_init(struct ttm_buffer_object *bo,
        res->bus.offset = 0;
        res->bus.is_iomem = false;
        res->bus.caching = ttm_cached;
+       res->bo = bo;
 }
 EXPORT_SYMBOL(ttm_resource_init);
 
@@ -73,6 +74,14 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct 
ttm_resource **res)
 }
 EXPORT_SYMBOL(ttm_resource_free);
 
+void ttm_resource_set_bo(struct ttm_resource *res,
+                        struct ttm_buffer_object *bo)
+{
+       spin_lock(&bo->bdev->lru_lock);
+       res->bo = bo;
+       spin_unlock(&bo->bdev->lru_lock);
+}
+
 /**
  * ttm_resource_manager_init
  *
diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
index c004672789b6..e8080192cae4 100644
--- a/include/drm/ttm/ttm_resource.h
+++ b/include/drm/ttm/ttm_resource.h
@@ -160,6 +160,7 @@ struct ttm_bus_placement {
  * @mem_type: Resource type of the allocation.
  * @placement: Placement flags.
  * @bus: Placement on io bus accessible to the CPU
+ * @bo: weak reference to the BO, protected by ttm_device::lru_lock
  *
  * Structure indicating the placement and space resources used by a
  * buffer object.
@@ -170,6 +171,7 @@ struct ttm_resource {
        uint32_t mem_type;
        uint32_t placement;
        struct ttm_bus_placement bus;
+       struct ttm_buffer_object *bo;
 };
 
 /**
@@ -268,6 +270,8 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
                       const struct ttm_place *place,
                       struct ttm_resource **res);
 void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource 
**res);
+void ttm_resource_set_bo(struct ttm_resource *res,
+                        struct ttm_buffer_object *bo);
 
 void ttm_resource_manager_init(struct ttm_resource_manager *man,
                               struct ttm_device *bdev,
-- 
2.25.1

Reply via email to