Am 11.07.2018 um 18:23 schrieb Michel Dänzer: > From: Michel Dänzer <michel.daenzer at amd.com> > > Concurrent execution of the non-atomic arithmetic could result in > completely bogus values. > > Cc: stable at vger.kernel.org > Bugzilla: https://bugs.freedesktop.org/106872 > Signed-off-by: Michel Dänzer <michel.daenzer at amd.com> Reviewed-by: Christian König <christian.koenig 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 | 18 ++++++++++-------- > 4 files changed, 25 insertions(+), 23 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 752484328665..24d6fb87f3b6 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > @@ -916,11 +916,12 @@ 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_bo_size(bo) - amdgpu_vram_mgr_bo_invisible_size(bo); > + atomic64_add(amdgpu_bo_size(bo), &adev->vram_pin_size); > + atomic64_add(amdgpu_bo_size(bo) - > + amdgpu_vram_mgr_bo_invisible_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: > @@ -969,11 +970,12 @@ 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_bo_size(bo) - amdgpu_vram_mgr_bo_invisible_size(bo); > + atomic64_sub(amdgpu_bo_size(bo), &adev->vram_pin_size); > + atomic64_sub(amdgpu_bo_size(bo) - > + amdgpu_vram_mgr_bo_invisible_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++) {