aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-02-08 04:57:22 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-02-10 14:16:43 -0500
commitd7006964d46d76930a44e14f1aae401ccb1797da (patch)
tree5688e0d3eaed9d4fdf404dfe6bfbe5a1c2a9be19
parent10c1b6183a163aca59ba92b88f2b4c4cecd20d4c (diff)
drm/amdgpu: fix issue with overlapping userptrs
Otherwise we could try to evict overlapping userptr BOs in get_user_pages(), leading to a possible circular locking dependency. Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c19
3 files changed, 23 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 82edf95b7740..d0fee29ebeba 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2360,6 +2360,8 @@ bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
2360int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, 2360int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
2361 uint32_t flags); 2361 uint32_t flags);
2362bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); 2362bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
2363bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
2364 unsigned long end);
2363bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); 2365bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
2364uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, 2366uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
2365 struct ttm_mem_reg *mem); 2367 struct ttm_mem_reg *mem);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index b1969f2b2038..d4e2780c0796 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -142,7 +142,8 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn,
142 142
143 list_for_each_entry(bo, &node->bos, mn_list) { 143 list_for_each_entry(bo, &node->bos, mn_list) {
144 144
145 if (!bo->tbo.ttm || bo->tbo.ttm->state != tt_bound) 145 if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start,
146 end))
146 continue; 147 continue;
147 148
148 r = amdgpu_bo_reserve(bo, true); 149 r = amdgpu_bo_reserve(bo, true);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 55cf05e1c81c..6442a06d6fdc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -783,6 +783,25 @@ bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm)
783 return !!gtt->userptr; 783 return !!gtt->userptr;
784} 784}
785 785
786bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
787 unsigned long end)
788{
789 struct amdgpu_ttm_tt *gtt = (void *)ttm;
790 unsigned long size;
791
792 if (gtt == NULL)
793 return false;
794
795 if (gtt->ttm.ttm.state != tt_bound || !gtt->userptr)
796 return false;
797
798 size = (unsigned long)gtt->ttm.ttm.num_pages * PAGE_SIZE;
799 if (gtt->userptr > end || gtt->userptr + size <= start)
800 return false;
801
802 return true;
803}
804
786bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) 805bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm)
787{ 806{
788 struct amdgpu_ttm_tt *gtt = (void *)ttm; 807 struct amdgpu_ttm_tt *gtt = (void *)ttm;