From: Michel Dänzer <michel.daenzer@xxxxxxx> Concurrent execution of the non-atomic arithmetic could result in completely bogus values. v2: * Rebased on v2 of the previous patch Cc: stable at vger.kernel.org Bugzilla: https://bugs.freedesktop.org/106872 Reviewed-by: Christian König <christian.koenig at amd.com> # v1 Signed-off-by: Michel Dänzer <michel.daenzer at amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 22 +++++++++++----------- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 14 ++++++++------ 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 77ab06bf26d5..f00be3d80aa4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1592,9 +1592,9 @@ struct amdgpu_device { DECLARE_HASHTABLE(mn_hash, 7); /* tracking pinned memory */ - u64 vram_pin_size; - u64 visible_pin_size; - u64 gart_pin_size; + atomic64_t vram_pin_size; + atomic64_t visible_pin_size; + atomic64_t gart_pin_size; /* amdkfd interface */ struct kfd_dev *kfd; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 9881a1e55df3..5a2a5ba29f9a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -262,7 +262,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, return; } - total_vram = adev->gmc.real_vram_size - adev->vram_pin_size; + total_vram = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size); used_vram = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index b1ea43ee8b87..258b6f73cbdf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -501,13 +501,13 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file case AMDGPU_INFO_VRAM_GTT: { struct drm_amdgpu_info_vram_gtt vram_gtt; - vram_gtt.vram_size = adev->gmc.real_vram_size; - vram_gtt.vram_size -= adev->vram_pin_size; - vram_gtt.vram_cpu_accessible_size = adev->gmc.visible_vram_size; - vram_gtt.vram_cpu_accessible_size -= adev->visible_pin_size; + vram_gtt.vram_size = adev->gmc.real_vram_size - + atomic64_read(&adev->vram_pin_size); + vram_gtt.vram_cpu_accessible_size = adev->gmc.visible_vram_size - + atomic64_read(&adev->visible_pin_size); vram_gtt.gtt_size = adev->mman.bdev.man[TTM_PL_TT].size; vram_gtt.gtt_size *= PAGE_SIZE; - vram_gtt.gtt_size -= adev->gart_pin_size; + vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size); return copy_to_user(out, &vram_gtt, min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0; } @@ -516,16 +516,16 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file memset(&mem, 0, sizeof(mem)); mem.vram.total_heap_size = adev->gmc.real_vram_size; - mem.vram.usable_heap_size = - adev->gmc.real_vram_size - adev->vram_pin_size; + mem.vram.usable_heap_size = adev->gmc.real_vram_size - + atomic64_read(&adev->vram_pin_size); mem.vram.heap_usage = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4; mem.cpu_accessible_vram.total_heap_size = adev->gmc.visible_vram_size; - mem.cpu_accessible_vram.usable_heap_size = - adev->gmc.visible_vram_size - adev->visible_pin_size; + mem.cpu_accessible_vram.usable_heap_size = adev->gmc.visible_vram_size - + atomic64_read(&adev->visible_pin_size); mem.cpu_accessible_vram.heap_usage = amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); mem.cpu_accessible_vram.max_allocation = @@ -533,8 +533,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file mem.gtt.total_heap_size = adev->mman.bdev.man[TTM_PL_TT].size; mem.gtt.total_heap_size *= PAGE_SIZE; - mem.gtt.usable_heap_size = mem.gtt.total_heap_size - - adev->gart_pin_size; + mem.gtt.usable_heap_size = mem.gtt.total_heap_size - + atomic64_read(&adev->gart_pin_size); mem.gtt.heap_usage = amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]); mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index f0239feceab4..1fd83ed175fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -916,10 +916,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); if (domain == AMDGPU_GEM_DOMAIN_VRAM) { - adev->vram_pin_size += amdgpu_bo_size(bo); - adev->visible_pin_size += amdgpu_vram_mgr_bo_visible_size(bo); + atomic64_add(amdgpu_bo_size(bo), &adev->vram_pin_size); + atomic64_add(amdgpu_vram_mgr_bo_visible_size(bo), + &adev->visible_pin_size); } else if (domain == AMDGPU_GEM_DOMAIN_GTT) { - adev->gart_pin_size += amdgpu_bo_size(bo); + atomic64_add(amdgpu_bo_size(bo), &adev->gart_pin_size); } error: @@ -968,10 +969,11 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo) return 0; if (bo->tbo.mem.mem_type == TTM_PL_VRAM) { - adev->vram_pin_size -= amdgpu_bo_size(bo); - adev->visible_pin_size -= amdgpu_vram_mgr_bo_visible_size(bo); + atomic64_sub(amdgpu_bo_size(bo), &adev->vram_pin_size); + atomic64_sub(amdgpu_vram_mgr_bo_visible_size(bo), + &adev->visible_pin_size); } else if (bo->tbo.mem.mem_type == TTM_PL_TT) { - adev->gart_pin_size -= amdgpu_bo_size(bo); + atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size); } for (i = 0; i < bo->placement.num_placement; i++) { -- 2.18.0