[Why]
  After calling amdgpu_vram_mgr_reserve_range
multiple times with the same address, calling
amdgpu_vram_mgr_query_page_status will always
return -EBUSY.
  From the second call to amdgpu_vram_mgr_reserve_range,
the same address will be added to the reservations_pending
list again and is never moved to the reserved_pages list
because the address had been reserved.

[How]
  First add the address status check before calling
amdgpu_vram_mgr_do_reserve, if the address is already
reserved, do nothing; If the address is already in the
reservations_pending list, directly reserve memory;
only add new nodes for the addresses that are not in the
reserved_pages list and reservations_pending list.

V2:
 Avoid repeated locking/unlocking.

Signed-off-by: YiPeng Chai <yipeng.c...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 25 +++++++++++++-------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 1e36c428d254..a636d3f650b1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -317,7 +317,6 @@ static void amdgpu_vram_mgr_do_reserve(struct 
ttm_resource_manager *man)
 
                dev_dbg(adev->dev, "Reservation 0x%llx - %lld, Succeeded\n",
                        rsv->start, rsv->size);
-
                vis_usage = amdgpu_vram_mgr_vis_size(adev, block);
                atomic64_add(vis_usage, &mgr->vis_usage);
                spin_lock(&man->bdev->lru_lock);
@@ -340,19 +339,27 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr 
*mgr,
                                  uint64_t start, uint64_t size)
 {
        struct amdgpu_vram_reservation *rsv;
+       int ret = 0;
 
-       rsv = kzalloc(sizeof(*rsv), GFP_KERNEL);
-       if (!rsv)
-               return -ENOMEM;
+       ret = amdgpu_vram_mgr_query_page_status(mgr, start);
+       if (!ret)
+               return 0;
 
-       INIT_LIST_HEAD(&rsv->allocated);
-       INIT_LIST_HEAD(&rsv->blocks);
+       if (ret == -ENOENT) {
+               rsv = kzalloc(sizeof(*rsv), GFP_KERNEL);
+               if (!rsv)
+                       return -ENOMEM;
 
-       rsv->start = start;
-       rsv->size = size;
+               INIT_LIST_HEAD(&rsv->allocated);
+               INIT_LIST_HEAD(&rsv->blocks);
+
+               rsv->start = start;
+               rsv->size = size;
+       }
 
        mutex_lock(&mgr->lock);
-       list_add_tail(&rsv->blocks, &mgr->reservations_pending);
+       if (ret == -ENOENT)
+               list_add_tail(&rsv->blocks, &mgr->reservations_pending);
        amdgpu_vram_mgr_do_reserve(&mgr->manager);
        mutex_unlock(&mgr->lock);
 
-- 
2.34.1

Reply via email to